func TestReplicationControllerScale(t *testing.T) { fake := fake.NewSimpleClientset(oldRc(0, 0)) scaler := ReplicationControllerScaler{fake.Core()} preconditions := ScalePrecondition{-1, ""} count := uint(3) name := "foo-v1" 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() != api.Resource("replicationcontrollers") || 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() != api.Resource("replicationcontrollers") || action.GetObject().(*api.ReplicationController).Spec.Replicas != int32(count) { t.Errorf("unexpected action %v, expected update-replicationController 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 TestGetSecrets(t *testing.T) { fake := fake.NewSimpleClientset(&kapi.SecretList{ Items: []kapi.Secret{ { ObjectMeta: kapi.ObjectMeta{Name: "secret-1", Namespace: "default"}, Type: kapi.SecretTypeDockercfg, }, { ObjectMeta: kapi.ObjectMeta{Name: "secret-2", Annotations: map[string]string{api.ExcludeImageSecretAnnotation: "true"}, Namespace: "default"}, Type: kapi.SecretTypeDockercfg, }, { ObjectMeta: kapi.ObjectMeta{Name: "secret-3", Namespace: "default"}, Type: kapi.SecretTypeOpaque, }, { ObjectMeta: kapi.ObjectMeta{Name: "secret-4", Namespace: "default"}, Type: kapi.SecretTypeServiceAccountToken, }, { ObjectMeta: kapi.ObjectMeta{Name: "secret-5", Namespace: "default"}, Type: kapi.SecretTypeDockerConfigJson, }, }, }) rest := NewREST(fake.Core()) opts, _, _ := rest.NewGetOptions() obj, err := rest.Get(kapi.NewDefaultContext(), "", opts) if err != nil { t.Fatal(err) } list := obj.(*kapi.SecretList) if len(list.Items) != 2 { t.Fatal(list) } if list.Items[0].Name != "secret-1" || list.Items[1].Name != "secret-5" { t.Fatal(list) } }
func TestGetFirstPod(t *testing.T) { labelSet := map[string]string{"test": "selector"} tests := []struct { name string podList *api.PodList watching []watch.Event sortBy func([]*api.Pod) sort.Interface expected *api.Pod expectedNum int expectedErr bool }{ { name: "kubectl logs - two ready pods", podList: newPodList(2, -1, -1, labelSet), sortBy: func(pods []*api.Pod) sort.Interface { return controller.ByLogging(pods) }, expected: &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "pod-1", Namespace: api.NamespaceDefault, CreationTimestamp: unversioned.Date(2016, time.April, 1, 1, 0, 0, 0, time.UTC), Labels: map[string]string{"test": "selector"}, }, Status: api.PodStatus{ Conditions: []api.PodCondition{ { Status: api.ConditionTrue, Type: api.PodReady, }, }, }, }, expectedNum: 2, }, { name: "kubectl logs - one unhealthy, one healthy", podList: newPodList(2, -1, 1, labelSet), sortBy: func(pods []*api.Pod) sort.Interface { return controller.ByLogging(pods) }, expected: &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "pod-2", Namespace: api.NamespaceDefault, CreationTimestamp: unversioned.Date(2016, time.April, 1, 1, 0, 1, 0, time.UTC), Labels: map[string]string{"test": "selector"}, }, Status: api.PodStatus{ Conditions: []api.PodCondition{ { Status: api.ConditionTrue, Type: api.PodReady, }, }, ContainerStatuses: []api.ContainerStatus{{RestartCount: 5}}, }, }, expectedNum: 2, }, { name: "kubectl attach - two ready pods", podList: newPodList(2, -1, -1, labelSet), sortBy: func(pods []*api.Pod) sort.Interface { return sort.Reverse(controller.ActivePods(pods)) }, expected: &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "pod-1", Namespace: api.NamespaceDefault, CreationTimestamp: unversioned.Date(2016, time.April, 1, 1, 0, 0, 0, time.UTC), Labels: map[string]string{"test": "selector"}, }, Status: api.PodStatus{ Conditions: []api.PodCondition{ { Status: api.ConditionTrue, Type: api.PodReady, }, }, }, }, expectedNum: 2, }, { name: "kubectl attach - wait for ready pod", podList: newPodList(1, 1, -1, labelSet), watching: []watch.Event{ { Type: watch.Modified, Object: &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "pod-1", Namespace: api.NamespaceDefault, CreationTimestamp: unversioned.Date(2016, time.April, 1, 1, 0, 0, 0, time.UTC), Labels: map[string]string{"test": "selector"}, }, Status: api.PodStatus{ Conditions: []api.PodCondition{ { Status: api.ConditionTrue, Type: api.PodReady, }, }, }, }, }, }, sortBy: func(pods []*api.Pod) sort.Interface { return sort.Reverse(controller.ActivePods(pods)) }, expected: &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "pod-1", Namespace: api.NamespaceDefault, CreationTimestamp: unversioned.Date(2016, time.April, 1, 1, 0, 0, 0, time.UTC), Labels: map[string]string{"test": "selector"}, }, Status: api.PodStatus{ Conditions: []api.PodCondition{ { Status: api.ConditionTrue, Type: api.PodReady, }, }, }, }, expectedNum: 1, }, } for i := range tests { test := tests[i] fake := fake.NewSimpleClientset(test.podList) if len(test.watching) > 0 { watcher := watch.NewFake() for _, event := range test.watching { switch event.Type { case watch.Added: go watcher.Add(event.Object) case watch.Modified: go watcher.Modify(event.Object) } } fake.PrependWatchReactor("pods", testcore.DefaultWatchReactor(watcher, nil)) } selector := labels.Set(labelSet).AsSelector() pod, numPods, err := GetFirstPod(fake.Core(), api.NamespaceDefault, selector, 1*time.Minute, test.sortBy) if !test.expectedErr && err != nil { t.Errorf("%s: unexpected error: %v", test.name, err) continue } if test.expectedErr && err == nil { t.Errorf("%s: expected an error", test.name) continue } if test.expectedNum != numPods { t.Errorf("%s: expected %d pods, got %d", test.name, test.expectedNum, numPods) continue } if !reflect.DeepEqual(test.expected, pod) { t.Errorf("%s:\nexpected pod:\n%#v\ngot:\n%#v\n\n", test.name, test.expected, pod) } } }
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) } } } }