// TestHandle_pausedConfig ensures that a paused config will not be instantiated. func TestHandle_pausedConfig(t *testing.T) { fake := &testclient.Fake{} controller := NewDeploymentTriggerController(dcInformer, rcInformer, streamInformer, fake, codec) config := testapi.OkDeploymentConfig(1) config.Namespace = kapi.NamespaceDefault config.Spec.Paused = true if err := controller.Handle(config); err != nil { t.Fatalf("unexpected error: %v", err) } if len(fake.Actions()) > 0 { t.Fatalf("unexpected actions: %v", fake.Actions()) } }
func TestJobScaleFailsPreconditions(t *testing.T) { ten := int32(10) fake := fake.NewSimpleClientset(&batch.Job{ ObjectMeta: metav1.ObjectMeta{ Namespace: api.NamespaceDefault, Name: "foo", }, Spec: batch.JobSpec{ Parallelism: &ten, }, }) scaler := JobScaler{fake.Batch()} preconditions := ScalePrecondition{2, ""} count := uint(3) name := "foo" scaler.Scale("default", name, count, &preconditions, nil, nil) actions := fake.Actions() if len(actions) != 1 { t.Errorf("unexpected actions: %v, expected 1 actions (get)", actions) } if action, ok := actions[0].(testcore.GetAction); !ok || action.GetResource().GroupResource() != batch.Resource("jobs") || action.GetName() != name { t.Errorf("unexpected action: %v, expected get-job %s", actions[0], name) } }
// issue: https://github.com/kubernetes/kubernetes/issues/23218 func TestDeploymentController_dontSyncDeploymentsWithEmptyPodSelector(t *testing.T) { fake := &fake.Clientset{} informers := informers.NewSharedInformerFactory(fake, controller.NoResyncPeriodFunc()) controller := NewDeploymentController(informers.Deployments(), informers.ReplicaSets(), informers.Pods(), fake) controller.eventRecorder = &record.FakeRecorder{} controller.dListerSynced = alwaysReady controller.rsListerSynced = alwaysReady controller.podListerSynced = alwaysReady stopCh := make(chan struct{}) defer close(stopCh) informers.Start(stopCh) d := newDeployment("foo", 1, nil, nil, nil, map[string]string{"foo": "bar"}) empty := unversioned.LabelSelector{} d.Spec.Selector = &empty controller.dLister.Indexer.Add(d) // We expect the deployment controller to not take action here since it's configuration // is invalid, even though no replicasets exist that match it's selector. controller.syncDeployment(fmt.Sprintf("%s/%s", d.ObjectMeta.Namespace, d.ObjectMeta.Name)) filteredActions := filterInformerActions(fake.Actions()) if len(filteredActions) == 0 { return } for _, action := range filteredActions { t.Logf("unexpected action: %#v", action) } t.Errorf("expected deployment controller to not take action") }
// issue: https://github.com/kubernetes/kubernetes/issues/23218 func TestDeploymentController_dontSyncDeploymentsWithEmptyPodSelector(t *testing.T) { fake := &fake.Clientset{} controller := NewDeploymentController(fake, controller.NoResyncPeriodFunc) controller.eventRecorder = &record.FakeRecorder{} controller.rsStoreSynced = alwaysReady controller.podStoreSynced = alwaysReady d := newDeployment(1, nil) empty := unversioned.LabelSelector{} d.Spec.Selector = &empty controller.dStore.Indexer.Add(d) // We expect the deployment controller to not take action here since it's configuration // is invalid, even though no replicasets exist that match it's selector. controller.syncDeployment(fmt.Sprintf("%s/%s", d.ObjectMeta.Namespace, d.ObjectMeta.Name)) if len(fake.Actions()) == 0 { return } for _, action := range fake.Actions() { t.Logf("unexpected action: %#v", action) } t.Errorf("expected deployment controller to not take action") }
func TestDeploymentScale(t *testing.T) { fake := fake.NewSimpleClientset(deployment()) scaler := DeploymentScaler{fake.Extensions()} preconditions := ScalePrecondition{-1, ""} count := uint(3) name := "foo" scaler.Scale("default", name, count, &preconditions, nil, nil) actions := fake.Actions() if len(actions) != 2 { t.Errorf("unexpected actions: %v, expected 2 actions (get, update)", actions) } if action, ok := actions[0].(testcore.GetAction); !ok || action.GetResource().GroupResource() != extensions.Resource("deployments") || action.GetName() != name { t.Errorf("unexpected action: %v, expected get-replicationController %s", actions[0], name) } if action, ok := actions[1].(testcore.UpdateAction); !ok || action.GetResource().GroupResource() != extensions.Resource("deployments") || action.GetObject().(*extensions.Deployment).Spec.Replicas != int32(count) { t.Errorf("unexpected action %v, expected update-deployment with replicas = %d", actions[1], count) } }
func TestReplicationControllerScaleFailsPreconditions(t *testing.T) { fake := fake.NewSimpleClientset(&api.ReplicationController{ ObjectMeta: metav1.ObjectMeta{Namespace: api.NamespaceDefault, Name: "foo"}, Spec: api.ReplicationControllerSpec{ Replicas: 10, }, }) scaler := ReplicationControllerScaler{fake.Core()} preconditions := ScalePrecondition{2, ""} count := uint(3) name := "foo" scaler.Scale("default", name, count, &preconditions, nil, nil) actions := fake.Actions() if len(actions) != 1 { t.Errorf("unexpected actions: %v, expected 1 action (get)", actions) } if action, ok := actions[0].(testcore.GetAction); !ok || action.GetResource().GroupResource() != api.Resource("replicationcontrollers") || action.GetName() != name { t.Errorf("unexpected action: %v, expected get-replicationController %s", actions[0], name) } }
func TestDeploymentScaleFailsPreconditions(t *testing.T) { fake := fake.NewSimpleClientset(&extensions.Deployment{ ObjectMeta: api.ObjectMeta{ Namespace: api.NamespaceDefault, Name: "foo", }, Spec: extensions.DeploymentSpec{ Replicas: 10, }, }) scaler := DeploymentScaler{fake.Extensions()} preconditions := ScalePrecondition{2, ""} count := uint(3) name := "foo" scaler.Scale("default", name, count, &preconditions, nil, nil) actions := fake.Actions() if len(actions) != 1 { t.Errorf("unexpected actions: %v, expected 1 actions (get)", actions) } if action, ok := actions[0].(testcore.GetAction); !ok || action.GetResource().GroupResource() != extensions.Resource("deployments") || action.GetName() != name { t.Errorf("unexpected action: %v, expected get-deployment %s", actions[0], name) } }
func TestDeploymentController_cleanupOldReplicaSets(t *testing.T) { selector := map[string]string{"foo": "bar"} tests := []struct { oldRSs []*exp.ReplicaSet revisionHistoryLimit int expectedDeletions int }{ { oldRSs: []*exp.ReplicaSet{ newRSWithStatus("foo-1", 0, 0, selector), newRSWithStatus("foo-2", 0, 0, selector), newRSWithStatus("foo-3", 0, 0, selector), }, revisionHistoryLimit: 1, expectedDeletions: 2, }, { // Only delete the replica set with Spec.Replicas = Status.Replicas = 0. oldRSs: []*exp.ReplicaSet{ newRSWithStatus("foo-1", 0, 0, selector), newRSWithStatus("foo-2", 0, 1, selector), newRSWithStatus("foo-3", 1, 0, selector), newRSWithStatus("foo-4", 1, 1, selector), }, revisionHistoryLimit: 0, expectedDeletions: 1, }, { oldRSs: []*exp.ReplicaSet{ newRSWithStatus("foo-1", 0, 0, selector), newRSWithStatus("foo-2", 0, 0, selector), }, revisionHistoryLimit: 0, expectedDeletions: 2, }, { oldRSs: []*exp.ReplicaSet{ newRSWithStatus("foo-1", 1, 1, selector), newRSWithStatus("foo-2", 1, 1, selector), }, revisionHistoryLimit: 0, expectedDeletions: 0, }, } for i, test := range tests { fake := &fake.Clientset{} controller := NewDeploymentController(fake, controller.NoResyncPeriodFunc) controller.eventRecorder = &record.FakeRecorder{} controller.rsStoreSynced = alwaysReady controller.podStoreSynced = alwaysReady for _, rs := range test.oldRSs { controller.rsStore.Add(rs) } d := newDeployment(1, &tests[i].revisionHistoryLimit) controller.cleanupOldReplicaSets(test.oldRSs, d) gotDeletions := 0 for _, action := range fake.Actions() { if "delete" == action.GetVerb() { gotDeletions++ } } if gotDeletions != test.expectedDeletions { t.Errorf("expect %v old replica sets been deleted, but got %v", test.expectedDeletions, gotDeletions) continue } } }
func TestSimpleStop(t *testing.T) { tests := []struct { fake *reaperFake kind schema.GroupKind actions []testcore.Action expectError bool test string }{ { fake: &reaperFake{ Clientset: fake.NewSimpleClientset(pod()), }, kind: api.Kind("Pod"), actions: []testcore.Action{ testcore.NewGetAction(api.Resource("pods").WithVersion(""), api.NamespaceDefault, "foo"), testcore.NewDeleteAction(api.Resource("pods").WithVersion(""), api.NamespaceDefault, "foo"), }, expectError: false, test: "stop pod succeeds", }, { fake: &reaperFake{ Clientset: fake.NewSimpleClientset(service()), }, kind: api.Kind("Service"), actions: []testcore.Action{ testcore.NewGetAction(api.Resource("services").WithVersion(""), api.NamespaceDefault, "foo"), testcore.NewDeleteAction(api.Resource("services").WithVersion(""), api.NamespaceDefault, "foo"), }, expectError: false, test: "stop service succeeds", }, { fake: &reaperFake{ Clientset: fake.NewSimpleClientset(), noSuchPod: true, }, kind: api.Kind("Pod"), actions: []testcore.Action{}, expectError: true, test: "stop pod fails, no pod", }, { fake: &reaperFake{ Clientset: fake.NewSimpleClientset(service()), noDeleteService: true, }, kind: api.Kind("Service"), actions: []testcore.Action{ testcore.NewGetAction(api.Resource("services").WithVersion(""), api.NamespaceDefault, "foo"), }, expectError: true, test: "stop service fails, can't delete", }, } for _, test := range tests { fake := test.fake reaper, err := ReaperFor(test.kind, fake) if err != nil { t.Errorf("unexpected error: %v (%s)", err, test.test) } err = reaper.Stop("default", "foo", 0, nil) if err != nil && !test.expectError { t.Errorf("unexpected error: %v (%s)", err, test.test) } if err == nil { if test.expectError { t.Errorf("unexpected non-error: %v (%s)", err, test.test) } } actions := fake.Actions() if len(test.actions) != len(actions) { t.Errorf("unexpected actions: %v; expected %v (%s)", actions, test.actions, test.test) } for i, action := range actions { testAction := test.actions[i] if action != testAction { t.Errorf("unexpected action: %#v; expected %v (%s)", action, testAction, test.test) } } } }
func TestDeploymentStop(t *testing.T) { name := "foo" ns := "default" deployment := extensions.Deployment{ ObjectMeta: api.ObjectMeta{ Name: name, Namespace: ns, }, Spec: extensions.DeploymentSpec{ Replicas: 0, Selector: &unversioned.LabelSelector{MatchLabels: map[string]string{"k1": "v1"}}, }, Status: extensions.DeploymentStatus{ Replicas: 0, }, } template := deploymentutil.GetNewReplicaSetTemplateInternal(&deployment) tests := []struct { Name string Objs []runtime.Object StopError error ExpectedActions []string }{ { Name: "SimpleDeployment", Objs: []runtime.Object{ &extensions.Deployment{ // GET ObjectMeta: api.ObjectMeta{ Name: name, Namespace: ns, }, Spec: extensions.DeploymentSpec{ Replicas: 0, Selector: &unversioned.LabelSelector{MatchLabels: map[string]string{"k1": "v1"}}, }, Status: extensions.DeploymentStatus{ Replicas: 0, }, }, }, StopError: nil, ExpectedActions: []string{"get:deployments", "update:deployments", "get:deployments", "list:replicasets", "delete:deployments"}, }, { Name: "Deployment with single replicaset", Objs: []runtime.Object{ &deployment, // GET &extensions.ReplicaSetList{ // LIST Items: []extensions.ReplicaSet{ { ObjectMeta: api.ObjectMeta{ Name: name, Namespace: ns, Labels: map[string]string{"k1": "v1"}, }, Spec: extensions.ReplicaSetSpec{ Template: template, }, }, }, }, }, StopError: nil, ExpectedActions: []string{"get:deployments", "update:deployments", "get:deployments", "list:replicasets", "get:replicasets", "get:replicasets", "update:replicasets", "get:replicasets", "get:replicasets", "delete:replicasets", "delete:deployments"}, }, } for _, test := range tests { fake := fake.NewSimpleClientset(test.Objs...) reaper := DeploymentReaper{fake.Extensions(), fake.Extensions(), time.Millisecond, time.Millisecond} err := reaper.Stop(ns, name, 0, nil) if !reflect.DeepEqual(err, test.StopError) { t.Errorf("%s unexpected error: %v", test.Name, err) continue } actions := fake.Actions() if len(actions) != len(test.ExpectedActions) { t.Errorf("%s unexpected actions: %v, expected %d actions got %d", test.Name, actions, len(test.ExpectedActions), len(actions)) continue } for i, expAction := range test.ExpectedActions { action := strings.Split(expAction, ":") if actions[i].GetVerb() != action[0] { t.Errorf("%s unexpected verb: %+v, expected %s", test.Name, actions[i], expAction) } if actions[i].GetResource().Resource != action[1] { t.Errorf("%s unexpected resource: %+v, expected %s", test.Name, actions[i], expAction) } if len(action) == 3 && actions[i].GetSubresource() != action[2] { t.Errorf("%s unexpected subresource: %+v, expected %s", test.Name, actions[i], expAction) } } } }
func TestReplicationControllerStop(t *testing.T) { name := "foo" ns := "default" tests := []struct { Name string Objs []runtime.Object StopError error ExpectedActions []string }{ { Name: "OnlyOneRC", Objs: []runtime.Object{ &api.ReplicationControllerList{ // LIST Items: []api.ReplicationController{ { ObjectMeta: api.ObjectMeta{ Name: name, Namespace: ns, }, Spec: api.ReplicationControllerSpec{ Replicas: 0, Selector: map[string]string{"k1": "v1"}}, }, }, }, }, StopError: nil, ExpectedActions: []string{"get", "list", "get", "update", "get", "delete"}, }, { Name: "NoOverlapping", Objs: []runtime.Object{ &api.ReplicationControllerList{ // LIST Items: []api.ReplicationController{ { ObjectMeta: api.ObjectMeta{ Name: "baz", Namespace: ns, }, Spec: api.ReplicationControllerSpec{ Replicas: 0, Selector: map[string]string{"k3": "v3"}}, }, { ObjectMeta: api.ObjectMeta{ Name: name, Namespace: ns, }, Spec: api.ReplicationControllerSpec{ Replicas: 0, Selector: map[string]string{"k1": "v1"}}, }, }, }, }, StopError: nil, ExpectedActions: []string{"get", "list", "get", "update", "get", "delete"}, }, { Name: "OverlappingError", Objs: []runtime.Object{ &api.ReplicationControllerList{ // LIST Items: []api.ReplicationController{ { ObjectMeta: api.ObjectMeta{ Name: "baz", Namespace: ns, }, Spec: api.ReplicationControllerSpec{ Replicas: 0, Selector: map[string]string{"k1": "v1", "k2": "v2"}}, }, { ObjectMeta: api.ObjectMeta{ Name: name, Namespace: ns, }, Spec: api.ReplicationControllerSpec{ Replicas: 0, Selector: map[string]string{"k1": "v1"}}, }, }, }, }, StopError: fmt.Errorf("Detected overlapping controllers for rc foo: baz, please manage deletion individually with --cascade=false."), ExpectedActions: []string{"get", "list"}, }, { Name: "OverlappingButSafeDelete", Objs: []runtime.Object{ &api.ReplicationControllerList{ // LIST Items: []api.ReplicationController{ { ObjectMeta: api.ObjectMeta{ Name: "baz", Namespace: ns, }, Spec: api.ReplicationControllerSpec{ Replicas: 0, Selector: map[string]string{"k1": "v1", "k2": "v2", "k3": "v3"}}, }, { ObjectMeta: api.ObjectMeta{ Name: "zaz", Namespace: ns, }, Spec: api.ReplicationControllerSpec{ Replicas: 0, Selector: map[string]string{"k1": "v1"}}, }, { ObjectMeta: api.ObjectMeta{ Name: name, Namespace: ns, }, Spec: api.ReplicationControllerSpec{ Replicas: 0, Selector: map[string]string{"k1": "v1", "k2": "v2"}}, }, }, }, }, StopError: fmt.Errorf("Detected overlapping controllers for rc foo: baz,zaz, please manage deletion individually with --cascade=false."), ExpectedActions: []string{"get", "list"}, }, { Name: "TwoExactMatchRCs", Objs: []runtime.Object{ &api.ReplicationControllerList{ // LIST Items: []api.ReplicationController{ { ObjectMeta: api.ObjectMeta{ Name: "zaz", Namespace: ns, }, Spec: api.ReplicationControllerSpec{ Replicas: 0, Selector: map[string]string{"k1": "v1"}}, }, { ObjectMeta: api.ObjectMeta{ Name: name, Namespace: ns, }, Spec: api.ReplicationControllerSpec{ Replicas: 0, Selector: map[string]string{"k1": "v1"}}, }, }, }, }, StopError: nil, ExpectedActions: []string{"get", "list", "delete"}, }, } for _, test := range tests { copiedForWatch, err := api.Scheme.Copy(test.Objs[0]) if err != nil { t.Fatalf("%s unexpected error: %v", test.Name, err) } fake := fake.NewSimpleClientset(test.Objs...) fakeWatch := watch.NewFake() fake.PrependWatchReactor("replicationcontrollers", testcore.DefaultWatchReactor(fakeWatch, nil)) go func() { fakeWatch.Add(copiedForWatch) }() reaper := ReplicationControllerReaper{fake.Core(), time.Millisecond, time.Millisecond} err = reaper.Stop(ns, name, 0, nil) if !reflect.DeepEqual(err, test.StopError) { t.Errorf("%s unexpected error: %v", test.Name, err) continue } actions := fake.Actions() if len(actions) != len(test.ExpectedActions) { t.Errorf("%s unexpected actions: %v, expected %d actions got %d", test.Name, actions, len(test.ExpectedActions), len(actions)) continue } for i, verb := range test.ExpectedActions { if actions[i].GetResource().GroupResource() != api.Resource("replicationcontrollers") { t.Errorf("%s unexpected action: %+v, expected %s-replicationController", test.Name, actions[i], verb) } if actions[i].GetVerb() != verb { t.Errorf("%s unexpected action: %+v, expected %s-replicationController", test.Name, actions[i], verb) } } } }
func TestJobStop(t *testing.T) { name := "foo" ns := "default" zero := int32(0) tests := []struct { Name string Objs []runtime.Object StopError error ExpectedActions []string }{ { Name: "OnlyOneJob", Objs: []runtime.Object{ &batch.JobList{ // LIST Items: []batch.Job{ { ObjectMeta: api.ObjectMeta{ Name: name, Namespace: ns, }, Spec: batch.JobSpec{ Parallelism: &zero, Selector: &unversioned.LabelSelector{ MatchLabels: map[string]string{"k1": "v1"}, }, }, }, }, }, }, StopError: nil, ExpectedActions: []string{"get:jobs", "get:jobs", "update:jobs", "get:jobs", "get:jobs", "list:pods", "delete:jobs"}, }, { Name: "JobWithDeadPods", Objs: []runtime.Object{ &batch.JobList{ // LIST Items: []batch.Job{ { ObjectMeta: api.ObjectMeta{ Name: name, Namespace: ns, }, Spec: batch.JobSpec{ Parallelism: &zero, Selector: &unversioned.LabelSelector{ MatchLabels: map[string]string{"k1": "v1"}, }, }, }, }, }, &api.PodList{ // LIST Items: []api.Pod{ { ObjectMeta: api.ObjectMeta{ Name: "pod1", Namespace: ns, Labels: map[string]string{"k1": "v1"}, }, }, }, }, }, StopError: nil, ExpectedActions: []string{"get:jobs", "get:jobs", "update:jobs", "get:jobs", "get:jobs", "list:pods", "delete:pods", "delete:jobs"}, }, } for _, test := range tests { fake := fake.NewSimpleClientset(test.Objs...) reaper := JobReaper{fake.Batch(), fake.Core(), time.Millisecond, time.Millisecond} err := reaper.Stop(ns, name, 0, nil) if !reflect.DeepEqual(err, test.StopError) { t.Errorf("%s unexpected error: %v", test.Name, err) continue } actions := fake.Actions() if len(actions) != len(test.ExpectedActions) { t.Errorf("%s unexpected actions: %v, expected %d actions got %d", test.Name, actions, len(test.ExpectedActions), len(actions)) continue } for i, expAction := range test.ExpectedActions { action := strings.Split(expAction, ":") if actions[i].GetVerb() != action[0] { t.Errorf("%s unexpected verb: %+v, expected %s", test.Name, actions[i], expAction) } if actions[i].GetResource().Resource != action[1] { t.Errorf("%s unexpected resource: %+v, expected %s", test.Name, actions[i], expAction) } } } }
func TestReplicaSetStop(t *testing.T) { name := "foo" ns := "default" tests := []struct { Name string Objs []runtime.Object StopError error ExpectedActions []string }{ { Name: "OnlyOneRS", Objs: []runtime.Object{ &extensions.ReplicaSetList{ // LIST Items: []extensions.ReplicaSet{ { ObjectMeta: api.ObjectMeta{ Name: name, Namespace: ns, }, Spec: extensions.ReplicaSetSpec{ Replicas: 0, Selector: &unversioned.LabelSelector{MatchLabels: map[string]string{"k1": "v1"}}, }, }, }, }, }, StopError: nil, ExpectedActions: []string{"get", "get", "update", "get", "get", "delete"}, }, { Name: "NoOverlapping", Objs: []runtime.Object{ &extensions.ReplicaSetList{ // LIST Items: []extensions.ReplicaSet{ { ObjectMeta: api.ObjectMeta{ Name: "baz", Namespace: ns, }, Spec: extensions.ReplicaSetSpec{ Replicas: 0, Selector: &unversioned.LabelSelector{MatchLabels: map[string]string{"k3": "v3"}}, }, }, { ObjectMeta: api.ObjectMeta{ Name: name, Namespace: ns, }, Spec: extensions.ReplicaSetSpec{ Replicas: 0, Selector: &unversioned.LabelSelector{MatchLabels: map[string]string{"k1": "v1"}}, }, }, }, }, }, StopError: nil, ExpectedActions: []string{"get", "get", "update", "get", "get", "delete"}, }, // TODO: Implement tests for overlapping replica sets, similar to replication controllers, // when the overlapping checks are implemented for replica sets. } for _, test := range tests { fake := fake.NewSimpleClientset(test.Objs...) reaper := ReplicaSetReaper{fake.Extensions(), time.Millisecond, time.Millisecond} err := reaper.Stop(ns, name, 0, nil) if !reflect.DeepEqual(err, test.StopError) { t.Errorf("%s unexpected error: %v", test.Name, err) continue } actions := fake.Actions() if len(actions) != len(test.ExpectedActions) { t.Errorf("%s unexpected actions: %v, expected %d actions got %d", test.Name, actions, len(test.ExpectedActions), len(actions)) continue } for i, verb := range test.ExpectedActions { if actions[i].GetResource().GroupResource() != extensions.Resource("replicasets") { t.Errorf("%s unexpected action: %+v, expected %s-replicaSet", test.Name, actions[i], verb) } if actions[i].GetVerb() != verb { t.Errorf("%s unexpected action: %+v, expected %s-replicaSet", test.Name, actions[i], verb) } } } }
func TestDeploymentController_cleanupDeployment(t *testing.T) { selector := map[string]string{"foo": "bar"} tests := []struct { oldRSs []*extensions.ReplicaSet revisionHistoryLimit int32 expectedDeletions int }{ { oldRSs: []*extensions.ReplicaSet{ newRSWithStatus("foo-1", 0, 0, selector), newRSWithStatus("foo-2", 0, 0, selector), newRSWithStatus("foo-3", 0, 0, selector), }, revisionHistoryLimit: 1, expectedDeletions: 2, }, { // Only delete the replica set with Spec.Replicas = Status.Replicas = 0. oldRSs: []*extensions.ReplicaSet{ newRSWithStatus("foo-1", 0, 0, selector), newRSWithStatus("foo-2", 0, 1, selector), newRSWithStatus("foo-3", 1, 0, selector), newRSWithStatus("foo-4", 1, 1, selector), }, revisionHistoryLimit: 0, expectedDeletions: 1, }, { oldRSs: []*extensions.ReplicaSet{ newRSWithStatus("foo-1", 0, 0, selector), newRSWithStatus("foo-2", 0, 0, selector), }, revisionHistoryLimit: 0, expectedDeletions: 2, }, { oldRSs: []*extensions.ReplicaSet{ newRSWithStatus("foo-1", 1, 1, selector), newRSWithStatus("foo-2", 1, 1, selector), }, revisionHistoryLimit: 0, expectedDeletions: 0, }, } for i := range tests { test := tests[i] fake := &fake.Clientset{} informers := informers.NewSharedInformerFactory(fake, controller.NoResyncPeriodFunc()) controller := NewDeploymentController(informers.Deployments(), informers.ReplicaSets(), informers.Pods(), fake) controller.eventRecorder = &record.FakeRecorder{} controller.dListerSynced = alwaysReady controller.rsListerSynced = alwaysReady controller.podListerSynced = alwaysReady for _, rs := range test.oldRSs { controller.rsLister.Indexer.Add(rs) } stopCh := make(chan struct{}) defer close(stopCh) informers.Start(stopCh) d := newDeployment("foo", 1, &test.revisionHistoryLimit, nil, nil, map[string]string{"foo": "bar"}) controller.cleanupDeployment(test.oldRSs, d) gotDeletions := 0 for _, action := range fake.Actions() { if "delete" == action.GetVerb() { gotDeletions++ } } if gotDeletions != test.expectedDeletions { t.Errorf("expect %v old replica sets been deleted, but got %v", test.expectedDeletions, gotDeletions) continue } } }