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 TestSetObjWithoutResourceVersioner(t *testing.T) { obj := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}} fakeClient := NewFakeEtcdClient(t) helper := NewEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix()) helper.Versioner = nil returnedObj := &api.Pod{} err := helper.SetObj("/some/key", obj, returnedObj, 3) key := etcdtest.AddPrefix("/some/key") if err != nil { t.Errorf("Unexpected error %#v", err) } data, err := testapi.Codec().Encode(obj) if err != nil { t.Errorf("Unexpected error %#v", err) } expect := string(data) got := fakeClient.Data[key].R.Node.Value if expect != got { t.Errorf("Wanted %v, got %v", expect, got) } if e, a := uint64(3), fakeClient.LastSetTTL; e != a { t.Errorf("Wanted %v, got %v", e, a) } if obj.ResourceVersion != returnedObj.ResourceVersion || obj.Name != returnedObj.Name { t.Errorf("If set was successful but returned object did not have correct resource version") } }
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 TestSetObjWithVersion(t *testing.T) { obj := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"}} fakeClient := NewFakeEtcdClient(t) fakeClient.TestIndex = true fakeClient.Data["/some/key"] = EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Value: runtime.EncodeOrDie(testapi.Codec(), obj), ModifiedIndex: 1, }, }, } helper := NewEtcdHelper(fakeClient, testapi.Codec()) returnedObj := &api.Pod{} err := helper.SetObj("/some/key", obj, returnedObj, 7) if err != nil { t.Fatalf("Unexpected error %#v", err) } data, err := testapi.Codec().Encode(obj) if err != nil { t.Fatalf("Unexpected error %#v", err) } expect := string(data) got := fakeClient.Data["/some/key"].R.Node.Value if expect != got { t.Errorf("Wanted %v, got %v", expect, got) } if e, a := uint64(7), fakeClient.LastSetTTL; e != a { t.Errorf("Wanted %v, got %v", e, a) } if obj.ResourceVersion != returnedObj.ResourceVersion || obj.Name != returnedObj.Name { t.Errorf("If set was successful but returned object did not have correct resource version") } }
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 TestSetObjWithVersion(t *testing.T) { obj := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"}} fakeClient := NewFakeEtcdClient(t) fakeClient.TestIndex = true fakeClient.Data["/some/key"] = EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Value: runtime.EncodeOrDie(testapi.Codec(), obj), ModifiedIndex: 1, }, }, } helper := EtcdHelper{fakeClient, testapi.Codec(), versioner} err := helper.SetObj("/some/key", obj) if err != nil { t.Fatalf("Unexpected error %#v", err) } data, err := testapi.Codec().Encode(obj) if err != nil { t.Fatalf("Unexpected error %#v", err) } expect := string(data) got := fakeClient.Data["/some/key"].R.Node.Value if expect != got { t.Errorf("Wanted %v, got %v", expect, got) } }
func TestDoRequestNewWayFile(t *testing.T) { reqObj := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}} reqBodyExpected, err := testapi.Codec().Encode(reqObj) if err != nil { t.Errorf("unexpected error: %v", err) } file, err := ioutil.TempFile("", "foo") if err != nil { t.Errorf("unexpected error: %v", err) } _, err = file.Write(reqBodyExpected) if err != nil { t.Errorf("unexpected error: %v", err) } expectedObj := &api.Service{Spec: api.ServiceSpec{Ports: []api.ServicePort{{ Protocol: "TCP", Port: 12345, TargetPort: util.NewIntOrStringFromInt(12345), }}}} expectedBody, _ := testapi.Codec().Encode(expectedObj) fakeHandler := util.FakeHandler{ StatusCode: 200, ResponseBody: string(expectedBody), T: t, } testServer := httptest.NewServer(&fakeHandler) c := NewOrDie(&Config{Host: testServer.URL, Version: testapi.Version(), Username: "******", Password: "******"}) wasCreated := true obj, err := c.Verb("POST"). Prefix("foo/bar", "baz"). Timeout(time.Second). Body(file.Name()). Do().WasCreated(&wasCreated).Get() if err != nil { t.Errorf("Unexpected error: %v %#v", err, err) return } if obj == nil { t.Error("nil obj") } else if !api.Semantic.DeepDerivative(expectedObj, obj) { t.Errorf("Expected: %#v, got %#v", expectedObj, obj) } if wasCreated { t.Errorf("expected object was not created") } tmpStr := string(reqBodyExpected) requestURL := testapi.ResourcePathWithPrefix("foo/bar/baz", "", "", "") requestURL += "?timeout=1s" fakeHandler.ValidateRequest(t, requestURL, "POST", &tmpStr) if fakeHandler.RequestReceived.Header["Authorization"] == nil { t.Errorf("Request is missing authorization header: %#v", *fakeHandler.RequestReceived) } }
func TestWatch(t *testing.T) { client := framework.NewEtcdClient() etcdStorage := tools.NewEtcdStorage(client, testapi.Codec(), etcdtest.PathPrefix()) framework.WithEtcdKey(func(key string) { key = etcdtest.AddPrefix(key) resp, err := client.Set(key, runtime.EncodeOrDie(testapi.Codec(), &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}), 0) if err != nil { t.Fatalf("unexpected error: %v", err) } expectedVersion := resp.Node.ModifiedIndex // watch should load the object at the current index w, err := etcdStorage.Watch(key, 0, tools.Everything) if err != nil { t.Fatalf("Unexpected error: %v", err) } event := <-w.ResultChan() if event.Type != watch.Added || event.Object == nil { t.Fatalf("expected first value to be set to ADDED, got %#v", event) } // version should match what we set pod := event.Object.(*api.Pod) if pod.ResourceVersion != strconv.FormatUint(expectedVersion, 10) { t.Errorf("expected version %d, got %#v", expectedVersion, pod) } // should be no events in the stream select { case event, ok := <-w.ResultChan(): if !ok { t.Fatalf("channel closed unexpectedly") } t.Fatalf("unexpected object in channel: %#v", event) default: } // should return the previously deleted item in the watch, but with the latest index resp, err = client.Delete(key, false) if err != nil { t.Fatalf("unexpected error: %v", err) } expectedVersion = resp.Node.ModifiedIndex event = <-w.ResultChan() if event.Type != watch.Deleted { t.Errorf("expected deleted event %#v", event) } pod = event.Object.(*api.Pod) if pod.ResourceVersion != strconv.FormatUint(expectedVersion, 10) { t.Errorf("expected version %d, got %#v", expectedVersion, pod) } }) }
func TestDecoder(t *testing.T) { table := []watch.EventType{watch.Added, watch.Deleted, watch.Modified, watch.Error} for _, eventType := range table { out, in := io.Pipe() decoder := NewDecoder(out, testapi.Codec()) expect := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}} encoder := json.NewEncoder(in) go func() { data, err := testapi.Codec().Encode(expect) if err != nil { t.Fatalf("Unexpected error %v", err) } if err := encoder.Encode(&watchEvent{eventType, runtime.RawExtension{json.RawMessage(data)}}); err != nil { t.Errorf("Unexpected error %v", err) } in.Close() }() done := make(chan struct{}) go func() { action, got, err := decoder.Decode() if err != nil { t.Fatalf("Unexpected error %v", err) } if e, a := eventType, action; e != a { t.Errorf("Expected %v, got %v", e, a) } if e, a := expect, got; !reflect.DeepEqual(e, a) { t.Errorf("Expected %v, got %v", e, a) } t.Logf("Exited read") close(done) }() <-done done = make(chan struct{}) go func() { _, _, err := decoder.Decode() if err == nil { t.Errorf("Unexpected nil error") } close(done) }() <-done decoder.Close() } }
func TestExtractObj(t *testing.T) { fakeClient := NewFakeEtcdClient(t) expect := api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}} fakeClient.Set("/some/key", runtime.EncodeOrDie(testapi.Codec(), &expect), 0) helper := EtcdHelper{fakeClient, testapi.Codec(), versioner} var got api.Pod err := helper.ExtractObj("/some/key", &got, false) if err != nil { t.Errorf("Unexpected error %#v", err) } if !reflect.DeepEqual(got, expect) { t.Errorf("Wanted %#v, got %#v", expect, got) } }
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 TestDoRequestBearer(t *testing.T) { status := &api.Status{Status: api.StatusFailure} expectedBody, _ := latest.Codec.Encode(status) fakeHandler := util.FakeHandler{ StatusCode: 400, ResponseBody: string(expectedBody), T: t, } testServer := httptest.NewServer(&fakeHandler) defer testServer.Close() request, _ := http.NewRequest("GET", testServer.URL, nil) c, err := RESTClientFor(&Config{ Host: testServer.URL, Version: testapi.Version(), Codec: testapi.Codec(), LegacyBehavior: true, BearerToken: "test", }) if err != nil { t.Fatalf("unexpected error: %v", err) } err = c.Get().Do().Error() if err == nil { t.Fatalf("unexpected non-error: %v", err) } if fakeHandler.RequestReceived.Header.Get("Authorization") != "Bearer test" { t.Errorf("Request is missing authorization header: %#v", *request) } }
func TestEtcdWatch(t *testing.T) { podA := &api.Pod{ ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"}, Status: api.PodStatus{Host: "machine"}, } respWithPodA := &etcd.Response{ Node: &etcd.Node{ Value: runtime.EncodeOrDie(testapi.Codec(), podA), ModifiedIndex: 1, CreatedIndex: 1, }, Action: "create", } fakeClient, registry := NewTestGenericEtcdRegistry(t) wi, err := registry.Watch(api.NewContext(), EverythingMatcher{}, "1") if err != nil { t.Fatalf("unexpected error: %v", err) } fakeClient.WaitForWatchCompletion() go func() { fakeClient.WatchResponse <- respWithPodA }() got, open := <-wi.ResultChan() if !open { t.Fatalf("unexpected channel close") } if e, a := podA, got.Object; !reflect.DeepEqual(e, a) { t.Errorf("difference: %s", util.ObjectDiff(e, a)) } }
func NewAPIFactory() (*cmdutil.Factory, *testFactory, runtime.Codec) { t := &testFactory{ Validator: validation.NullSchema{}, } return &cmdutil.Factory{ Object: func() (meta.RESTMapper, runtime.ObjectTyper) { return latest.RESTMapper, api.Scheme }, Client: func() (*client.Client, error) { // Swap out the HTTP client out of the client with the fake's version. fakeClient := t.Client.(*client.FakeRESTClient) c := client.NewOrDie(t.ClientConfig) c.Client = fakeClient.Client return c, t.Err }, RESTClient: func(*meta.RESTMapping) (resource.RESTClient, error) { return t.Client, t.Err }, Describer: func(*meta.RESTMapping) (kubectl.Describer, error) { return t.Describer, t.Err }, Printer: func(mapping *meta.RESTMapping, noHeaders bool) (kubectl.ResourcePrinter, error) { return t.Printer, t.Err }, Validator: func() (validation.Schema, error) { return t.Validator, t.Err }, DefaultNamespace: func() (string, error) { return t.Namespace, t.Err }, ClientConfig: func() (*client.Config, error) { return t.ClientConfig, t.Err }, }, t, testapi.Codec() }
func TestBind(t *testing.T) { table := []struct { binding *api.Binding }{ {binding: &api.Binding{PodID: "foo", Host: "foohost.kubernetes.mydomain.com"}}, } for _, item := range table { handler := util.FakeHandler{ StatusCode: 200, ResponseBody: "", T: t, } server := httptest.NewServer(&handler) defer server.Close() client := client.NewOrDie(&client.Config{Host: server.URL, Version: testapi.Version()}) b := binder{client} if err := b.Bind(item.binding); err != nil { t.Errorf("Unexpected error: %v", err) continue } expectedBody := runtime.EncodeOrDie(testapi.Codec(), item.binding) handler.ValidateRequest(t, "/api/"+testapi.Version()+"/bindings", "POST", &expectedBody) } }
func TestDoRequestFailed(t *testing.T) { status := &api.Status{Status: api.StatusFailure, Reason: api.StatusReasonInvalid, Details: &api.StatusDetails{ID: "test", Kind: "test"}} expectedBody, _ := latest.Codec.Encode(status) fakeHandler := util.FakeHandler{ StatusCode: 404, ResponseBody: string(expectedBody), T: t, } testServer := httptest.NewServer(&fakeHandler) defer testServer.Close() c, err := RESTClientFor(&Config{ Host: testServer.URL, Version: testapi.Version(), Codec: testapi.Codec(), LegacyBehavior: true, }) if err != nil { t.Fatalf("unexpected error: %v", err) } body, err := c.Get().Do().Raw() if err == nil || body != nil { t.Errorf("unexpected non-error: %#v", body) } ss, ok := err.(APIStatus) if !ok { t.Errorf("unexpected error type %v", err) } actual := ss.Status() if !reflect.DeepEqual(status, &actual) { t.Errorf("Unexpected mis-match. Expected %#v. Saw %#v", status, actual) } }
func TestValidateOk(t *testing.T) { schema, err := loadSchemaForTest() if err != nil { t.Errorf("Failed to load: %v", err) } tests := []struct { obj runtime.Object typeName string }{ {obj: &api.Pod{}}, {obj: &api.Service{}}, {obj: &api.ReplicationController{}}, } seed := rand.Int63() apiObjectFuzzer := apitesting.FuzzerFor(nil, "", rand.NewSource(seed)) for i := 0; i < 5; i++ { for _, test := range tests { testObj := test.obj apiObjectFuzzer.Fuzz(testObj) data, err := testapi.Codec().Encode(testObj) if err != nil { t.Errorf("unexpected error: %v", err) } err = schema.ValidateBytes(data) if err != nil { t.Errorf("unexpected error: %v", err) } } } }
func TestSetsCodec(t *testing.T) { testCases := map[string]struct { Err bool Prefix string Codec runtime.Codec }{ testapi.Version(): {false, "/api/" + testapi.Version() + "/", testapi.Codec()}, "invalidVersion": {true, "", nil}, } for version, expected := range testCases { client, err := New(&Config{Host: "127.0.0.1", Version: version}) switch { case err == nil && expected.Err: t.Errorf("expected error but was nil") continue case err != nil && !expected.Err: t.Errorf("unexpected error %v", err) continue case err != nil: continue } if e, a := expected.Prefix, client.RESTClient.baseURL.Path; e != a { t.Errorf("expected %#v, got %#v", e, a) } if e, a := expected.Codec, client.RESTClient.Codec; e != a { t.Errorf("expected %#v, got %#v", e, a) } } }
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 testServer, fakeUpdateHandler := makeTestServer(t, api.NamespaceDefault, rc.Name, serverResponse{http.StatusOK, newPodList(activePods)}, serverResponse{http.StatusOK, &api.ReplicationControllerList{ Items: []api.ReplicationController{rc}, }}, serverResponse{http.StatusOK, &rc}) 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} // These are set by default. rc.Spec.Selector = rc.Spec.Template.Labels rc.Labels = rc.Spec.Template.Labels decRc := runtime.EncodeOrDie(testapi.Codec(), &rc) fakeUpdateHandler.ValidateRequest(t, testapi.ResourcePathWithNamespaceQuery(replicationControllerResourceName(), rc.Namespace, rc.Name), "PUT", &decRc) validateSyncReplication(t, &fakePodControl, 1, 0) }
func TestSyncEndpointsItems(t *testing.T) { serviceList := api.ServiceList{ Items: []api.Service{ { ObjectMeta: api.ObjectMeta{Name: "foo"}, Spec: api.ServiceSpec{ Selector: map[string]string{ "foo": "bar", }, }, }, }, } testServer, endpointsHandler := makeTestServer(t, serverResponse{http.StatusOK, newPodList(1)}, serverResponse{http.StatusOK, serviceList}, serverResponse{http.StatusOK, api.Endpoints{}}) defer testServer.Close() client := client.NewOrDie(&client.Config{Host: testServer.URL, Version: testapi.Version()}) endpoints := NewEndpointController(client) if err := endpoints.SyncServiceEndpoints(); err != nil { t.Errorf("unexpected error: %v", err) } data := runtime.EncodeOrDie(testapi.Codec(), &api.Endpoints{ ObjectMeta: api.ObjectMeta{ ResourceVersion: "", }, Endpoints: []string{"1.2.3.4:8080"}, }) endpointsHandler.ValidateRequest(t, "/api/"+testapi.Version()+"/endpoints", "POST", &data) }
func TestBind(t *testing.T) { table := []struct { binding *api.Binding }{ {binding: &api.Binding{ ObjectMeta: api.ObjectMeta{ Namespace: api.NamespaceDefault, Name: "foo", }, Target: api.ObjectReference{ Name: "foohost.kubernetes.mydomain.com", }, }}, } for _, item := range table { handler := util.FakeHandler{ StatusCode: 200, ResponseBody: "", T: t, } server := httptest.NewServer(&handler) defer server.Close() client := client.NewOrDie(&client.Config{Host: server.URL, Version: testapi.Version()}) b := binder{client} if err := b.Bind(item.binding); err != nil { t.Errorf("Unexpected error: %v", err) continue } expectedBody := runtime.EncodeOrDie(testapi.Codec(), item.binding) handler.ValidateRequest(t, testapi.ResourcePath("bindings", api.NamespaceDefault, ""), "POST", &expectedBody) } }
func NewTestEventEtcdRegistry(t *testing.T) (*tools.FakeEtcdClient, generic.Registry) { f := tools.NewFakeEtcdClient(t) f.TestIndex = true h := tools.NewEtcdHelper(f, testapi.Codec(), etcdtest.PathPrefix()) return f, NewEtcdRegistry(h, testTTL) }
func TestTransformResponse(t *testing.T) { invalid := []byte("aaaaa") uri, _ := url.Parse("http://localhost") testCases := []struct { Response *http.Response Data []byte Created bool Error bool }{ {Response: &http.Response{StatusCode: 200}, Data: []byte{}}, {Response: &http.Response{StatusCode: 201}, Data: []byte{}, Created: true}, {Response: &http.Response{StatusCode: 199}, Error: true}, {Response: &http.Response{StatusCode: 500}, Error: true}, {Response: &http.Response{StatusCode: 200, Body: ioutil.NopCloser(bytes.NewReader(invalid))}, Data: invalid}, {Response: &http.Response{StatusCode: 200, Body: ioutil.NopCloser(bytes.NewReader(invalid))}, Data: invalid}, } for i, test := range testCases { r := NewRequest(nil, "", uri, testapi.Codec()) if test.Response.Body == nil { test.Response.Body = ioutil.NopCloser(bytes.NewReader([]byte{})) } response, created, err := r.transformResponse(test.Response, &http.Request{}) hasErr := err != nil if hasErr != test.Error { t.Errorf("%d: unexpected error: %f %v", i, test.Error, err) } if !(test.Data == nil && response == nil) && !reflect.DeepEqual(test.Data, response) { t.Errorf("%d: unexpected response: %#v %#v", i, test.Data, response) } if test.Created != created { t.Errorf("%d: expected created %f, got %f", i, test.Created, created) } } }
func TestDecodeSinglePod(t *testing.T) { pod := &api.Pod{ TypeMeta: api.TypeMeta{ APIVersion: "", }, ObjectMeta: api.ObjectMeta{ Name: "test", UID: "12345", Namespace: "mynamespace", }, Spec: api.PodSpec{ RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, Containers: []api.Container{{ Name: "image", Image: "test/image", ImagePullPolicy: "IfNotPresent", TerminationMessagePath: "/dev/termination-log", SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(), }}, }, } json, err := testapi.Codec().Encode(pod) if err != nil { t.Errorf("unexpected error: %v", err) } parsed, podOut, err := tryDecodeSinglePod(json, noDefault) if !parsed { t.Errorf("expected to have parsed file: (%s)", string(json)) } if err != nil { t.Errorf("unexpected error: %v (%s)", err, string(json)) } if !reflect.DeepEqual(pod, podOut) { t.Errorf("expected:\n%#v\ngot:\n%#v\n%s", pod, podOut, string(json)) } for _, version := range registered.RegisteredVersions { externalPod, err := testapi.Converter().ConvertToVersion(pod, version) if err != nil { t.Errorf("unexpected error: %v", err) } yaml, err := yaml.Marshal(externalPod) if err != nil { t.Errorf("unexpected error: %v", err) } parsed, podOut, err = tryDecodeSinglePod(yaml, noDefault) if !parsed { t.Errorf("expected to have parsed file: (%s)", string(yaml)) } if err != nil { t.Errorf("unexpected error: %v (%s)", err, string(yaml)) } if !reflect.DeepEqual(pod, podOut) { t.Errorf("expected:\n%#v\ngot:\n%#v\n%s", pod, podOut, string(yaml)) } } }
func body(obj runtime.Object, raw *string) *string { if obj != nil { bs, _ := testapi.Codec().Encode(obj) body := string(bs) return &body } return raw }
func TestEtcdDelete(t *testing.T) { podA := &api.Pod{ ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"}, Spec: api.PodSpec{Host: "machine"}, } nodeWithPodA := tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Value: runtime.EncodeOrDie(testapi.Codec(), podA), ModifiedIndex: 1, CreatedIndex: 1, }, }, E: nil, } emptyNode := tools.EtcdResponseWithError{ R: &etcd.Response{}, E: tools.EtcdErrorNotFound, } key := "foo" table := map[string]struct { existing tools.EtcdResponseWithError expect tools.EtcdResponseWithError errOK func(error) bool }{ "normal": { existing: nodeWithPodA, expect: emptyNode, errOK: func(err error) bool { return err == nil }, }, "notExisting": { existing: emptyNode, expect: emptyNode, errOK: func(err error) bool { return errors.IsNotFound(err) }, }, } for name, item := range table { fakeClient, registry := NewTestGenericEtcdRegistry(t) path := etcdtest.AddPrefix("pods/foo") fakeClient.Data[path] = item.existing obj, err := registry.Delete(api.NewContext(), key, nil) if !item.errOK(err) { t.Errorf("%v: unexpected error: %v (%#v)", name, err, obj) } if item.expect.E != nil { item.expect.E.(*etcd.EtcdError).Index = fakeClient.ChangeIndex } if e, a := item.expect, fakeClient.Data[path]; !api.Semantic.DeepDerivative(e, a) { t.Errorf("%v:\n%s", name, util.ObjectDiff(e, a)) } } }
func TestEncodeDecodeRoundTrip(t *testing.T) { testCases := []struct { Type watch.EventType Object runtime.Object Codec runtime.Codec }{ { watch.Added, &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}, testapi.Codec(), }, { watch.Modified, &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}, testapi.Codec(), }, { watch.Deleted, &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}, testapi.Codec(), }, } for i, testCase := range testCases { buf := &bytes.Buffer{} encoder := NewEncoder(buf, testCase.Codec) if err := encoder.Encode(&watch.Event{Type: testCase.Type, Object: testCase.Object}); err != nil { t.Errorf("%d: unexpected error: %v", i, err) continue } decoder := NewDecoder(ioutil.NopCloser(buf), testCase.Codec) event, obj, err := decoder.Decode() if err != nil { t.Errorf("%d: unexpected error: %v", i, err) continue } if !api.Semantic.DeepDerivative(testCase.Object, obj) { t.Errorf("%d: expected %#v, got %#v", i, testCase.Object, obj) } if event != testCase.Type { t.Errorf("%d: unexpected type: %#v", i, event) } } }
func TestCreateReplica(t *testing.T) { ns := api.NamespaceDefault body := runtime.EncodeOrDie(testapi.Codec(), &api.Pod{}) fakeHandler := util.FakeHandler{ StatusCode: 200, ResponseBody: string(body), } testServer := httptest.NewServer(&fakeHandler) defer testServer.Close() client := client.NewOrDie(&client.Config{Host: testServer.URL, Version: testapi.Version()}) podControl := RealPodControl{ kubeClient: client, } controllerSpec := api.ReplicationController{ ObjectMeta: api.ObjectMeta{ Name: "test", }, DesiredState: api.ReplicationControllerState{ PodTemplate: api.PodTemplate{ DesiredState: api.PodState{ Manifest: api.ContainerManifest{ Containers: []api.Container{ { Image: "foo/bar", }, }, }, }, Labels: map[string]string{ "name": "foo", "type": "production", "replicationController": "test", }, }, }, } podControl.createReplica(ns, controllerSpec) expectedPod := api.Pod{ ObjectMeta: api.ObjectMeta{ Labels: controllerSpec.DesiredState.PodTemplate.Labels, }, DesiredState: controllerSpec.DesiredState.PodTemplate.DesiredState, } fakeHandler.ValidateRequest(t, makeURL("/pods?namespace=default"), "POST", nil) actualPod, err := client.Codec.Decode([]byte(fakeHandler.RequestBody)) if err != nil { t.Errorf("Unexpected error: %#v", err) } if !reflect.DeepEqual(&expectedPod, actualPod) { t.Logf("Body: %s", fakeHandler.RequestBody) t.Errorf("Unexpected mismatch. Expected\n %#v,\n Got:\n %#v", &expectedPod, actualPod) } }
func TestCreateObjNilOutParam(t *testing.T) { obj := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}} fakeClient := NewFakeEtcdClient(t) helper := NewEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix()) err := helper.CreateObj("/some/key", obj, nil, 5) if err != nil { t.Errorf("Unexpected error %#v", err) } }
func TestSetObjNilOutParam(t *testing.T) { obj := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}} fakeClient := NewFakeEtcdClient(t) helper := EtcdHelper{fakeClient, testapi.Codec(), nil} err := helper.SetObj("/some/key", obj, nil, 3) if err != nil { t.Errorf("Unexpected error %#v", err) } }