stop_test.go 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776
  1. /*
  2. Copyright 2014 The Kubernetes Authors.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package kubectl
  14. import (
  15. "fmt"
  16. "reflect"
  17. "strings"
  18. "testing"
  19. "time"
  20. "k8s.io/kubernetes/pkg/api"
  21. "k8s.io/kubernetes/pkg/api/errors"
  22. "k8s.io/kubernetes/pkg/api/unversioned"
  23. "k8s.io/kubernetes/pkg/apis/batch"
  24. "k8s.io/kubernetes/pkg/apis/extensions"
  25. client "k8s.io/kubernetes/pkg/client/unversioned"
  26. "k8s.io/kubernetes/pkg/client/unversioned/testclient"
  27. deploymentutil "k8s.io/kubernetes/pkg/controller/deployment/util"
  28. "k8s.io/kubernetes/pkg/runtime"
  29. "k8s.io/kubernetes/pkg/watch"
  30. )
  31. func TestReplicationControllerStop(t *testing.T) {
  32. name := "foo"
  33. ns := "default"
  34. tests := []struct {
  35. Name string
  36. Objs []runtime.Object
  37. StopError error
  38. ExpectedActions []string
  39. }{
  40. {
  41. Name: "OnlyOneRC",
  42. Objs: []runtime.Object{
  43. &api.ReplicationController{ // GET
  44. ObjectMeta: api.ObjectMeta{
  45. Name: name,
  46. Namespace: ns,
  47. },
  48. Spec: api.ReplicationControllerSpec{
  49. Replicas: 0,
  50. Selector: map[string]string{"k1": "v1"}},
  51. },
  52. &api.ReplicationControllerList{ // LIST
  53. Items: []api.ReplicationController{
  54. {
  55. ObjectMeta: api.ObjectMeta{
  56. Name: name,
  57. Namespace: ns,
  58. },
  59. Spec: api.ReplicationControllerSpec{
  60. Replicas: 0,
  61. Selector: map[string]string{"k1": "v1"}},
  62. },
  63. },
  64. },
  65. },
  66. StopError: nil,
  67. ExpectedActions: []string{"get", "list", "get", "update", "get", "delete"},
  68. },
  69. {
  70. Name: "NoOverlapping",
  71. Objs: []runtime.Object{
  72. &api.ReplicationController{ // GET
  73. ObjectMeta: api.ObjectMeta{
  74. Name: name,
  75. Namespace: ns,
  76. },
  77. Spec: api.ReplicationControllerSpec{
  78. Replicas: 0,
  79. Selector: map[string]string{"k1": "v1"}},
  80. },
  81. &api.ReplicationControllerList{ // LIST
  82. Items: []api.ReplicationController{
  83. {
  84. ObjectMeta: api.ObjectMeta{
  85. Name: "baz",
  86. Namespace: ns,
  87. },
  88. Spec: api.ReplicationControllerSpec{
  89. Replicas: 0,
  90. Selector: map[string]string{"k3": "v3"}},
  91. },
  92. {
  93. ObjectMeta: api.ObjectMeta{
  94. Name: name,
  95. Namespace: ns,
  96. },
  97. Spec: api.ReplicationControllerSpec{
  98. Replicas: 0,
  99. Selector: map[string]string{"k1": "v1"}},
  100. },
  101. },
  102. },
  103. },
  104. StopError: nil,
  105. ExpectedActions: []string{"get", "list", "get", "update", "get", "delete"},
  106. },
  107. {
  108. Name: "OverlappingError",
  109. Objs: []runtime.Object{
  110. &api.ReplicationController{ // GET
  111. ObjectMeta: api.ObjectMeta{
  112. Name: name,
  113. Namespace: ns,
  114. },
  115. Spec: api.ReplicationControllerSpec{
  116. Replicas: 0,
  117. Selector: map[string]string{"k1": "v1"}},
  118. },
  119. &api.ReplicationControllerList{ // LIST
  120. Items: []api.ReplicationController{
  121. {
  122. ObjectMeta: api.ObjectMeta{
  123. Name: "baz",
  124. Namespace: ns,
  125. },
  126. Spec: api.ReplicationControllerSpec{
  127. Replicas: 0,
  128. Selector: map[string]string{"k1": "v1", "k2": "v2"}},
  129. },
  130. {
  131. ObjectMeta: api.ObjectMeta{
  132. Name: name,
  133. Namespace: ns,
  134. },
  135. Spec: api.ReplicationControllerSpec{
  136. Replicas: 0,
  137. Selector: map[string]string{"k1": "v1"}},
  138. },
  139. },
  140. },
  141. },
  142. StopError: fmt.Errorf("Detected overlapping controllers for rc foo: baz, please manage deletion individually with --cascade=false."),
  143. ExpectedActions: []string{"get", "list"},
  144. },
  145. {
  146. Name: "OverlappingButSafeDelete",
  147. Objs: []runtime.Object{
  148. &api.ReplicationController{ // GET
  149. ObjectMeta: api.ObjectMeta{
  150. Name: name,
  151. Namespace: ns,
  152. },
  153. Spec: api.ReplicationControllerSpec{
  154. Replicas: 0,
  155. Selector: map[string]string{"k1": "v1", "k2": "v2"}},
  156. },
  157. &api.ReplicationControllerList{ // LIST
  158. Items: []api.ReplicationController{
  159. {
  160. ObjectMeta: api.ObjectMeta{
  161. Name: "baz",
  162. Namespace: ns,
  163. },
  164. Spec: api.ReplicationControllerSpec{
  165. Replicas: 0,
  166. Selector: map[string]string{"k1": "v1", "k2": "v2", "k3": "v3"}},
  167. },
  168. {
  169. ObjectMeta: api.ObjectMeta{
  170. Name: "zaz",
  171. Namespace: ns,
  172. },
  173. Spec: api.ReplicationControllerSpec{
  174. Replicas: 0,
  175. Selector: map[string]string{"k1": "v1"}},
  176. },
  177. {
  178. ObjectMeta: api.ObjectMeta{
  179. Name: name,
  180. Namespace: ns,
  181. },
  182. Spec: api.ReplicationControllerSpec{
  183. Replicas: 0,
  184. Selector: map[string]string{"k1": "v1", "k2": "v2"}},
  185. },
  186. },
  187. },
  188. },
  189. StopError: fmt.Errorf("Detected overlapping controllers for rc foo: baz,zaz, please manage deletion individually with --cascade=false."),
  190. ExpectedActions: []string{"get", "list"},
  191. },
  192. {
  193. Name: "TwoExactMatchRCs",
  194. Objs: []runtime.Object{
  195. &api.ReplicationController{ // GET
  196. ObjectMeta: api.ObjectMeta{
  197. Name: name,
  198. Namespace: ns,
  199. },
  200. Spec: api.ReplicationControllerSpec{
  201. Replicas: 0,
  202. Selector: map[string]string{"k1": "v1"}},
  203. },
  204. &api.ReplicationControllerList{ // LIST
  205. Items: []api.ReplicationController{
  206. {
  207. ObjectMeta: api.ObjectMeta{
  208. Name: "zaz",
  209. Namespace: ns,
  210. },
  211. Spec: api.ReplicationControllerSpec{
  212. Replicas: 0,
  213. Selector: map[string]string{"k1": "v1"}},
  214. },
  215. {
  216. ObjectMeta: api.ObjectMeta{
  217. Name: name,
  218. Namespace: ns,
  219. },
  220. Spec: api.ReplicationControllerSpec{
  221. Replicas: 0,
  222. Selector: map[string]string{"k1": "v1"}},
  223. },
  224. },
  225. },
  226. },
  227. StopError: nil,
  228. ExpectedActions: []string{"get", "list", "delete"},
  229. },
  230. }
  231. for _, test := range tests {
  232. copiedForWatch, err := api.Scheme.Copy(test.Objs[0])
  233. if err != nil {
  234. t.Fatalf("%s unexpected error: %v", test.Name, err)
  235. }
  236. fake := testclient.NewSimpleFake(test.Objs...)
  237. fakeWatch := watch.NewFake()
  238. fake.PrependWatchReactor("replicationcontrollers", testclient.DefaultWatchReactor(fakeWatch, nil))
  239. go func() {
  240. fakeWatch.Add(copiedForWatch)
  241. }()
  242. reaper := ReplicationControllerReaper{fake, time.Millisecond, time.Millisecond}
  243. err = reaper.Stop(ns, name, 0, nil)
  244. if !reflect.DeepEqual(err, test.StopError) {
  245. t.Errorf("%s unexpected error: %v", test.Name, err)
  246. continue
  247. }
  248. actions := fake.Actions()
  249. if len(actions) != len(test.ExpectedActions) {
  250. t.Errorf("%s unexpected actions: %v, expected %d actions got %d", test.Name, actions, len(test.ExpectedActions), len(actions))
  251. continue
  252. }
  253. for i, verb := range test.ExpectedActions {
  254. if actions[i].GetResource() != "replicationcontrollers" {
  255. t.Errorf("%s unexpected action: %+v, expected %s-replicationController", test.Name, actions[i], verb)
  256. }
  257. if actions[i].GetVerb() != verb {
  258. t.Errorf("%s unexpected action: %+v, expected %s-replicationController", test.Name, actions[i], verb)
  259. }
  260. }
  261. }
  262. }
  263. func TestReplicaSetStop(t *testing.T) {
  264. name := "foo"
  265. ns := "default"
  266. tests := []struct {
  267. Name string
  268. Objs []runtime.Object
  269. StopError error
  270. ExpectedActions []string
  271. }{
  272. {
  273. Name: "OnlyOneRS",
  274. Objs: []runtime.Object{
  275. &extensions.ReplicaSet{ // GET
  276. ObjectMeta: api.ObjectMeta{
  277. Name: name,
  278. Namespace: ns,
  279. },
  280. Spec: extensions.ReplicaSetSpec{
  281. Replicas: 0,
  282. Selector: &unversioned.LabelSelector{MatchLabels: map[string]string{"k1": "v1"}},
  283. },
  284. },
  285. &extensions.ReplicaSetList{ // LIST
  286. Items: []extensions.ReplicaSet{
  287. {
  288. ObjectMeta: api.ObjectMeta{
  289. Name: name,
  290. Namespace: ns,
  291. },
  292. Spec: extensions.ReplicaSetSpec{
  293. Replicas: 0,
  294. Selector: &unversioned.LabelSelector{MatchLabels: map[string]string{"k1": "v1"}},
  295. },
  296. },
  297. },
  298. },
  299. },
  300. StopError: nil,
  301. ExpectedActions: []string{"get", "get", "update", "get", "get", "delete"},
  302. },
  303. {
  304. Name: "NoOverlapping",
  305. Objs: []runtime.Object{
  306. &extensions.ReplicaSet{ // GET
  307. ObjectMeta: api.ObjectMeta{
  308. Name: name,
  309. Namespace: ns,
  310. },
  311. Spec: extensions.ReplicaSetSpec{
  312. Replicas: 0,
  313. Selector: &unversioned.LabelSelector{MatchLabels: map[string]string{"k1": "v1"}},
  314. },
  315. },
  316. &extensions.ReplicaSetList{ // LIST
  317. Items: []extensions.ReplicaSet{
  318. {
  319. ObjectMeta: api.ObjectMeta{
  320. Name: "baz",
  321. Namespace: ns,
  322. },
  323. Spec: extensions.ReplicaSetSpec{
  324. Replicas: 0,
  325. Selector: &unversioned.LabelSelector{MatchLabels: map[string]string{"k3": "v3"}},
  326. },
  327. },
  328. {
  329. ObjectMeta: api.ObjectMeta{
  330. Name: name,
  331. Namespace: ns,
  332. },
  333. Spec: extensions.ReplicaSetSpec{
  334. Replicas: 0,
  335. Selector: &unversioned.LabelSelector{MatchLabels: map[string]string{"k1": "v1"}},
  336. },
  337. },
  338. },
  339. },
  340. },
  341. StopError: nil,
  342. ExpectedActions: []string{"get", "get", "update", "get", "get", "delete"},
  343. },
  344. // TODO: Implement tests for overlapping replica sets, similar to replication controllers,
  345. // when the overlapping checks are implemented for replica sets.
  346. }
  347. for _, test := range tests {
  348. fake := testclient.NewSimpleFake(test.Objs...)
  349. reaper := ReplicaSetReaper{fake, time.Millisecond, time.Millisecond}
  350. err := reaper.Stop(ns, name, 0, nil)
  351. if !reflect.DeepEqual(err, test.StopError) {
  352. t.Errorf("%s unexpected error: %v", test.Name, err)
  353. continue
  354. }
  355. actions := fake.Actions()
  356. if len(actions) != len(test.ExpectedActions) {
  357. t.Errorf("%s unexpected actions: %v, expected %d actions got %d", test.Name, actions, len(test.ExpectedActions), len(actions))
  358. continue
  359. }
  360. for i, verb := range test.ExpectedActions {
  361. if actions[i].GetResource() != "replicasets" {
  362. t.Errorf("%s unexpected action: %+v, expected %s-replicaSet", test.Name, actions[i], verb)
  363. }
  364. if actions[i].GetVerb() != verb {
  365. t.Errorf("%s unexpected action: %+v, expected %s-replicaSet", test.Name, actions[i], verb)
  366. }
  367. }
  368. }
  369. }
  370. func TestJobStop(t *testing.T) {
  371. name := "foo"
  372. ns := "default"
  373. zero := int32(0)
  374. tests := []struct {
  375. Name string
  376. Objs []runtime.Object
  377. StopError error
  378. ExpectedActions []string
  379. }{
  380. {
  381. Name: "OnlyOneJob",
  382. Objs: []runtime.Object{
  383. &batch.Job{ // GET
  384. ObjectMeta: api.ObjectMeta{
  385. Name: name,
  386. Namespace: ns,
  387. },
  388. Spec: batch.JobSpec{
  389. Parallelism: &zero,
  390. Selector: &unversioned.LabelSelector{
  391. MatchLabels: map[string]string{"k1": "v1"},
  392. },
  393. },
  394. },
  395. &batch.JobList{ // LIST
  396. Items: []batch.Job{
  397. {
  398. ObjectMeta: api.ObjectMeta{
  399. Name: name,
  400. Namespace: ns,
  401. },
  402. Spec: batch.JobSpec{
  403. Parallelism: &zero,
  404. Selector: &unversioned.LabelSelector{
  405. MatchLabels: map[string]string{"k1": "v1"},
  406. },
  407. },
  408. },
  409. },
  410. },
  411. },
  412. StopError: nil,
  413. ExpectedActions: []string{"get:jobs", "get:jobs", "update:jobs",
  414. "get:jobs", "get:jobs", "list:pods", "delete:jobs"},
  415. },
  416. {
  417. Name: "JobWithDeadPods",
  418. Objs: []runtime.Object{
  419. &batch.Job{ // GET
  420. ObjectMeta: api.ObjectMeta{
  421. Name: name,
  422. Namespace: ns,
  423. },
  424. Spec: batch.JobSpec{
  425. Parallelism: &zero,
  426. Selector: &unversioned.LabelSelector{
  427. MatchLabels: map[string]string{"k1": "v1"},
  428. },
  429. },
  430. },
  431. &batch.JobList{ // LIST
  432. Items: []batch.Job{
  433. {
  434. ObjectMeta: api.ObjectMeta{
  435. Name: name,
  436. Namespace: ns,
  437. },
  438. Spec: batch.JobSpec{
  439. Parallelism: &zero,
  440. Selector: &unversioned.LabelSelector{
  441. MatchLabels: map[string]string{"k1": "v1"},
  442. },
  443. },
  444. },
  445. },
  446. },
  447. &api.PodList{ // LIST
  448. Items: []api.Pod{
  449. {
  450. ObjectMeta: api.ObjectMeta{
  451. Name: "pod1",
  452. Namespace: ns,
  453. Labels: map[string]string{"k1": "v1"},
  454. },
  455. },
  456. },
  457. },
  458. },
  459. StopError: nil,
  460. ExpectedActions: []string{"get:jobs", "get:jobs", "update:jobs",
  461. "get:jobs", "get:jobs", "list:pods", "delete:pods", "delete:jobs"},
  462. },
  463. }
  464. for _, test := range tests {
  465. fake := testclient.NewSimpleFake(test.Objs...)
  466. reaper := JobReaper{fake, time.Millisecond, time.Millisecond}
  467. err := reaper.Stop(ns, name, 0, nil)
  468. if !reflect.DeepEqual(err, test.StopError) {
  469. t.Errorf("%s unexpected error: %v", test.Name, err)
  470. continue
  471. }
  472. actions := fake.Actions()
  473. if len(actions) != len(test.ExpectedActions) {
  474. t.Errorf("%s unexpected actions: %v, expected %d actions got %d", test.Name, actions, len(test.ExpectedActions), len(actions))
  475. continue
  476. }
  477. for i, expAction := range test.ExpectedActions {
  478. action := strings.Split(expAction, ":")
  479. if actions[i].GetVerb() != action[0] {
  480. t.Errorf("%s unexpected verb: %+v, expected %s", test.Name, actions[i], expAction)
  481. }
  482. if actions[i].GetResource() != action[1] {
  483. t.Errorf("%s unexpected resource: %+v, expected %s", test.Name, actions[i], expAction)
  484. }
  485. }
  486. }
  487. }
  488. func TestDeploymentStop(t *testing.T) {
  489. name := "foo"
  490. ns := "default"
  491. deployment := extensions.Deployment{
  492. ObjectMeta: api.ObjectMeta{
  493. Name: name,
  494. Namespace: ns,
  495. },
  496. Spec: extensions.DeploymentSpec{
  497. Replicas: 0,
  498. Selector: &unversioned.LabelSelector{MatchLabels: map[string]string{"k1": "v1"}},
  499. },
  500. Status: extensions.DeploymentStatus{
  501. Replicas: 0,
  502. },
  503. }
  504. template := deploymentutil.GetNewReplicaSetTemplate(&deployment)
  505. tests := []struct {
  506. Name string
  507. Objs []runtime.Object
  508. StopError error
  509. ExpectedActions []string
  510. }{
  511. {
  512. Name: "SimpleDeployment",
  513. Objs: []runtime.Object{
  514. &extensions.Deployment{ // GET
  515. ObjectMeta: api.ObjectMeta{
  516. Name: name,
  517. Namespace: ns,
  518. },
  519. Spec: extensions.DeploymentSpec{
  520. Replicas: 0,
  521. Selector: &unversioned.LabelSelector{MatchLabels: map[string]string{"k1": "v1"}},
  522. },
  523. Status: extensions.DeploymentStatus{
  524. Replicas: 0,
  525. },
  526. },
  527. },
  528. StopError: nil,
  529. ExpectedActions: []string{"get:deployments", "update:deployments",
  530. "get:deployments", "list:replicasets", "delete:deployments"},
  531. },
  532. {
  533. Name: "Deployment with single replicaset",
  534. Objs: []runtime.Object{
  535. &deployment, // GET
  536. &extensions.ReplicaSetList{ // LIST
  537. Items: []extensions.ReplicaSet{
  538. {
  539. ObjectMeta: api.ObjectMeta{
  540. Name: name,
  541. Namespace: ns,
  542. },
  543. Spec: extensions.ReplicaSetSpec{
  544. Template: template,
  545. },
  546. },
  547. },
  548. },
  549. },
  550. StopError: nil,
  551. ExpectedActions: []string{"get:deployments", "update:deployments",
  552. "get:deployments", "list:replicasets", "get:replicasets",
  553. "get:replicasets", "update:replicasets", "get:replicasets",
  554. "get:replicasets", "delete:replicasets", "delete:deployments"},
  555. },
  556. }
  557. for _, test := range tests {
  558. fake := testclient.NewSimpleFake(test.Objs...)
  559. reaper := DeploymentReaper{fake, time.Millisecond, time.Millisecond}
  560. err := reaper.Stop(ns, name, 0, nil)
  561. if !reflect.DeepEqual(err, test.StopError) {
  562. t.Errorf("%s unexpected error: %v", test.Name, err)
  563. continue
  564. }
  565. actions := fake.Actions()
  566. if len(actions) != len(test.ExpectedActions) {
  567. t.Errorf("%s unexpected actions: %v, expected %d actions got %d", test.Name, actions, len(test.ExpectedActions), len(actions))
  568. continue
  569. }
  570. for i, expAction := range test.ExpectedActions {
  571. action := strings.Split(expAction, ":")
  572. if actions[i].GetVerb() != action[0] {
  573. t.Errorf("%s unexpected verb: %+v, expected %s", test.Name, actions[i], expAction)
  574. }
  575. if actions[i].GetResource() != action[1] {
  576. t.Errorf("%s unexpected resource: %+v, expected %s", test.Name, actions[i], expAction)
  577. }
  578. if len(action) == 3 && actions[i].GetSubresource() != action[2] {
  579. t.Errorf("%s unexpected subresource: %+v, expected %s", test.Name, actions[i], expAction)
  580. }
  581. }
  582. }
  583. }
  584. type noSuchPod struct {
  585. *testclient.FakePods
  586. }
  587. func (c *noSuchPod) Get(name string) (*api.Pod, error) {
  588. return nil, fmt.Errorf("%s does not exist", name)
  589. }
  590. type noDeleteService struct {
  591. *testclient.FakeServices
  592. }
  593. func (c *noDeleteService) Delete(service string) error {
  594. return fmt.Errorf("I'm afraid I can't do that, Dave")
  595. }
  596. type reaperFake struct {
  597. *testclient.Fake
  598. noSuchPod, noDeleteService bool
  599. }
  600. func (c *reaperFake) Pods(namespace string) client.PodInterface {
  601. pods := &testclient.FakePods{Fake: c.Fake, Namespace: namespace}
  602. if c.noSuchPod {
  603. return &noSuchPod{pods}
  604. }
  605. return pods
  606. }
  607. func (c *reaperFake) Services(namespace string) client.ServiceInterface {
  608. services := &testclient.FakeServices{Fake: c.Fake, Namespace: namespace}
  609. if c.noDeleteService {
  610. return &noDeleteService{services}
  611. }
  612. return services
  613. }
  614. func TestSimpleStop(t *testing.T) {
  615. tests := []struct {
  616. fake *reaperFake
  617. kind unversioned.GroupKind
  618. actions []testclient.Action
  619. expectError bool
  620. test string
  621. }{
  622. {
  623. fake: &reaperFake{
  624. Fake: &testclient.Fake{},
  625. },
  626. kind: api.Kind("Pod"),
  627. actions: []testclient.Action{
  628. testclient.NewGetAction("pods", api.NamespaceDefault, "foo"),
  629. testclient.NewDeleteAction("pods", api.NamespaceDefault, "foo"),
  630. },
  631. expectError: false,
  632. test: "stop pod succeeds",
  633. },
  634. {
  635. fake: &reaperFake{
  636. Fake: &testclient.Fake{},
  637. },
  638. kind: api.Kind("Service"),
  639. actions: []testclient.Action{
  640. testclient.NewGetAction("services", api.NamespaceDefault, "foo"),
  641. testclient.NewDeleteAction("services", api.NamespaceDefault, "foo"),
  642. },
  643. expectError: false,
  644. test: "stop service succeeds",
  645. },
  646. {
  647. fake: &reaperFake{
  648. Fake: &testclient.Fake{},
  649. noSuchPod: true,
  650. },
  651. kind: api.Kind("Pod"),
  652. actions: []testclient.Action{},
  653. expectError: true,
  654. test: "stop pod fails, no pod",
  655. },
  656. {
  657. fake: &reaperFake{
  658. Fake: &testclient.Fake{},
  659. noDeleteService: true,
  660. },
  661. kind: api.Kind("Service"),
  662. actions: []testclient.Action{
  663. testclient.NewGetAction("services", api.NamespaceDefault, "foo"),
  664. },
  665. expectError: true,
  666. test: "stop service fails, can't delete",
  667. },
  668. }
  669. for _, test := range tests {
  670. fake := test.fake
  671. reaper, err := ReaperFor(test.kind, fake)
  672. if err != nil {
  673. t.Errorf("unexpected error: %v (%s)", err, test.test)
  674. }
  675. err = reaper.Stop("default", "foo", 0, nil)
  676. if err != nil && !test.expectError {
  677. t.Errorf("unexpected error: %v (%s)", err, test.test)
  678. }
  679. if err == nil {
  680. if test.expectError {
  681. t.Errorf("unexpected non-error: %v (%s)", err, test.test)
  682. }
  683. }
  684. actions := fake.Actions()
  685. if len(test.actions) != len(actions) {
  686. t.Errorf("unexpected actions: %v; expected %v (%s)", actions, test.actions, test.test)
  687. }
  688. for i, action := range actions {
  689. testAction := test.actions[i]
  690. if action != testAction {
  691. t.Errorf("unexpected action: %#v; expected %v (%s)", action, testAction, test.test)
  692. }
  693. }
  694. }
  695. }
  696. func TestDeploymentNotFoundError(t *testing.T) {
  697. name := "foo"
  698. ns := "default"
  699. deployment := &extensions.Deployment{
  700. ObjectMeta: api.ObjectMeta{
  701. Name: name,
  702. Namespace: ns,
  703. },
  704. Spec: extensions.DeploymentSpec{
  705. Replicas: 0,
  706. Selector: &unversioned.LabelSelector{MatchLabels: map[string]string{"k1": "v1"}},
  707. },
  708. Status: extensions.DeploymentStatus{
  709. Replicas: 0,
  710. },
  711. }
  712. template := deploymentutil.GetNewReplicaSetTemplate(deployment)
  713. fake := &testclient.Fake{}
  714. fake.AddReactor("get", "deployments", func(action testclient.Action) (handled bool, ret runtime.Object, err error) {
  715. return true, deployment, nil
  716. })
  717. fake.AddReactor("list", "replicasets", func(action testclient.Action) (handled bool, ret runtime.Object, err error) {
  718. list := &extensions.ReplicaSetList{Items: []extensions.ReplicaSet{
  719. {
  720. ObjectMeta: api.ObjectMeta{
  721. Name: name,
  722. Namespace: ns,
  723. },
  724. Spec: extensions.ReplicaSetSpec{
  725. Template: template,
  726. },
  727. },
  728. }}
  729. return true, list, nil
  730. })
  731. fake.AddReactor("get", "replicasets", func(action testclient.Action) (handled bool, ret runtime.Object, err error) {
  732. return true, nil, ScaleError{ActualError: errors.NewNotFound(api.Resource("replicaset"), "doesnt-matter")}
  733. })
  734. reaper := DeploymentReaper{fake, time.Millisecond, time.Millisecond}
  735. if err := reaper.Stop(ns, name, 0, nil); err != nil {
  736. t.Fatalf("unexpected error: %#v", err)
  737. }
  738. }