func TestResourceNames(t *testing.T) { pods, svc := testData() b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClientWith("", t, map[string]string{ "/namespaces/test/pods/foo": runtime.EncodeOrDie(testapi.Default.Codec(), &pods.Items[0]), "/namespaces/test/services/baz": runtime.EncodeOrDie(testapi.Default.Codec(), &svc.Items[0]), }), testapi.Default.Codec()). NamespaceParam("test") test := &testVisitor{} if b.Do().Err() == nil { t.Errorf("unexpected non-error") } b.ResourceNames("pods", "foo", "services/baz") err := b.Do().Visit(test.Handle) if err != nil || len(test.Infos) != 2 { t.Fatalf("unexpected response: %v %#v", err, test.Infos) } if !reflect.DeepEqual(&pods.Items[0], test.Objects()[0]) { t.Errorf("unexpected object: \n%#v, expected: \n%#v", test.Objects()[0], &pods.Items[0]) } if !reflect.DeepEqual(&svc.Items[0], test.Objects()[1]) { t.Errorf("unexpected object: \n%#v, expected: \n%#v", test.Objects()[1], &svc.Items[0]) } }
func TestListObjectWithDifferentVersions(t *testing.T) { pods, svc := testData() labelKey := metav1.LabelSelectorQueryParam(api.Registry.GroupOrDie(api.GroupName).GroupVersion.String()) obj, err := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClientWith("", t, map[string]string{ "/namespaces/test/pods?" + labelKey + "=a%3Db": runtime.EncodeOrDie(testapi.Default.Codec(), pods), "/namespaces/test/services?" + labelKey + "=a%3Db": runtime.EncodeOrDie(testapi.Default.Codec(), svc), }), testapi.Default.Codec()). SelectorParam("a=b"). NamespaceParam("test"). ResourceTypeOrNameArgs(true, "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 TestLatest(t *testing.T) { r, _, _ := streamTestData() newPod := &api.Pod{ ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "test", ResourceVersion: "13"}, } newPod2 := &api.Pod{ ObjectMeta: metav1.ObjectMeta{Name: "bar", Namespace: "test", ResourceVersion: "14"}, } newSvc := &api.Service{ ObjectMeta: metav1.ObjectMeta{Name: "baz", Namespace: "test", ResourceVersion: "15"}, } b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClientWith("", t, map[string]string{ "/namespaces/test/pods/foo": runtime.EncodeOrDie(testapi.Default.Codec(), newPod), "/namespaces/test/pods/bar": runtime.EncodeOrDie(testapi.Default.Codec(), newPod2), "/namespaces/test/services/baz": runtime.EncodeOrDie(testapi.Default.Codec(), newSvc), }), testapi.Default.Codec()). NamespaceParam("other").Stream(r, "STDIN").Flatten().Latest() test := &testVisitor{} singleItemImplied := false err := b.Do().IntoSingleItemImplied(&singleItemImplied).Visit(test.Handle) if err != nil || singleItemImplied || len(test.Infos) != 3 { t.Fatalf("unexpected response: %v %t %#v", err, singleItemImplied, test.Infos) } if !api.Semantic.DeepDerivative([]runtime.Object{newPod, newPod2, newSvc}, test.Objects()) { t.Errorf("unexpected visited objects: %#v", test.Objects()) } }
func TestSelector(t *testing.T) { pods, svc := testData() labelKey := metav1.LabelSelectorQueryParam(api.Registry.GroupOrDie(api.GroupName).GroupVersion.String()) b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClientWith("", t, map[string]string{ "/namespaces/test/pods?" + labelKey + "=a%3Db": runtime.EncodeOrDie(testapi.Default.Codec(), pods), "/namespaces/test/services?" + labelKey + "=a%3Db": runtime.EncodeOrDie(testapi.Default.Codec(), svc), }), testapi.Default.Codec()). SelectorParam("a=b"). NamespaceParam("test"). Flatten() test := &testVisitor{} singleItemImplied := false if b.Do().Err() == nil { t.Errorf("unexpected non-error") } b.ResourceTypeOrNameArgs(true, "pods,service") err := b.Do().IntoSingleItemImplied(&singleItemImplied).Visit(test.Handle) if err != nil || singleItemImplied || len(test.Infos) != 3 { t.Fatalf("unexpected response: %v %t %#v", err, singleItemImplied, test.Infos) } if !api.Semantic.DeepDerivative([]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 TestURLBuilder(t *testing.T) { s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { w.WriteHeader(http.StatusOK) w.Write([]byte(runtime.EncodeOrDie(testapi.Default.Codec(), &api.Pod{ObjectMeta: metav1.ObjectMeta{Namespace: "foo", Name: "test"}}))) w.Write([]byte(runtime.EncodeOrDie(testapi.Default.Codec(), &api.Pod{ObjectMeta: metav1.ObjectMeta{Namespace: "foo", Name: "test1"}}))) })) defer s.Close() b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClient(), testapi.Default.Codec()). FilenameParam(false, &FilenameOptions{Recursive: false, Filenames: []string{s.URL}}). NamespaceParam("foo") test := &testVisitor{} err := b.Do().Visit(test.Handle) if err != nil || len(test.Infos) != 2 { t.Fatalf("unexpected response: %v %#v", err, test.Infos) } info := test.Infos[0] if info.Name != "test" || info.Namespace != "foo" || info.Object == nil { t.Errorf("unexpected info: %#v", info) } info = test.Infos[1] if info.Name != "test1" || info.Namespace != "foo" || info.Object == nil { t.Errorf("unexpected info: %#v", info) } }
func TestMultipleResourceByTheSameName(t *testing.T) { pods, svcs := testData() b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClientWith("", t, map[string]string{ "/namespaces/test/pods/foo": runtime.EncodeOrDie(testapi.Default.Codec(), &pods.Items[0]), "/namespaces/test/pods/baz": runtime.EncodeOrDie(testapi.Default.Codec(), &pods.Items[1]), "/namespaces/test/services/foo": runtime.EncodeOrDie(testapi.Default.Codec(), &svcs.Items[0]), "/namespaces/test/services/baz": runtime.EncodeOrDie(testapi.Default.Codec(), &svcs.Items[0]), }), testapi.Default.Codec()). NamespaceParam("test") test := &testVisitor{} singleItemImplied := false if b.Do().Err() == nil { t.Errorf("unexpected non-error") } b.ResourceTypeOrNameArgs(true, "pods,services", "foo", "baz") err := b.Do().IntoSingleItemImplied(&singleItemImplied).Visit(test.Handle) if err != nil || singleItemImplied || len(test.Infos) != 4 { t.Fatalf("unexpected response: %v %t %#v", err, singleItemImplied, test.Infos) } if !api.Semantic.DeepDerivative([]runtime.Object{&pods.Items[0], &pods.Items[1], &svcs.Items[0], &svcs.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 streamTestData() (io.Reader, *api.PodList, *api.ServiceList) { pods, svc := testData() r, w := io.Pipe() go func() { defer w.Close() w.Write([]byte(runtime.EncodeOrDie(testapi.Default.Codec(), pods))) w.Write([]byte(runtime.EncodeOrDie(testapi.Default.Codec(), svc))) }() return r, pods, svc }
func TestNodeBuilder(t *testing.T) { node := &api.Node{ ObjectMeta: metav1.ObjectMeta{Name: "node1", Namespace: "should-not-have", ResourceVersion: "10"}, Spec: api.NodeSpec{}, Status: api.NodeStatus{ Capacity: api.ResourceList{ api.ResourceCPU: resource.MustParse("1000m"), api.ResourceMemory: resource.MustParse("1Mi"), }, }, } r, w := io.Pipe() go func() { defer w.Close() w.Write([]byte(runtime.EncodeOrDie(testapi.Default.Codec(), node))) }() b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClient(), testapi.Default.Codec()). NamespaceParam("test").Stream(r, "STDIN") test := &testVisitor{} err := b.Do().Visit(test.Handle) if err != nil || len(test.Infos) != 1 { t.Fatalf("unexpected response: %v %#v", err, test.Infos) } info := test.Infos[0] if info.Name != "node1" || info.Namespace != "" || info.Object == nil { t.Errorf("unexpected info: %#v", info) } }
func TestListObject(t *testing.T) { pods, _ := testData() labelKey := metav1.LabelSelectorQueryParam(api.Registry.GroupOrDie(api.GroupName).GroupVersion.String()) b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClientWith("", t, map[string]string{ "/namespaces/test/pods?" + labelKey + "=a%3Db": runtime.EncodeOrDie(testapi.Default.Codec(), pods), }), testapi.Default.Codec()). SelectorParam("a=b"). NamespaceParam("test"). ResourceTypeOrNameArgs(true, "pods"). Flatten() obj, err := b.Do().Object() if err != nil { t.Fatalf("unexpected error: %v", err) } list, ok := obj.(*api.List) if !ok { t.Fatalf("unexpected object: %#v", obj) } if list.ResourceVersion != pods.ResourceVersion || len(list.Items) != 2 { t.Errorf("unexpected list: %#v", list) } mapping, err := b.Do().ResourceMapping() if err != nil { t.Fatalf("unexpected error: %v", err) } if mapping.Resource != "pods" { t.Errorf("unexpected resource mapping: %#v", mapping) } }
func TestResourceByNameAndEmptySelector(t *testing.T) { pods, _ := testData() b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClientWith("", t, map[string]string{ "/namespaces/test/pods/foo": runtime.EncodeOrDie(testapi.Default.Codec(), &pods.Items[0]), }), testapi.Default.Codec()). NamespaceParam("test"). SelectorParam(""). ResourceTypeOrNameArgs(true, "pods", "foo") singleItemImplied := false infos, err := b.Do().IntoSingleItemImplied(&singleItemImplied).Infos() if err != nil || !singleItemImplied || len(infos) != 1 { t.Fatalf("unexpected response: %v %t %#v", err, singleItemImplied, infos) } if !reflect.DeepEqual(&pods.Items[0], infos[0].Object) { t.Errorf("unexpected object: %#v", infos[0]) } mapping, err := b.Do().ResourceMapping() if err != nil { t.Fatalf("unexpected error: %v", err) } if mapping.Resource != "pods" { t.Errorf("unexpected resource mapping: %#v", mapping) } }
func verifyObjects(t *testing.T, expected, actual []runtime.Object) { var actualObj runtime.Object var err error if len(actual) != len(expected) { t.Fatal(actual) } for i, obj := range actual { switch obj.(type) { case runtime.Unstructured, *runtime.Unknown: actualObj, err = runtime.Decode( api.Codecs.UniversalDecoder(), []byte(runtime.EncodeOrDie(api.Codecs.LegacyCodec(), obj))) default: actualObj = obj err = nil } if err != nil { t.Fatal(err) } if !api.Semantic.DeepEqual(expected[i], actualObj) { t.Errorf("unexpected object: \n%#v\n%#v", expected[i], actualObj) } } }
func TestBind(t *testing.T) { table := []struct { binding *v1.Binding }{ {binding: &v1.Binding{ ObjectMeta: metav1.ObjectMeta{ Namespace: v1.NamespaceDefault, Name: "foo", }, Target: v1.ObjectReference{ Name: "foohost.kubernetes.mydomain.com", }, }}, } for _, item := range table { handler := utiltesting.FakeHandler{ StatusCode: 200, ResponseBody: "", T: t, } server := httptest.NewServer(&handler) defer server.Close() client := clientset.NewForConfigOrDie(&restclient.Config{Host: server.URL, ContentConfig: restclient.ContentConfig{GroupVersion: &api.Registry.GroupOrDie(v1.GroupName).GroupVersion}}) b := binder{client} if err := b.Bind(item.binding); err != nil { t.Errorf("Unexpected error: %v", err) continue } expectedBody := runtime.EncodeOrDie(testapi.Default.Codec(), item.binding) handler.ValidateRequest(t, testapi.Default.ResourcePath("bindings", v1.NamespaceDefault, ""), "POST", &expectedBody) } }
func streamTestObject(obj runtime.Object) io.Reader { r, w := io.Pipe() go func() { defer w.Close() w.Write([]byte(runtime.EncodeOrDie(testapi.Default.Codec(), obj))) }() return r }
func TestUpdatePetWithoutRetry(t *testing.T) { pcb1, pcb2 := makeTwoDifferntPCB() // invalid pet with empty pod invalidPcb := *pcb1 invalidPcb.pod = nil testCases := []struct { realPet *pcb expectedPet *pcb expectErr bool requests int }{ // case 0: error occurs, no need to update { realPet: pcb1, expectedPet: &invalidPcb, expectErr: true, requests: 0, }, // case 1: identical pet, no need to update { realPet: pcb1, expectedPet: pcb1, expectErr: false, requests: 0, }, // case 2: need to call update once { realPet: pcb1, expectedPet: pcb2, expectErr: false, requests: 1, }, } for k, tc := range testCases { body := runtime.EncodeOrDie(testapi.Default.Codec(), &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "empty_pod"}}) fakeHandler := utiltesting.FakeHandler{ StatusCode: 200, ResponseBody: string(body), } testServer := httptest.NewServer(&fakeHandler) client := clientset.NewForConfigOrDie(&restclient.Config{Host: testServer.URL, ContentConfig: restclient.ContentConfig{GroupVersion: &api.Registry.GroupOrDie(v1.GroupName).GroupVersion}}) petClient := newPetClient(client) err := petClient.Update(tc.realPet, tc.expectedPet) if tc.expectErr != (err != nil) { t.Errorf("case %d: expect error(%v), got err: %v", k, tc.expectErr, err) } fakeHandler.ValidateRequestCount(t, tc.requests) testServer.Close() } }
func TestResourceNamesWithoutResource(t *testing.T) { pods, svc := testData() b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClientWith("", t, map[string]string{ "/namespaces/test/pods/foo": runtime.EncodeOrDie(testapi.Default.Codec(), &pods.Items[0]), "/namespaces/test/services/baz": runtime.EncodeOrDie(testapi.Default.Codec(), &svc.Items[0]), }), testapi.Default.Codec()). NamespaceParam("test") test := &testVisitor{} if b.Do().Err() == nil { t.Errorf("unexpected non-error") } b.ResourceNames("", "foo", "services/baz") err := b.Do().Visit(test.Handle) if err == nil || !strings.Contains(err.Error(), "must be RESOURCE/NAME") { t.Fatalf("unexpected response: %v", err) } }
// Verifies that schemas that are not in the master tree of Kubernetes can be retrieved via Get. func TestGetUnknownSchemaObject(t *testing.T) { f, tf, _, _ := cmdtesting.NewAPIFactory() _, _, codec, _ := cmdtesting.NewTestFactory() tf.Printer = &testPrinter{} tf.Client = &fake.RESTClient{ NegotiatedSerializer: unstructuredSerializer, Resp: &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, cmdtesting.NewInternalType("", "", "foo"))}, } tf.Namespace = "test" tf.ClientConfig = &restclient.Config{ContentConfig: restclient.ContentConfig{GroupVersion: &api.Registry.GroupOrDie(api.GroupName).GroupVersion}} buf := bytes.NewBuffer([]byte{}) errBuf := bytes.NewBuffer([]byte{}) cmd := NewCmdGet(f, buf, errBuf) cmd.SetOutput(buf) cmd.Run(cmd, []string{"type", "foo"}) expected := []runtime.Object{cmdtesting.NewInternalType("", "", "foo")} actual := tf.Printer.(*testPrinter).Objects if len(actual) != len(expected) { t.Fatal(actual) } for i, obj := range actual { expectedJSON := runtime.EncodeOrDie(codec, expected[i]) expectedMap := map[string]interface{}{} if err := encjson.Unmarshal([]byte(expectedJSON), &expectedMap); err != nil { t.Fatal(err) } actualJSON := runtime.EncodeOrDie(api.Codecs.LegacyCodec(), obj) actualMap := map[string]interface{}{} if err := encjson.Unmarshal([]byte(actualJSON), &actualMap); err != nil { t.Fatal(err) } if !reflect.DeepEqual(expectedMap, actualMap) { t.Errorf("unexpected object: \n%#v\n%#v", expectedMap, actualMap) } } }
func TestRequestStream(t *testing.T) { testCases := []struct { Request *Request Err bool }{ { Request: &Request{err: errors.New("bail")}, Err: true, }, { Request: &Request{baseURL: &url.URL{}, pathPrefix: "%"}, Err: true, }, { Request: &Request{ client: clientFunc(func(req *http.Request) (*http.Response, error) { return nil, errors.New("err") }), baseURL: &url.URL{}, }, Err: true, }, { Request: &Request{ client: clientFunc(func(req *http.Request) (*http.Response, error) { return &http.Response{ StatusCode: http.StatusUnauthorized, Body: ioutil.NopCloser(bytes.NewReader([]byte(runtime.EncodeOrDie(testapi.Default.Codec(), &metav1.Status{ Status: metav1.StatusFailure, Reason: metav1.StatusReasonUnauthorized, })))), }, nil }), content: defaultContentConfig(), serializers: defaultSerializers(), baseURL: &url.URL{}, }, Err: true, }, } for i, testCase := range testCases { testCase.Request.backoffMgr = &NoBackoff{} body, err := testCase.Request.Stream() hasErr := err != nil if hasErr != testCase.Err { t.Errorf("%d: expected %t, got %t: %v", i, testCase.Err, hasErr, err) } if hasErr && body != nil { t.Errorf("%d: body should be nil when error is returned", i) } } }
func makeTestServer(t *testing.T, namespace string, endpointsResponse serverResponse) (*httptest.Server, *utiltesting.FakeHandler) { fakeEndpointsHandler := utiltesting.FakeHandler{ StatusCode: endpointsResponse.statusCode, ResponseBody: runtime.EncodeOrDie(testapi.Default.Codec(), endpointsResponse.obj.(runtime.Object)), } mux := http.NewServeMux() mux.Handle(testapi.Default.ResourcePath("endpoints", namespace, ""), &fakeEndpointsHandler) mux.Handle(testapi.Default.ResourcePath("endpoints/", namespace, ""), &fakeEndpointsHandler) mux.HandleFunc("/", func(res http.ResponseWriter, req *http.Request) { t.Errorf("unexpected request: %v", req.RequestURI) res.WriteHeader(http.StatusNotFound) }) return httptest.NewServer(mux), &fakeEndpointsHandler }
func TestReceiveMultipleErrors(t *testing.T) { pods, svc := testData() r, w := io.Pipe() go func() { defer w.Close() w.Write([]byte(`{}`)) w.Write([]byte(runtime.EncodeOrDie(testapi.Default.Codec(), &pods.Items[0]))) }() r2, w2 := io.Pipe() go func() { defer w2.Close() w2.Write([]byte(`{}`)) w2.Write([]byte(runtime.EncodeOrDie(testapi.Default.Codec(), &svc.Items[0]))) }() b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClient(), testapi.Default.Codec()). Stream(r, "1").Stream(r2, "2"). ContinueOnError() test := &testVisitor{} singleItemImplied := false err := b.Do().IntoSingleItemImplied(&singleItemImplied).Visit(test.Handle) if err == nil || singleItemImplied || len(test.Infos) != 2 { t.Fatalf("unexpected response: %v %t %#v", err, singleItemImplied, test.Infos) } errs, ok := err.(utilerrors.Aggregate) if !ok { t.Fatalf("unexpected error: %v", reflect.TypeOf(err)) } if len(errs.Errors()) != 2 { t.Errorf("unexpected errors %v", errs) } }
func TestSyncEndpointsItemsPreexistingLabelsChange(t *testing.T) { ns := "bar" testServer, endpointsHandler := makeTestServer(t, ns, serverResponse{http.StatusOK, &v1.Endpoints{ ObjectMeta: metav1.ObjectMeta{ Name: "foo", Namespace: ns, ResourceVersion: "1", Labels: map[string]string{ "foo": "bar", }, }, Subsets: []v1.EndpointSubset{{ Addresses: []v1.EndpointAddress{{IP: "6.7.8.9", NodeName: &emptyNodeName}}, Ports: []v1.EndpointPort{{Port: 1000}}, }}, }}) defer testServer.Close() client := clientset.NewForConfigOrDie(&restclient.Config{Host: testServer.URL, ContentConfig: restclient.ContentConfig{GroupVersion: &api.Registry.GroupOrDie(v1.GroupName).GroupVersion}}) endpoints := NewEndpointControllerFromClient(client, controller.NoResyncPeriodFunc) endpoints.podStoreSynced = alwaysReady addPods(endpoints.podStore.Indexer, ns, 1, 1, 0) serviceLabels := map[string]string{"baz": "blah"} endpoints.serviceStore.Indexer.Add(&v1.Service{ ObjectMeta: metav1.ObjectMeta{ Name: "foo", Namespace: ns, Labels: serviceLabels, }, Spec: v1.ServiceSpec{ Selector: map[string]string{"foo": "bar"}, Ports: []v1.ServicePort{{Port: 80, Protocol: "TCP", TargetPort: intstr.FromInt(8080)}}, }, }) endpoints.syncService(ns + "/foo") data := runtime.EncodeOrDie(testapi.Default.Codec(), &v1.Endpoints{ ObjectMeta: metav1.ObjectMeta{ Name: "foo", Namespace: ns, ResourceVersion: "1", Labels: serviceLabels, }, Subsets: []v1.EndpointSubset{{ Addresses: []v1.EndpointAddress{{IP: "1.2.3.4", NodeName: &emptyNodeName, TargetRef: &v1.ObjectReference{Kind: "Pod", Name: "pod0", Namespace: ns}}}, Ports: []v1.EndpointPort{{Port: 8080, Protocol: "TCP"}}, }}, }) endpointsHandler.ValidateRequest(t, testapi.Default.ResourcePath("endpoints", ns, "foo"), "PUT", &data) }
func TestSyncEndpointsItemsWithLabels(t *testing.T) { ns := "other" testServer, endpointsHandler := makeTestServer(t, ns, serverResponse{http.StatusOK, &v1.Endpoints{}}) defer testServer.Close() client := clientset.NewForConfigOrDie(&restclient.Config{Host: testServer.URL, ContentConfig: restclient.ContentConfig{GroupVersion: &api.Registry.GroupOrDie(v1.GroupName).GroupVersion}}) endpoints := NewEndpointControllerFromClient(client, controller.NoResyncPeriodFunc) endpoints.podStoreSynced = alwaysReady addPods(endpoints.podStore.Indexer, ns, 3, 2, 0) serviceLabels := map[string]string{"foo": "bar"} endpoints.serviceStore.Indexer.Add(&v1.Service{ ObjectMeta: metav1.ObjectMeta{ Name: "foo", Namespace: ns, Labels: serviceLabels, }, Spec: v1.ServiceSpec{ Selector: map[string]string{"foo": "bar"}, Ports: []v1.ServicePort{ {Name: "port0", Port: 80, Protocol: "TCP", TargetPort: intstr.FromInt(8080)}, {Name: "port1", Port: 88, Protocol: "TCP", TargetPort: intstr.FromInt(8088)}, }, }, }) endpoints.syncService(ns + "/foo") expectedSubsets := []v1.EndpointSubset{{ Addresses: []v1.EndpointAddress{ {IP: "1.2.3.4", NodeName: &emptyNodeName, TargetRef: &v1.ObjectReference{Kind: "Pod", Name: "pod0", Namespace: ns}}, {IP: "1.2.3.5", NodeName: &emptyNodeName, TargetRef: &v1.ObjectReference{Kind: "Pod", Name: "pod1", Namespace: ns}}, {IP: "1.2.3.6", NodeName: &emptyNodeName, TargetRef: &v1.ObjectReference{Kind: "Pod", Name: "pod2", Namespace: ns}}, }, Ports: []v1.EndpointPort{ {Name: "port0", Port: 8080, Protocol: "TCP"}, {Name: "port1", Port: 8088, Protocol: "TCP"}, }, }} data := runtime.EncodeOrDie(testapi.Default.Codec(), &v1.Endpoints{ ObjectMeta: metav1.ObjectMeta{ ResourceVersion: "", Labels: serviceLabels, }, Subsets: endptspkg.SortSubsets(expectedSubsets), }) // endpointsHandler should get 2 requests - one for "GET" and the next for "POST". endpointsHandler.ValidateRequestCount(t, 2) endpointsHandler.ValidateRequest(t, testapi.Default.ResourcePath("endpoints", ns, ""), "POST", &data) }
func main() { flag.Parse() if *kubeconfig == "" { log.Fatalf("Need to specify --kubeconfig") } cfg := read(*kubeconfig) secret := &api.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: *name, Namespace: *ns, }, Data: map[string][]byte{ "config": cfg, }, } fmt.Printf(runtime.EncodeOrDie(api.Codecs.LegacyCodec(api.Registry.EnabledVersions()...), secret)) }
func main() { flag.Parse() if *crt == "" || *key == "" { log.Fatalf("Need to specify -crt -key and -template") } nginxCrt := read(*crt) nginxKey := read(*key) secret := &api.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "nginxsecret", }, Data: map[string][]byte{ "nginx.crt": nginxCrt, "nginx.key": nginxKey, }, } fmt.Printf(runtime.EncodeOrDie(api.Codecs.LegacyCodec(api.Registry.EnabledVersions()...), secret)) }
func TestURLBuilderRequireNamespace(t *testing.T) { s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { w.WriteHeader(http.StatusOK) w.Write([]byte(runtime.EncodeOrDie(testapi.Default.Codec(), &api.Pod{ObjectMeta: metav1.ObjectMeta{Namespace: "foo", Name: "test"}}))) })) defer s.Close() b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClient(), testapi.Default.Codec()). FilenameParam(false, &FilenameOptions{Recursive: false, Filenames: []string{s.URL}}). NamespaceParam("test").RequireNamespace() test := &testVisitor{} singleItemImplied := false err := b.Do().IntoSingleItemImplied(&singleItemImplied).Visit(test.Handle) if err == nil || !singleItemImplied || len(test.Infos) != 0 { t.Fatalf("unexpected response: %v %t %#v", err, singleItemImplied, test.Infos) } }
func TestCreatePods(t *testing.T) { ns := v1.NamespaceDefault body := runtime.EncodeOrDie(testapi.Default.Codec(), &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "empty_pod"}}) fakeHandler := utiltesting.FakeHandler{ StatusCode: 200, ResponseBody: string(body), } testServer := httptest.NewServer(&fakeHandler) defer testServer.Close() clientset := clientset.NewForConfigOrDie(&restclient.Config{Host: testServer.URL, ContentConfig: restclient.ContentConfig{GroupVersion: &api.Registry.GroupOrDie(v1.GroupName).GroupVersion}}) podControl := RealPodControl{ KubeClient: clientset, Recorder: &record.FakeRecorder{}, } controllerSpec := newReplicationController(1) // Make sure createReplica sends a POST to the apiserver with a pod from the controllers pod template if err := podControl.CreatePods(ns, controllerSpec.Spec.Template, controllerSpec); err != nil { t.Fatalf("unexpected error: %v", err) } expectedPod := v1.Pod{ ObjectMeta: metav1.ObjectMeta{ Labels: controllerSpec.Spec.Template.Labels, GenerateName: fmt.Sprintf("%s-", controllerSpec.Name), }, Spec: controllerSpec.Spec.Template.Spec, } fakeHandler.ValidateRequest(t, testapi.Default.ResourcePath("pods", v1.NamespaceDefault, ""), "POST", nil) var actualPod = &v1.Pod{} err := json.Unmarshal([]byte(fakeHandler.RequestBody), actualPod) if err != nil { t.Fatalf("Unexpected error: %v", err) } if !api.Semantic.DeepDerivative(&expectedPod, actualPod) { t.Logf("Body: %s", fakeHandler.RequestBody) t.Errorf("Unexpected mismatch. Expected\n %#v,\n Got:\n %#v", &expectedPod, actualPod) } }
func TestDefaultErrorFunc(t *testing.T) { testPod := &v1.Pod{ ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar"}, Spec: apitesting.V1DeepEqualSafePodSpec(), } handler := utiltesting.FakeHandler{ StatusCode: 200, ResponseBody: runtime.EncodeOrDie(testapi.Default.Codec(), testPod), T: t, } mux := http.NewServeMux() // FakeHandler musn't be sent requests other than the one you want to test. mux.Handle(testapi.Default.ResourcePath("pods", "bar", "foo"), &handler) server := httptest.NewServer(mux) defer server.Close() factory := NewConfigFactory(clientset.NewForConfigOrDie(&restclient.Config{Host: server.URL, ContentConfig: restclient.ContentConfig{GroupVersion: &api.Registry.GroupOrDie(v1.GroupName).GroupVersion}}), v1.DefaultSchedulerName, v1.DefaultHardPodAffinitySymmetricWeight, v1.DefaultFailureDomains) queue := cache.NewFIFO(cache.MetaNamespaceKeyFunc) podBackoff := util.CreatePodBackoff(1*time.Millisecond, 1*time.Second) errFunc := factory.MakeDefaultErrorFunc(podBackoff, queue) errFunc(testPod, nil) for { // This is a terrible way to do this but I plan on replacing this // whole error handling system in the future. The test will time // out if something doesn't work. time.Sleep(10 * time.Millisecond) got, exists, _ := queue.Get(testPod) if !exists { continue } handler.ValidateRequest(t, testapi.Default.ResourcePath("pods", "bar", "foo"), "GET", nil) if e, a := testPod, got; !reflect.DeepEqual(e, a) { t.Errorf("Expected %v, got %v", e, a) } break } }
daemonsetLabelPrefix = "daemonset-" daemonsetNameLabel = daemonsetLabelPrefix + "name" daemonsetColorLabel = daemonsetLabelPrefix + "color" ) // This test must be run in serial because it assumes the Daemon Set pods will // always get scheduled. If we run other tests in parallel, this may not // happen. In the future, running in parallel may work if we have an eviction // model which lets the DS controller kick out other pods to make room. // See http://issues.k8s.io/21767 for more details var _ = framework.KubeDescribe("Daemon set [Serial]", func() { var f *framework.Framework AfterEach(func() { if daemonsets, err := f.ClientSet.Extensions().DaemonSets(f.Namespace.Name).List(v1.ListOptions{}); err == nil { framework.Logf("daemonset: %s", runtime.EncodeOrDie(api.Codecs.LegacyCodec(api.Registry.EnabledVersions()...), daemonsets)) } else { framework.Logf("unable to dump daemonsets: %v", err) } if pods, err := f.ClientSet.Core().Pods(f.Namespace.Name).List(v1.ListOptions{}); err == nil { framework.Logf("pods: %s", runtime.EncodeOrDie(api.Codecs.LegacyCodec(api.Registry.EnabledVersions()...), pods)) } else { framework.Logf("unable to dump pods: %v", err) } err := clearDaemonSetNodeLabels(f.ClientSet) Expect(err).NotTo(HaveOccurred()) }) f = framework.NewDefaultFramework("daemonsets") image := "gcr.io/google_containers/serve_hostname:v1.4"
func policyObjBody(obj runtime.Object) io.ReadCloser { return ioutil.NopCloser(bytes.NewReader([]byte(runtime.EncodeOrDie(testapi.Policy.Codec(), obj)))) }
func objBody(codec runtime.Codec, obj runtime.Object) io.ReadCloser { return ioutil.NopCloser(bytes.NewReader([]byte(runtime.EncodeOrDie(codec, obj)))) }
func TestWatchInterpretations(t *testing.T) { codec := testapi.Default.Codec() // Declare some pods to make the test cases compact. podFoo := &api.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo"}} podBar := &api.Pod{ObjectMeta: metav1.ObjectMeta{Name: "bar"}} podBaz := &api.Pod{ObjectMeta: metav1.ObjectMeta{Name: "baz"}} // All of these test cases will be run with the firstLetterIsB Filter. table := map[string]struct { actions []string // Run this test item for every action here. prevNodeValue string nodeValue string expectEmit bool expectType watch.EventType expectObject runtime.Object }{ "create": { actions: []string{"create", "get"}, nodeValue: runtime.EncodeOrDie(codec, podBar), expectEmit: true, expectType: watch.Added, expectObject: podBar, }, "create but filter blocks": { actions: []string{"create", "get"}, nodeValue: runtime.EncodeOrDie(codec, podFoo), expectEmit: false, }, "delete": { actions: []string{"delete"}, prevNodeValue: runtime.EncodeOrDie(codec, podBar), expectEmit: true, expectType: watch.Deleted, expectObject: podBar, }, "delete but filter blocks": { actions: []string{"delete"}, nodeValue: runtime.EncodeOrDie(codec, podFoo), expectEmit: false, }, "modify appears to create 1": { actions: []string{"set", "compareAndSwap"}, nodeValue: runtime.EncodeOrDie(codec, podBar), expectEmit: true, expectType: watch.Added, expectObject: podBar, }, "modify appears to create 2": { actions: []string{"set", "compareAndSwap"}, prevNodeValue: runtime.EncodeOrDie(codec, podFoo), nodeValue: runtime.EncodeOrDie(codec, podBar), expectEmit: true, expectType: watch.Added, expectObject: podBar, }, "modify appears to delete": { actions: []string{"set", "compareAndSwap"}, prevNodeValue: runtime.EncodeOrDie(codec, podBar), nodeValue: runtime.EncodeOrDie(codec, podFoo), expectEmit: true, expectType: watch.Deleted, expectObject: podBar, // Should return last state that passed the filter! }, "modify modifies": { actions: []string{"set", "compareAndSwap"}, prevNodeValue: runtime.EncodeOrDie(codec, podBar), nodeValue: runtime.EncodeOrDie(codec, podBaz), expectEmit: true, expectType: watch.Modified, expectObject: podBaz, }, "modify ignores": { actions: []string{"set", "compareAndSwap"}, nodeValue: runtime.EncodeOrDie(codec, podFoo), expectEmit: false, }, } firstLetterIsB := func(obj runtime.Object) bool { return obj.(*api.Pod).Name[0] == 'b' } for name, item := range table { for _, action := range item.actions { w := newEtcdWatcher(true, false, nil, firstLetterIsB, codec, versioner, nil, &fakeEtcdCache{}) emitCalled := false w.emit = func(event watch.Event) { emitCalled = true if !item.expectEmit { return } if e, a := item.expectType, event.Type; e != a { t.Errorf("'%v - %v': expected %v, got %v", name, action, e, a) } if e, a := item.expectObject, event.Object; !api.Semantic.DeepDerivative(e, a) { t.Errorf("'%v - %v': expected %v, got %v", name, action, e, a) } } var n, pn *etcd.Node if item.nodeValue != "" { n = &etcd.Node{Value: item.nodeValue} } if item.prevNodeValue != "" { pn = &etcd.Node{Value: item.prevNodeValue} } w.sendResult(&etcd.Response{ Action: action, Node: n, PrevNode: pn, }) if e, a := item.expectEmit, emitCalled; e != a { t.Errorf("'%v - %v': expected %v, got %v", name, action, e, a) } w.Stop() } } }