func TestSyncReplicationControllerCreates(t *testing.T) { body := runtime.EncodeOrDie(testapi.Codec(), newPodList(0)) fakePodHandler := util.FakeHandler{ StatusCode: 200, ResponseBody: string(body), } fakePodControl := FakePodControl{} controller := newReplicationController(2) fakeUpdateHandler := util.FakeHandler{ StatusCode: 200, ResponseBody: runtime.EncodeOrDie(testapi.Codec(), &controller), T: t, } testServerMux := http.NewServeMux() testServerMux.Handle("/api/"+testapi.Version()+"/pods/", &fakePodHandler) testServerMux.Handle(fmt.Sprintf("/api/"+testapi.Version()+"/replicationControllers/%s", controller.Name), &fakeUpdateHandler) testServer := httptest.NewServer(testServerMux) defer testServer.Close() client := client.NewOrDie(&client.Config{Host: testServer.URL, Version: testapi.Version()}) manager := NewReplicationManager(client) manager.podControl = &fakePodControl manager.syncReplicationController(controller) validateSyncReplication(t, &fakePodControl, 2, 0) // No Status.Replicas update expected even though 2 pods were just created, // because the controller manager can't observe the pods till the next sync cycle. if fakeUpdateHandler.RequestReceived != nil { t.Errorf("Unexpected updates for controller via %v", fakeUpdateHandler.RequestReceived.URL) } }
func makeTestServer(t *testing.T, namespace, name string, podResponse, controllerResponse, updateResponse serverResponse) (*httptest.Server, *util.FakeHandler) { fakePodHandler := util.FakeHandler{ StatusCode: podResponse.statusCode, ResponseBody: runtime.EncodeOrDie(testapi.Codec(), podResponse.obj.(runtime.Object)), } fakeControllerHandler := util.FakeHandler{ StatusCode: controllerResponse.statusCode, ResponseBody: runtime.EncodeOrDie(testapi.Codec(), controllerResponse.obj.(runtime.Object)), } fakeUpdateHandler := util.FakeHandler{ StatusCode: updateResponse.statusCode, ResponseBody: runtime.EncodeOrDie(testapi.Codec(), updateResponse.obj.(runtime.Object)), } mux := http.NewServeMux() mux.Handle(testapi.ResourcePath("pods", namespace, ""), &fakePodHandler) mux.Handle(testapi.ResourcePath(replicationControllerResourceName(), "", ""), &fakeControllerHandler) if namespace != "" { mux.Handle(testapi.ResourcePath(replicationControllerResourceName(), namespace, ""), &fakeControllerHandler) } if name != "" { mux.Handle(testapi.ResourcePath(replicationControllerResourceName(), namespace, name), &fakeUpdateHandler) } mux.HandleFunc("/", func(res http.ResponseWriter, req *http.Request) { t.Errorf("unexpected request: %v", req.RequestURI) res.WriteHeader(http.StatusNotFound) }) return httptest.NewServer(mux), &fakeUpdateHandler }
func TestIgnoreStreamErrors(t *testing.T) { pods, svc := testData() r, w := io.Pipe() go func() { defer w.Close() w.Write([]byte(`{}`)) w.Write([]byte(runtime.EncodeOrDie(latest.Codec, &pods.Items[0]))) }() r2, w2 := io.Pipe() go func() { defer w2.Close() w2.Write([]byte(`{}`)) w2.Write([]byte(runtime.EncodeOrDie(latest.Codec, &svc.Items[0]))) }() b := NewBuilder(latest.RESTMapper, api.Scheme, fakeClient()). ContinueOnError(). // TODO: order seems bad, but allows clients to determine what they want... Stream(r, "1").Stream(r2, "2") test := &testVisitor{} singular := false err := b.Do().IntoSingular(&singular).Visit(test.Handle) if err != nil || singular || len(test.Infos) != 2 { t.Fatalf("unexpected response: %v %f %#v", err, singular, test.Infos) } if !reflect.DeepEqual([]runtime.Object{&pods.Items[0], &svc.Items[0]}, test.Objects()) { t.Errorf("unexpected visited objects: %#v", test.Objects()) } }
func TestEtcdDeleteService(t *testing.T) { ctx := api.NewDefaultContext() fakeClient := tools.NewFakeEtcdClient(t) registry := NewTestEtcdRegistryWithPods(fakeClient) key, _ := etcdgeneric.NamespaceKeyFunc(ctx, "/services/specs", "foo") key = etcdtest.AddPrefix(key) fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &api.Service{ObjectMeta: api.ObjectMeta{Name: "foo"}}), 0) path, _ := etcdgeneric.NamespaceKeyFunc(ctx, "/services/endpoints", "foo") endpointsKey := etcdtest.AddPrefix(path) fakeClient.Set(endpointsKey, runtime.EncodeOrDie(latest.Codec, &api.Endpoints{ObjectMeta: api.ObjectMeta{Name: "foo"}}), 0) err := registry.DeleteService(ctx, "foo") if err != nil { t.Errorf("unexpected error: %v", err) } if len(fakeClient.DeletedKeys) != 2 { t.Errorf("Expected 2 delete, found %#v", fakeClient.DeletedKeys) } if fakeClient.DeletedKeys[0] != key { t.Errorf("Unexpected key: %s, expected %s", fakeClient.DeletedKeys[0], key) } if fakeClient.DeletedKeys[1] != endpointsKey { t.Errorf("Unexpected key: %s, expected %s", fakeClient.DeletedKeys[1], endpointsKey) } }
func TestEtcdListControllers(t *testing.T) { fakeClient := tools.NewFakeEtcdClient(t) registry := NewTestEtcdRegistry(fakeClient) ctx := api.NewDefaultContext() key := makeControllerListKey(ctx) key = etcdtest.AddPrefix(key) fakeClient.Data[key] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Nodes: []*etcd.Node{ { Value: runtime.EncodeOrDie(latest.Codec, &api.ReplicationController{ObjectMeta: api.ObjectMeta{Name: "foo"}}), }, { Value: runtime.EncodeOrDie(latest.Codec, &api.ReplicationController{ObjectMeta: api.ObjectMeta{Name: "bar"}}), }, }, }, }, E: nil, } controllers, err := registry.ListControllers(ctx) if err != nil { t.Errorf("unexpected error: %v", err) } if len(controllers.Items) != 2 || controllers.Items[0].Name != "foo" || controllers.Items[1].Name != "bar" { t.Errorf("Unexpected controller list: %#v", controllers) } }
func TestEtcdList(t *testing.T) { registry, _, fakeClient, _ := newStorage(t) ctx := api.NewDefaultContext() key := registry.KeyRootFunc(ctx) key = etcdtest.AddPrefix(key) fakeClient.Data[key] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Nodes: []*etcd.Node{ { Value: runtime.EncodeOrDie(latest.Codec, &api.ResourceQuota{ ObjectMeta: api.ObjectMeta{Name: "foo"}, }), }, { Value: runtime.EncodeOrDie(latest.Codec, &api.ResourceQuota{ ObjectMeta: api.ObjectMeta{Name: "bar"}, }), }, }, }, }, E: nil, } obj, err := registry.List(ctx, labels.Everything(), fields.Everything()) if err != nil { t.Errorf("unexpected error: %v", err) } resourcequotas := obj.(*api.ResourceQuotaList) if len(resourcequotas.Items) != 2 || resourcequotas.Items[0].Name != "foo" || resourcequotas.Items[1].Name != "bar" { t.Errorf("Unexpected resourcequota list: %#v", resourcequotas) } }
func TestEtcdListNodes(t *testing.T) { ctx := api.NewContext() storage, fakeClient := newStorage(t) key := storage.KeyRootFunc(ctx) fakeClient.Data[key] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Nodes: []*etcd.Node{ { Value: runtime.EncodeOrDie(latest.Codec, &api.Node{ ObjectMeta: api.ObjectMeta{Name: "foo"}, }), }, { Value: runtime.EncodeOrDie(latest.Codec, &api.Node{ ObjectMeta: api.ObjectMeta{Name: "bar"}, }), }, }, }, }, E: nil, } nodesObj, err := storage.List(ctx, labels.Everything(), fields.Everything()) if err != nil { t.Errorf("unexpected error: %v", err) } nodes := nodesObj.(*api.NodeList) if len(nodes.Items) != 2 || nodes.Items[0].Name != "foo" || nodes.Items[1].Name != "bar" { t.Errorf("Unexpected nodes list: %#v", nodes) } }
func TestEtcdListEndpoints(t *testing.T) { fakeClient := tools.NewFakeEtcdClient(t) key := "/registry/services/endpoints" fakeClient.Data[key] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Nodes: []*etcd.Node{ { Value: runtime.EncodeOrDie(latest.Codec, &api.Endpoints{JSONBase: api.JSONBase{ID: "foo"}, Endpoints: []string{"127.0.0.1:8345"}}), }, { Value: runtime.EncodeOrDie(latest.Codec, &api.Endpoints{JSONBase: api.JSONBase{ID: "bar"}}), }, }, }, }, E: nil, } registry := NewTestEtcdRegistry(fakeClient) services, err := registry.ListEndpoints() if err != nil { t.Errorf("unexpected error: %v", err) } if len(services.Items) != 2 || services.Items[0].ID != "foo" || services.Items[1].ID != "bar" { t.Errorf("Unexpected endpoints list: %#v", services) } }
func TestEtcdListControllers(t *testing.T) { fakeClient := tools.NewFakeEtcdClient(t) key := "/registry/controllers" fakeClient.Data[key] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Nodes: []*etcd.Node{ { Value: runtime.EncodeOrDie(latest.Codec, &api.ReplicationController{JSONBase: api.JSONBase{ID: "foo"}}), }, { Value: runtime.EncodeOrDie(latest.Codec, &api.ReplicationController{JSONBase: api.JSONBase{ID: "bar"}}), }, }, }, }, E: nil, } registry := NewTestEtcdRegistry(fakeClient) controllers, err := registry.ListControllers() if err != nil { t.Errorf("unexpected error: %v", err) } if len(controllers.Items) != 2 || controllers.Items[0].ID != "foo" || controllers.Items[1].ID != "bar" { t.Errorf("Unexpected controller list: %#v", controllers) } }
func TestEtcdDeletePod(t *testing.T) { fakeClient := tools.NewFakeEtcdClient(t) fakeClient.TestIndex = true key := "/registry/pods/foo" fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &api.Pod{ JSONBase: api.JSONBase{ID: "foo"}, DesiredState: api.PodState{Host: "machine"}, }), 0) fakeClient.Set("/registry/hosts/machine/kubelet", runtime.EncodeOrDie(latest.Codec, &api.ContainerManifestList{ Items: []api.ContainerManifest{ {ID: "foo"}, }, }), 0) registry := NewTestEtcdRegistry(fakeClient) err := registry.DeletePod("foo") if err != nil { t.Errorf("unexpected error: %v", err) } if len(fakeClient.DeletedKeys) != 1 { t.Errorf("Expected 1 delete, found %#v", fakeClient.DeletedKeys) } else if fakeClient.DeletedKeys[0] != key { t.Errorf("Unexpected key: %s, expected %s", fakeClient.DeletedKeys[0], key) } response, err := fakeClient.Get("/registry/hosts/machine/kubelet", false, false) if err != nil { t.Fatalf("Unexpected error %v", err) } var manifests api.ContainerManifestList latest.Codec.DecodeInto([]byte(response.Node.Value), &manifests) if len(manifests.Items) != 0 { t.Errorf("Unexpected container set: %s, expected empty", response.Node.Value) } }
func TestControllerUpdateReplicas(t *testing.T) { // This is a happy server just to record the PUT request we expect for status.Replicas fakeHandler := util.FakeHandler{ StatusCode: 200, ResponseBody: "", } testServer := httptest.NewServer(&fakeHandler) defer testServer.Close() client := client.NewOrDie(&client.Config{Host: testServer.URL, Version: testapi.Version()}) manager := NewReplicationManager(client, BurstReplicas) // Insufficient number of pods in the system, and Status.Replicas is wrong; // Status.Replica should update to match number of pods in system, 1 new pod should be created. rc := newReplicationController(5) manager.controllerStore.Store.Add(rc) rc.Status = api.ReplicationControllerStatus{Replicas: 2} newPodList(manager.podStore.Store, 4, api.PodRunning, rc) response := runtime.EncodeOrDie(testapi.Codec(), rc) fakeHandler.ResponseBody = response fakePodControl := FakePodControl{} manager.podControl = &fakePodControl manager.syncReplicationController(getKey(rc, t)) // Status.Replicas should go up from 2->4 even though we created 5-4=1 pod rc.Status = api.ReplicationControllerStatus{Replicas: 4} decRc := runtime.EncodeOrDie(testapi.Codec(), rc) fakeHandler.ValidateRequest(t, testapi.ResourcePath(replicationControllerResourceName(), rc.Namespace, rc.Name), "PUT", &decRc) validateSyncReplication(t, &fakePodControl, 1, 0) }
func TestListImageStreamsPopulatedList(t *testing.T) { fakeEtcdClient, helper := newHelper(t) storage, _ := NewREST(helper, noDefaultRegistry, &fakeSubjectAccessReviewRegistry{}) fakeEtcdClient.Data["/imagestreams/default"] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Nodes: []*etcd.Node{ {Value: runtime.EncodeOrDie(latest.Codec, &api.ImageStream{ObjectMeta: kapi.ObjectMeta{Name: "foo"}})}, {Value: runtime.EncodeOrDie(latest.Codec, &api.ImageStream{ObjectMeta: kapi.ObjectMeta{Name: "bar"}})}, }, }, }, } list, err := storage.List(kapi.NewDefaultContext(), labels.Everything(), fields.Everything()) if err != nil { t.Fatalf("Unexpected non-nil error: %#v", err) } imageStreams := list.(*api.ImageStreamList) if e, a := 2, len(imageStreams.Items); e != a { t.Errorf("Expected %v, got %v", e, a) } }
func TestEtcdListMinions(t *testing.T) { ctx := api.NewContext() fakeClient := tools.NewFakeEtcdClient(t) key := "/registry/minions" fakeClient.Data[key] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Nodes: []*etcd.Node{ { Value: runtime.EncodeOrDie(latest.Codec, &api.Minion{ ObjectMeta: api.ObjectMeta{Name: "foo"}, }), }, { Value: runtime.EncodeOrDie(latest.Codec, &api.Minion{ ObjectMeta: api.ObjectMeta{Name: "bar"}, }), }, }, }, }, E: nil, } registry := NewTestEtcdRegistry(fakeClient) minions, err := registry.ListMinions(ctx) if err != nil { t.Errorf("unexpected error: %v", err) } if len(minions.Items) != 2 || minions.Items[0].Name != "foo" || minions.Items[1].Name != "bar" { t.Errorf("Unexpected minion list: %#v", minions) } }
func TestEtcdListPersistentVolumeClaims(t *testing.T) { ctx := api.NewDefaultContext() registry, _, fakeClient, _ := newStorage(t) key := registry.KeyRootFunc(ctx) key = etcdtest.AddPrefix(key) fakeClient.Data[key] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Nodes: []*etcd.Node{ { Value: runtime.EncodeOrDie(latest.Codec, validNewPersistentVolumeClaim("foo", api.NamespaceDefault)), }, { Value: runtime.EncodeOrDie(latest.Codec, validNewPersistentVolumeClaim("bar", api.NamespaceDefault)), }, }, }, }, E: nil, } pvObj, err := registry.List(ctx, labels.Everything(), fields.Everything()) if err != nil { t.Errorf("unexpected error: %v", err) } pvs := pvObj.(*api.PersistentVolumeClaimList) if len(pvs.Items) != 2 || pvs.Items[0].Name != "foo" || pvs.Items[1].Name != "bar" { t.Errorf("Unexpected persistentVolume list: %#v", pvs) } }
func TestWatchListFromZeroIndex(t *testing.T) { codec := latest.Codec pod := &api.Pod{JSONBase: api.JSONBase{ID: "foo"}} fakeClient := NewFakeEtcdClient(t) fakeClient.Data["/some/key"] = EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Dir: true, Nodes: etcd.Nodes{ &etcd.Node{ Value: runtime.EncodeOrDie(codec, pod), CreatedIndex: 1, ModifiedIndex: 1, Nodes: etcd.Nodes{}, }, &etcd.Node{ Value: runtime.EncodeOrDie(codec, pod), CreatedIndex: 2, ModifiedIndex: 2, Nodes: etcd.Nodes{}, }, }, }, Action: "get", EtcdIndex: 3, }, } h := EtcdHelper{fakeClient, codec, versioner} watching, err := h.WatchList("/some/key", 0, Everything) if err != nil { t.Fatalf("Unexpected error: %v", err) } // the existing node is detected and the index set event, open := <-watching.ResultChan() if !open { t.Fatalf("unexpected channel close") } for i := 0; i < 2; i++ { if e, a := watch.Added, event.Type; e != a { t.Errorf("Expected %v, got %v", e, a) } actualPod, ok := event.Object.(*api.Pod) if !ok { t.Fatalf("expected a pod, got %#v", event.Object) } if actualPod.ResourceVersion != 1 { t.Errorf("Expected pod with resource version %d, Got %#v", 1, actualPod) } pod.ResourceVersion = 1 if e, a := pod, event.Object; !reflect.DeepEqual(e, a) { t.Errorf("Expected %v, got %v", e, a) } } fakeClient.WaitForWatchCompletion() watching.Stop() }
func TestEtcdListControllers(t *testing.T) { storage, fakeClient := newStorage(t) ctx := api.NewDefaultContext() key := makeControllerListKey(ctx) key = etcdtest.AddPrefix(key) controller := validController controller.Name = "bar" fakeClient.Data[key] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Nodes: []*etcd.Node{ { Value: runtime.EncodeOrDie(latest.Codec, &validController), }, { Value: runtime.EncodeOrDie(latest.Codec, &controller), }, }, }, }, E: nil, } objList, err := storage.List(ctx, labels.Everything(), fields.Everything()) if err != nil { t.Errorf("unexpected error: %v", err) } controllers, _ := objList.(*api.ReplicationControllerList) if len(controllers.Items) != 2 || controllers.Items[0].Name != validController.Name || controllers.Items[1].Name != controller.Name { t.Errorf("Unexpected controller list: %#v", controllers) } }
func TestListObjectWithDifferentVersions(t *testing.T) { pods, svc := testData() obj, err := NewBuilder(latest.RESTMapper, api.Scheme, fakeClientWith(t, map[string]string{ "/ns/test/pods?labels=a%3Db": runtime.EncodeOrDie(latest.Codec, pods), "/ns/test/services?labels=a%3Db": runtime.EncodeOrDie(latest.Codec, svc), })). SelectorParam("a=b"). NamespaceParam("test"). ResourceTypeOrNameArgs("pods,services"). Flatten(). Do().Object() if err != nil { t.Fatalf("unexpected error: %v", err) } list, ok := obj.(*api.List) if !ok { t.Fatalf("unexpected object: %#v", obj) } // resource version differs between type lists, so it's not possible to get a single version. if list.ResourceVersion != "" || len(list.Items) != 3 { t.Errorf("unexpected list: %#v", list) } }
func TestListPopulatedList(t *testing.T) { fakeEtcdClient, helper := newHelper(t) fakeEtcdClient.ChangeIndex = 1 fakeEtcdClient.Data["/images"] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Nodes: []*etcd.Node{ {Value: runtime.EncodeOrDie(latest.Codec, &api.Image{ObjectMeta: kapi.ObjectMeta{Name: "foo"}})}, {Value: runtime.EncodeOrDie(latest.Codec, &api.Image{ObjectMeta: kapi.ObjectMeta{Name: "bar"}})}, }, }, }, } storage := NewREST(helper) list, err := storage.List(kapi.NewDefaultContext(), labels.Everything(), fields.Everything()) if err != nil { t.Errorf("Unexpected non-nil error: %#v", err) } images := list.(*api.ImageList) if e, a := 2, len(images.Items); e != a { t.Errorf("Expected %v, got %v", e, a) } }
func TestEtcdListImagesFiltered(t *testing.T) { fakeClient := tools.NewFakeEtcdClient(t) key := "/images" fakeClient.Data[key] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Nodes: []*etcd.Node{ { Value: runtime.EncodeOrDie(api.Image{ JSONBase: kubeapi.JSONBase{ID: "foo"}, Labels: map[string]string{"env": "prod"}, }), }, { Value: runtime.EncodeOrDie(api.Image{ JSONBase: kubeapi.JSONBase{ID: "bar"}, Labels: map[string]string{"env": "dev"}, }), }, }, }, }, E: nil, } registry := NewTestEtcdRegistry(fakeClient) images, err := registry.ListImages(labels.SelectorFromSet(labels.Set{"env": "dev"})) if err != nil { t.Errorf("unexpected error: %v", err) } if len(images.Items) != 1 || images.Items[0].ID != "bar" { t.Errorf("Unexpected images list: %#v", images) } }
func TestEtcdListBuildConfigs(t *testing.T) { fakeClient := tools.NewFakeEtcdClient(t) key := "/registry/build-configs" fakeClient.Data[key] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Nodes: []*etcd.Node{ { Value: runtime.EncodeOrDie(api.BuildConfig{ JSONBase: kubeapi.JSONBase{ID: "foo"}, }), }, { Value: runtime.EncodeOrDie(api.BuildConfig{ JSONBase: kubeapi.JSONBase{ID: "bar"}, }), }, }, }, }, E: nil, } registry := NewTestEtcdRegistry(fakeClient) buildConfigs, err := registry.ListBuildConfigs(labels.Everything()) if err != nil { t.Errorf("unexpected error: %v", err) } if len(buildConfigs.Items) != 2 || buildConfigs.Items[0].ID != "foo" || buildConfigs.Items[1].ID != "bar" { t.Errorf("Unexpected buildConfig list: %#v", buildConfigs) } }
func TestEtcdListImagesEverything(t *testing.T) { fakeClient := tools.NewFakeEtcdClient(t) key := "/images" fakeClient.Data[key] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Nodes: []*etcd.Node{ { Value: runtime.EncodeOrDie(api.Image{JSONBase: kubeapi.JSONBase{ID: "foo"}}), }, { Value: runtime.EncodeOrDie(api.Image{JSONBase: kubeapi.JSONBase{ID: "bar"}}), }, }, }, }, E: nil, } registry := NewTestEtcdRegistry(fakeClient) images, err := registry.ListImages(labels.Everything()) if err != nil { t.Errorf("unexpected error: %v", err) } if len(images.Items) != 2 || images.Items[0].ID != "foo" || images.Items[1].ID != "bar" { t.Errorf("Unexpected images list: %#v", images) } }
func TestLatest(t *testing.T) { r, _, _ := streamTestData() newPod := &api.Pod{ ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "test", ResourceVersion: "13"}, } newPod2 := &api.Pod{ ObjectMeta: api.ObjectMeta{Name: "bar", Namespace: "test", ResourceVersion: "14"}, } newSvc := &api.Service{ ObjectMeta: api.ObjectMeta{Name: "baz", Namespace: "test", ResourceVersion: "15"}, } b := NewBuilder(latest.RESTMapper, api.Scheme, fakeClientWith(t, map[string]string{ "/ns/test/pods/foo": runtime.EncodeOrDie(latest.Codec, newPod), "/ns/test/pods/bar": runtime.EncodeOrDie(latest.Codec, newPod2), "/ns/test/services/baz": runtime.EncodeOrDie(latest.Codec, newSvc), })). NamespaceParam("other").Stream(r, "STDIN").Flatten().Latest() test := &testVisitor{} singular := false err := b.Do().IntoSingular(&singular).Visit(test.Handle) if err != nil || singular || len(test.Infos) != 3 { t.Fatalf("unexpected response: %v %f %#v", err, singular, test.Infos) } if !reflect.DeepEqual([]runtime.Object{newPod, newPod2, newSvc}, test.Objects()) { t.Errorf("unexpected visited objects: %#v", test.Objects()) } }
func TestEtcdListServices(t *testing.T) { ctx := api.NewDefaultContext() fakeClient := tools.NewFakeEtcdClient(t) key := makeServiceListKey(ctx) fakeClient.Data[key] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Nodes: []*etcd.Node{ { Value: runtime.EncodeOrDie(latest.Codec, &api.Service{ObjectMeta: api.ObjectMeta{Name: "foo"}}), }, { Value: runtime.EncodeOrDie(latest.Codec, &api.Service{ObjectMeta: api.ObjectMeta{Name: "bar"}}), }, }, }, }, E: nil, } registry := NewTestEtcdRegistry(fakeClient) services, err := registry.ListServices(ctx) if err != nil { t.Errorf("unexpected error: %v", err) } if len(services.Items) != 2 || services.Items[0].Name != "foo" || services.Items[1].Name != "bar" { t.Errorf("Unexpected service list: %#v", services) } }
func TestSelector(t *testing.T) { pods, svc := testData() b := NewBuilder(latest.RESTMapper, api.Scheme, fakeClientWith(t, map[string]string{ "/ns/test/pods?labels=a%3Db": runtime.EncodeOrDie(latest.Codec, pods), "/ns/test/services?labels=a%3Db": runtime.EncodeOrDie(latest.Codec, svc), })). SelectorParam("a=b"). NamespaceParam("test"). Flatten() test := &testVisitor{} singular := false if b.Do().Err() == nil { t.Errorf("unexpected non-error") } b.ResourceTypeOrNameArgs("pods,service") err := b.Do().IntoSingular(&singular).Visit(test.Handle) if err != nil || singular || len(test.Infos) != 3 { t.Fatalf("unexpected response: %v %f %#v", err, singular, test.Infos) } if !reflect.DeepEqual([]runtime.Object{&pods.Items[0], &pods.Items[1], &svc.Items[0]}, test.Objects()) { t.Errorf("unexpected visited objects: %#v", test.Objects()) } if _, err := b.Do().ResourceMapping(); err == nil { t.Errorf("unexpected non-error") } }
func TestEtcdListEverythingRoutes(t *testing.T) { fakeClient := tools.NewFakeEtcdClient(t) key := makeTestDefaultRouteListKey() fakeClient.Data[key] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Nodes: []*etcd.Node{ { Value: runtime.EncodeOrDie(latest.Codec, &api.Route{ObjectMeta: kapi.ObjectMeta{Name: "foo"}}), }, { Value: runtime.EncodeOrDie(latest.Codec, &api.Route{ObjectMeta: kapi.ObjectMeta{Name: "bar"}}), }, }, }, }, E: nil, } registry := NewTestEtcd(fakeClient) routes, err := registry.ListRoutes(kapi.NewDefaultContext(), labels.Everything()) if err != nil { t.Errorf("unexpected error: %v", err) } if len(routes.Items) != 2 || routes.Items[0].Name != "foo" || routes.Items[1].Name != "bar" { t.Errorf("Unexpected routes list: %#v", routes) } }
func streamTestData() (io.Reader, *api.PodList, *api.ServiceList) { pods, svc := testData() r, w := io.Pipe() go func() { defer w.Close() w.Write([]byte(runtime.EncodeOrDie(latest.Codec, pods))) w.Write([]byte(runtime.EncodeOrDie(latest.Codec, svc))) }() return r, pods, svc }
// TestVerifyImageStreamAccess mocks openshift http request/response and // tests invalid/valid/scoped openshift tokens. func TestVerifyImageStreamAccess(t *testing.T) { tests := []struct { openshiftResponse response expectedError error }{ { // Test invalid openshift bearer token openshiftResponse: response{401, "Unauthorized"}, expectedError: ErrOpenShiftAccessDenied, }, { // Test valid openshift bearer token but token *not* scoped for create operation openshiftResponse: response{ 200, runtime.EncodeOrDie(latest.Codec, &api.SubjectAccessReviewResponse{ Namespace: "foo", Allowed: false, Reason: "not authorized!", }), }, expectedError: ErrOpenShiftAccessDenied, }, { // Test valid openshift bearer token and token scoped for create operation openshiftResponse: response{ 200, runtime.EncodeOrDie(latest.Codec, &api.SubjectAccessReviewResponse{ Namespace: "foo", Allowed: true, Reason: "authorized!", }), }, expectedError: nil, }, } for _, test := range tests { server, _ := simulateOpenShiftMaster([]response{test.openshiftResponse}) client, err := NewUserOpenShiftClient("magic bearer token") if err != nil { t.Fatal(err) } err = verifyImageStreamAccess("foo", "bar", "create", client) if err == nil || test.expectedError == nil { if err != test.expectedError { t.Fatal("verifyImageStreamAccess did not get expected error - got %s - expected %s", err, test.expectedError) } } else if err.Error() != test.expectedError.Error() { t.Fatal("verifyImageStreamAccess did not get expected error - got %s - expected %s", err, test.expectedError) } server.Close() } }
func TestControllerUpdateReplicas(t *testing.T) { // Insufficient number of pods in the system, and Status.Replicas is wrong; // Status.Replica should update to match number of pods in system, 1 new pod should be created. rc := newReplicationController(5) rc.Status = api.ReplicationControllerStatus{Replicas: 2} activePods := 4 body, _ := latest.Codec.Encode(newPodList(activePods)) fakePodHandler := util.FakeHandler{ StatusCode: 200, ResponseBody: string(body), T: t, } fakeControllerHandler := util.FakeHandler{ StatusCode: 200, ResponseBody: runtime.EncodeOrDie(latest.Codec, &api.ReplicationControllerList{ Items: []api.ReplicationController{rc}, }), T: t, } fakeUpdateHandler := util.FakeHandler{ StatusCode: 200, ResponseBody: runtime.EncodeOrDie(testapi.Codec(), &rc), T: t, } mux := http.NewServeMux() mux.Handle("/api/"+testapi.Version()+"/pods/", &fakePodHandler) mux.Handle("/api/"+testapi.Version()+"/replicationControllers/", &fakeControllerHandler) mux.Handle(fmt.Sprintf("/api/"+testapi.Version()+"/replicationControllers/%s", rc.Name), &fakeUpdateHandler) mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) { w.WriteHeader(http.StatusNotFound) t.Errorf("Unexpected request for %v", req.RequestURI) }) testServer := httptest.NewServer(mux) defer testServer.Close() client := client.NewOrDie(&client.Config{Host: testServer.URL, Version: testapi.Version()}) manager := NewReplicationManager(client) fakePodControl := FakePodControl{} manager.podControl = &fakePodControl manager.synchronize() // Status.Replicas should go up from 2->4 even though we created 5-4=1 pod rc.Status = api.ReplicationControllerStatus{Replicas: 4} decRc := runtime.EncodeOrDie(testapi.Codec(), &rc) fakeUpdateHandler.ValidateRequest(t, fmt.Sprintf("/api/"+testapi.Version()+"/replicationControllers/%s?namespace=%s", rc.Name, rc.Namespace), "PUT", &decRc) validateSyncReplication(t, &fakePodControl, 1, 0) }
func TestEtcdListRoutesInDifferentNamespaces(t *testing.T) { fakeClient := tools.NewFakeEtcdClient(t) namespaceAlfa := kapi.WithNamespace(kapi.NewContext(), "alfa") namespaceBravo := kapi.WithNamespace(kapi.NewContext(), "bravo") fakeClient.Data["/routes/alfa"] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Nodes: []*etcd.Node{ { Value: runtime.EncodeOrDie(latest.Codec, &api.Route{ObjectMeta: kapi.ObjectMeta{Name: "foo1"}}), }, }, }, }, E: nil, } fakeClient.Data["/routes/bravo"] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Nodes: []*etcd.Node{ { Value: runtime.EncodeOrDie(latest.Codec, &api.Route{ObjectMeta: kapi.ObjectMeta{Name: "foo2"}}), }, { Value: runtime.EncodeOrDie(latest.Codec, &api.Route{ObjectMeta: kapi.ObjectMeta{Name: "bar2"}}), }, }, }, }, E: nil, } registry := NewTestEtcd(fakeClient) routesAlfa, err := registry.ListRoutes(namespaceAlfa, labels.Everything()) if err != nil { t.Errorf("unexpected error: %v", err) } if len(routesAlfa.Items) != 1 || routesAlfa.Items[0].Name != "foo1" { t.Errorf("Unexpected builds list: %#v", routesAlfa) } routesBravo, err := registry.ListRoutes(namespaceBravo, labels.Everything()) if err != nil { t.Errorf("unexpected error: %v", err) } if len(routesBravo.Items) != 2 || routesBravo.Items[0].Name != "foo2" || routesBravo.Items[1].Name != "bar2" { t.Errorf("Unexpected builds list: %#v", routesBravo) } }
func TestControllerNoReplicaUpdate(t *testing.T) { // Steady state for the replication controller, no Status.Replicas updates expected rc := newReplicationController(5) rc.Status = api.ReplicationControllerStatus{Replicas: 5} activePods := 5 body, _ := latest.Codec.Encode(newPodList(activePods)) fakePodHandler := util.FakeHandler{ StatusCode: 200, ResponseBody: string(body), T: t, } fakeControllerHandler := util.FakeHandler{ StatusCode: 200, ResponseBody: runtime.EncodeOrDie(latest.Codec, &api.ReplicationControllerList{ Items: []api.ReplicationController{rc}, }), T: t, } fakeUpdateHandler := util.FakeHandler{ StatusCode: 200, ResponseBody: runtime.EncodeOrDie(testapi.Codec(), &rc), T: t, } mux := http.NewServeMux() mux.Handle("/api/"+testapi.Version()+"/pods/", &fakePodHandler) mux.Handle("/api/"+testapi.Version()+"/replicationControllers/", &fakeControllerHandler) mux.Handle(fmt.Sprintf("/api/"+testapi.Version()+"/replicationControllers/%s", rc.Name), &fakeUpdateHandler) mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) { w.WriteHeader(http.StatusNotFound) t.Errorf("Unexpected request for %v", req.RequestURI) }) testServer := httptest.NewServer(mux) defer testServer.Close() client := client.NewOrDie(&client.Config{Host: testServer.URL, Version: testapi.Version()}) manager := NewReplicationManager(client) fakePodControl := FakePodControl{} manager.podControl = &fakePodControl manager.synchronize() validateSyncReplication(t, &fakePodControl, 0, 0) if fakeUpdateHandler.RequestReceived != nil { t.Errorf("Unexpected updates for controller via %v", fakeUpdateHandler.RequestReceived.URL) } }