func (c *RESTClient) request(verb string) *rest.Request { config := rest.ContentConfig{ ContentType: runtime.ContentTypeJSON, GroupVersion: ®istered.GroupOrDie(api.GroupName).GroupVersion, NegotiatedSerializer: c.NegotiatedSerializer, } groupName := api.GroupName if c.GroupName != "" { groupName = c.GroupName } ns := c.NegotiatedSerializer info, _ := runtime.SerializerInfoForMediaType(ns.SupportedMediaTypes(), runtime.ContentTypeJSON) internalVersion := unversioned.GroupVersion{ Group: registered.GroupOrDie(groupName).GroupVersion.Group, Version: runtime.APIVersionInternal, } internalVersion.Version = runtime.APIVersionInternal serializers := rest.Serializers{ Encoder: ns.EncoderForVersion(info.Serializer, registered.GroupOrDie(api.GroupName).GroupVersion), Decoder: ns.DecoderToVersion(info.Serializer, internalVersion), } if info.StreamSerializer != nil { serializers.StreamingSerializer = info.StreamSerializer.Serializer serializers.Framer = info.StreamSerializer.Framer } return rest.NewRequest(c, verb, &url.URL{Host: "localhost"}, "", config, serializers, nil, nil) }
// MetadataAccessor returns the MetadataAccessor for the API version to test against, // as set by the KUBE_TEST_API env var. func (g TestGroup) MetadataAccessor() meta.MetadataAccessor { interfaces, err := registered.GroupOrDie(g.externalGroupVersion.Group).InterfacesFor(g.externalGroupVersion) if err != nil { panic(err) } return interfaces.MetadataAccessor }
// Converter returns the api.Scheme for the API version to test against, as set by the // KUBE_TEST_API env var. func (g TestGroup) Converter() runtime.ObjectConvertor { interfaces, err := registered.GroupOrDie(g.externalGroupVersion.Group).InterfacesFor(g.externalGroupVersion) if err != nil { panic(err) } return interfaces.ObjectConvertor }
func validate(testParam TestParam, t *testing.T, body []byte, fakeHandler *utiltesting.FakeHandler) { switch { case testParam.expectingError && testParam.actualError == nil: t.Errorf("Expected error") case !testParam.expectingError && testParam.actualError != nil: t.Error(testParam.actualError) } if !testParam.expCreated { if testParam.actualCreated { t.Errorf("Expected object not to be created") } } statusOut, err := runtime.Decode(testapi.Default.Codec(), body) if testParam.testBody { if testParam.testBodyErrorIsNotNil { if err == nil { t.Errorf("Expected Error") } } } if testParam.expStatus != nil { if !reflect.DeepEqual(testParam.expStatus, statusOut) { t.Errorf("Unexpected mis-match. Expected %#v. Saw %#v", testParam.expStatus, statusOut) } } fakeHandler.ValidateRequest(t, "/"+registered.GroupOrDie(api.GroupName).GroupVersion.String()+"/test", "GET", nil) }
func restClient(testServer *httptest.Server) (*RESTClient, error) { c, err := RESTClientFor(&Config{ Host: testServer.URL, ContentConfig: ContentConfig{ GroupVersion: ®istered.GroupOrDie(api.GroupName).GroupVersion, NegotiatedSerializer: testapi.Default.NegotiatedSerializer(), }, Username: "******", Password: "******", }) return c, err }
func TestDoRequestNewWayObj(t *testing.T) { reqObj := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}} reqBodyExpected, _ := runtime.Encode(testapi.Default.Codec(), reqObj) expectedObj := &api.Service{Spec: api.ServiceSpec{Ports: []api.ServicePort{{ Protocol: "TCP", Port: 12345, TargetPort: intstr.FromInt(12345), }}}} expectedBody, _ := runtime.Encode(testapi.Default.Codec(), expectedObj) fakeHandler := utiltesting.FakeHandler{ StatusCode: 200, ResponseBody: string(expectedBody), T: t, } testServer := httptest.NewServer(&fakeHandler) defer testServer.Close() c := testRESTClient(t, testServer) obj, err := c.Verb("POST"). Suffix("baz"). Name("bar"). Resource("foo"). LabelsSelectorParam(labels.Set{"name": "foo"}.AsSelector()). Timeout(time.Second). Body(reqObj). Do().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) } tmpStr := string(reqBodyExpected) requestURL := testapi.Default.ResourcePath("foo", "", "bar/baz") requestURL += "?" + metav1.LabelSelectorQueryParam(registered.GroupOrDie(api.GroupName).GroupVersion.String()) + "=name%3Dfoo&timeout=1s" fakeHandler.ValidateRequest(t, requestURL, "POST", &tmpStr) }
func TestValidatesHostParameter(t *testing.T) { testCases := []struct { Host string APIPath string URL string Err bool }{ {"127.0.0.1", "", "http://127.0.0.1/" + registered.GroupOrDie(api.GroupName).GroupVersion.Version, false}, {"127.0.0.1:8080", "", "http://127.0.0.1:8080/" + registered.GroupOrDie(api.GroupName).GroupVersion.Version, false}, {"foo.bar.com", "", "http://foo.bar.com/" + registered.GroupOrDie(api.GroupName).GroupVersion.Version, false}, {"http://host/prefix", "", "http://host/prefix/" + registered.GroupOrDie(api.GroupName).GroupVersion.Version, false}, {"http://host", "", "http://host/" + registered.GroupOrDie(api.GroupName).GroupVersion.Version, false}, {"http://host", "/", "http://host/" + registered.GroupOrDie(api.GroupName).GroupVersion.Version, false}, {"http://host", "/other", "http://host/other/" + registered.GroupOrDie(api.GroupName).GroupVersion.Version, false}, {"host/server", "", "", true}, } for i, testCase := range testCases { u, versionedAPIPath, err := DefaultServerURL(testCase.Host, testCase.APIPath, registered.GroupOrDie(api.GroupName).GroupVersion, false) switch { case err == nil && testCase.Err: t.Errorf("expected error but was nil") continue case err != nil && !testCase.Err: t.Errorf("unexpected error %v", err) continue case err != nil: continue } u.Path = path.Join(u.Path, versionedAPIPath) if e, a := testCase.URL, u.String(); e != a { t.Errorf("%d: expected host %s, got %s", i, e, a) continue } } }
func TestRequestWithErrorWontChange(t *testing.T) { original := Request{ err: errors.New("test"), content: ContentConfig{GroupVersion: ®istered.GroupOrDie(api.GroupName).GroupVersion}, } r := original changed := r.Param("foo", "bar"). LabelsSelectorParam(labels.Set{"a": "b"}.AsSelector()). UintParam("uint", 1). AbsPath("/abs"). Prefix("test"). Suffix("testing"). Namespace("new"). Resource("foos"). Name("bars"). Body("foo"). Timeout(time.Millisecond) if changed != &r { t.Errorf("returned request should point to the same object") } if !reflect.DeepEqual(changed, &original) { t.Errorf("expected %#v, got %#v", &original, changed) } }
func init() { if apiMediaType := os.Getenv("KUBE_TEST_API_TYPE"); len(apiMediaType) > 0 { var ok bool mediaType, _, err := mime.ParseMediaType(apiMediaType) if err != nil { panic(err) } serializer, ok = runtime.SerializerInfoForMediaType(api.Codecs.SupportedMediaTypes(), mediaType) if !ok { panic(fmt.Sprintf("no serializer for %s", apiMediaType)) } } if storageMediaType := StorageMediaType(); len(storageMediaType) > 0 { var ok bool mediaType, _, err := mime.ParseMediaType(storageMediaType) if err != nil { panic(err) } storageSerializer, ok = runtime.SerializerInfoForMediaType(api.Codecs.SupportedMediaTypes(), mediaType) if !ok { panic(fmt.Sprintf("no serializer for %s", storageMediaType)) } } kubeTestAPI := os.Getenv("KUBE_TEST_API") if len(kubeTestAPI) != 0 { // priority is "first in list preferred", so this has to run in reverse order testGroupVersions := strings.Split(kubeTestAPI, ",") for i := len(testGroupVersions) - 1; i >= 0; i-- { gvString := testGroupVersions[i] groupVersion, err := schema.ParseGroupVersion(gvString) if err != nil { panic(fmt.Sprintf("Error parsing groupversion %v: %v", gvString, err)) } internalGroupVersion := schema.GroupVersion{Group: groupVersion.Group, Version: runtime.APIVersionInternal} Groups[groupVersion.Group] = TestGroup{ externalGroupVersion: groupVersion, internalGroupVersion: internalGroupVersion, internalTypes: api.Scheme.KnownTypes(internalGroupVersion), externalTypes: api.Scheme.KnownTypes(groupVersion), } } } if _, ok := Groups[api.GroupName]; !ok { externalGroupVersion := schema.GroupVersion{Group: api.GroupName, Version: registered.GroupOrDie(api.GroupName).GroupVersion.Version} Groups[api.GroupName] = TestGroup{ externalGroupVersion: externalGroupVersion, internalGroupVersion: api.SchemeGroupVersion, internalTypes: api.Scheme.KnownTypes(api.SchemeGroupVersion), externalTypes: api.Scheme.KnownTypes(externalGroupVersion), } } if _, ok := Groups[extensions.GroupName]; !ok { externalGroupVersion := schema.GroupVersion{Group: extensions.GroupName, Version: registered.GroupOrDie(extensions.GroupName).GroupVersion.Version} Groups[extensions.GroupName] = TestGroup{ externalGroupVersion: externalGroupVersion, internalGroupVersion: extensions.SchemeGroupVersion, internalTypes: api.Scheme.KnownTypes(extensions.SchemeGroupVersion), externalTypes: api.Scheme.KnownTypes(externalGroupVersion), } } if _, ok := Groups[autoscaling.GroupName]; !ok { internalTypes := make(map[string]reflect.Type) for k, t := range api.Scheme.KnownTypes(extensions.SchemeGroupVersion) { if k == "Scale" { continue } internalTypes[k] = t } externalGroupVersion := schema.GroupVersion{Group: autoscaling.GroupName, Version: registered.GroupOrDie(autoscaling.GroupName).GroupVersion.Version} Groups[autoscaling.GroupName] = TestGroup{ externalGroupVersion: externalGroupVersion, internalGroupVersion: extensions.SchemeGroupVersion, internalTypes: internalTypes, externalTypes: api.Scheme.KnownTypes(externalGroupVersion), } } if _, ok := Groups[autoscaling.GroupName+"IntraGroup"]; !ok { internalTypes := make(map[string]reflect.Type) for k, t := range api.Scheme.KnownTypes(extensions.SchemeGroupVersion) { if k == "Scale" { internalTypes[k] = t break } } externalGroupVersion := schema.GroupVersion{Group: autoscaling.GroupName, Version: registered.GroupOrDie(autoscaling.GroupName).GroupVersion.Version} Groups[autoscaling.GroupName] = TestGroup{ externalGroupVersion: externalGroupVersion, internalGroupVersion: autoscaling.SchemeGroupVersion, internalTypes: internalTypes, externalTypes: api.Scheme.KnownTypes(externalGroupVersion), } } if _, ok := Groups[batch.GroupName]; !ok { externalGroupVersion := schema.GroupVersion{Group: batch.GroupName, Version: registered.GroupOrDie(batch.GroupName).GroupVersion.Version} Groups[batch.GroupName] = TestGroup{ externalGroupVersion: externalGroupVersion, internalGroupVersion: batch.SchemeGroupVersion, internalTypes: api.Scheme.KnownTypes(batch.SchemeGroupVersion), externalTypes: api.Scheme.KnownTypes(externalGroupVersion), } } if _, ok := Groups[apps.GroupName]; !ok { externalGroupVersion := schema.GroupVersion{Group: apps.GroupName, Version: registered.GroupOrDie(apps.GroupName).GroupVersion.Version} Groups[apps.GroupName] = TestGroup{ externalGroupVersion: externalGroupVersion, internalGroupVersion: extensions.SchemeGroupVersion, internalTypes: api.Scheme.KnownTypes(extensions.SchemeGroupVersion), externalTypes: api.Scheme.KnownTypes(externalGroupVersion), } } if _, ok := Groups[policy.GroupName]; !ok { externalGroupVersion := schema.GroupVersion{Group: policy.GroupName, Version: registered.GroupOrDie(policy.GroupName).GroupVersion.Version} Groups[policy.GroupName] = TestGroup{ externalGroupVersion: externalGroupVersion, internalGroupVersion: policy.SchemeGroupVersion, internalTypes: api.Scheme.KnownTypes(policy.SchemeGroupVersion), externalTypes: api.Scheme.KnownTypes(externalGroupVersion), } } if _, ok := Groups[federation.GroupName]; !ok { externalGroupVersion := schema.GroupVersion{Group: federation.GroupName, Version: registered.GroupOrDie(federation.GroupName).GroupVersion.Version} Groups[federation.GroupName] = TestGroup{ externalGroupVersion: externalGroupVersion, internalGroupVersion: federation.SchemeGroupVersion, internalTypes: api.Scheme.KnownTypes(federation.SchemeGroupVersion), externalTypes: api.Scheme.KnownTypes(externalGroupVersion), } } if _, ok := Groups[rbac.GroupName]; !ok { externalGroupVersion := schema.GroupVersion{Group: rbac.GroupName, Version: registered.GroupOrDie(rbac.GroupName).GroupVersion.Version} Groups[rbac.GroupName] = TestGroup{ externalGroupVersion: externalGroupVersion, internalGroupVersion: rbac.SchemeGroupVersion, internalTypes: api.Scheme.KnownTypes(rbac.SchemeGroupVersion), externalTypes: api.Scheme.KnownTypes(externalGroupVersion), } } if _, ok := Groups[storage.GroupName]; !ok { externalGroupVersion := schema.GroupVersion{Group: storage.GroupName, Version: registered.GroupOrDie(storage.GroupName).GroupVersion.Version} Groups[storage.GroupName] = TestGroup{ externalGroupVersion: externalGroupVersion, internalGroupVersion: storage.SchemeGroupVersion, internalTypes: api.Scheme.KnownTypes(storage.SchemeGroupVersion), externalTypes: api.Scheme.KnownTypes(externalGroupVersion), } } if _, ok := Groups[certificates.GroupName]; !ok { externalGroupVersion := schema.GroupVersion{Group: certificates.GroupName, Version: registered.GroupOrDie(certificates.GroupName).GroupVersion.Version} Groups[certificates.GroupName] = TestGroup{ externalGroupVersion: externalGroupVersion, internalGroupVersion: certificates.SchemeGroupVersion, internalTypes: api.Scheme.KnownTypes(certificates.SchemeGroupVersion), externalTypes: api.Scheme.KnownTypes(externalGroupVersion), } } if _, ok := Groups[imagepolicy.GroupName]; !ok { externalGroupVersion := schema.GroupVersion{Group: imagepolicy.GroupName, Version: registered.GroupOrDie(imagepolicy.GroupName).GroupVersion.Version} Groups[imagepolicy.GroupName] = TestGroup{ externalGroupVersion: externalGroupVersion, internalGroupVersion: imagepolicy.SchemeGroupVersion, internalTypes: api.Scheme.KnownTypes(imagepolicy.SchemeGroupVersion), externalTypes: api.Scheme.KnownTypes(externalGroupVersion), } } if _, ok := Groups[authorization.GroupName]; !ok { externalGroupVersion := schema.GroupVersion{Group: authorization.GroupName, Version: registered.GroupOrDie(authorization.GroupName).GroupVersion.Version} Groups[authorization.GroupName] = TestGroup{ externalGroupVersion: externalGroupVersion, internalGroupVersion: authorization.SchemeGroupVersion, internalTypes: api.Scheme.KnownTypes(authorization.SchemeGroupVersion), externalTypes: api.Scheme.KnownTypes(externalGroupVersion), } } if _, ok := Groups[kubeadm.GroupName]; !ok { externalGroupVersion := schema.GroupVersion{Group: kubeadm.GroupName, Version: registered.GroupOrDie(kubeadm.GroupName).GroupVersion.Version} Groups[kubeadm.GroupName] = TestGroup{ externalGroupVersion: externalGroupVersion, internalGroupVersion: kubeadm.SchemeGroupVersion, internalTypes: api.Scheme.KnownTypes(kubeadm.SchemeGroupVersion), externalTypes: api.Scheme.KnownTypes(externalGroupVersion), } } Default = Groups[api.GroupName] Autoscaling = Groups[autoscaling.GroupName] Batch = Groups[batch.GroupName] Apps = Groups[apps.GroupName] Policy = Groups[policy.GroupName] Certificates = Groups[certificates.GroupName] Extensions = Groups[extensions.GroupName] Federation = Groups[federation.GroupName] Rbac = Groups[rbac.GroupName] Storage = Groups[storage.GroupName] ImagePolicy = Groups[imagepolicy.GroupName] Authorization = Groups[authorization.GroupName] }
func TestNegotiateVersion(t *testing.T) { tests := []struct { name string version *uapi.GroupVersion expectedVersion *uapi.GroupVersion serverVersions []string clientVersions []uapi.GroupVersion config *rest.Config expectErr func(err error) bool sendErr error statusCode int }{ { name: "server supports client default", version: &uapi.GroupVersion{Version: "version1"}, config: &rest.Config{}, serverVersions: []string{"version1", registered.GroupOrDie(api.GroupName).GroupVersion.String()}, clientVersions: []uapi.GroupVersion{{Version: "version1"}, registered.GroupOrDie(api.GroupName).GroupVersion}, expectedVersion: &uapi.GroupVersion{Version: "version1"}, statusCode: http.StatusOK, }, { name: "server falls back to client supported", version: ®istered.GroupOrDie(api.GroupName).GroupVersion, config: &rest.Config{}, serverVersions: []string{"version1"}, clientVersions: []uapi.GroupVersion{{Version: "version1"}, registered.GroupOrDie(api.GroupName).GroupVersion}, expectedVersion: &uapi.GroupVersion{Version: "version1"}, statusCode: http.StatusOK, }, { name: "explicit version supported", config: &rest.Config{ContentConfig: rest.ContentConfig{GroupVersion: ®istered.GroupOrDie(api.GroupName).GroupVersion}}, serverVersions: []string{"/version1", registered.GroupOrDie(api.GroupName).GroupVersion.String()}, clientVersions: []uapi.GroupVersion{{Version: "version1"}, registered.GroupOrDie(api.GroupName).GroupVersion}, expectedVersion: ®istered.GroupOrDie(api.GroupName).GroupVersion, statusCode: http.StatusOK, }, { name: "explicit version not supported", config: &rest.Config{ContentConfig: rest.ContentConfig{GroupVersion: ®istered.GroupOrDie(api.GroupName).GroupVersion}}, serverVersions: []string{"version1"}, clientVersions: []uapi.GroupVersion{{Version: "version1"}, registered.GroupOrDie(api.GroupName).GroupVersion}, expectErr: func(err error) bool { return strings.Contains(err.Error(), `server does not support API version "v1"`) }, statusCode: http.StatusOK, }, { name: "connection refused error", config: &rest.Config{ContentConfig: rest.ContentConfig{GroupVersion: ®istered.GroupOrDie(api.GroupName).GroupVersion}}, serverVersions: []string{"version1"}, clientVersions: []uapi.GroupVersion{{Version: "version1"}, registered.GroupOrDie(api.GroupName).GroupVersion}, sendErr: errors.New("connection refused"), expectErr: func(err error) bool { return strings.Contains(err.Error(), "connection refused") }, statusCode: http.StatusOK, }, { name: "discovery fails due to 403 Forbidden errors and thus serverVersions is empty, use default GroupVersion", config: &rest.Config{ContentConfig: rest.ContentConfig{GroupVersion: ®istered.GroupOrDie(api.GroupName).GroupVersion}}, clientVersions: []uapi.GroupVersion{{Version: "version1"}, registered.GroupOrDie(api.GroupName).GroupVersion}, expectedVersion: ®istered.GroupOrDie(api.GroupName).GroupVersion, statusCode: http.StatusForbidden, }, { name: "discovery fails due to 404 Not Found errors and thus serverVersions is empty, use requested GroupVersion", version: &uapi.GroupVersion{Version: "version1"}, config: &rest.Config{ContentConfig: rest.ContentConfig{GroupVersion: ®istered.GroupOrDie(api.GroupName).GroupVersion}}, clientVersions: []uapi.GroupVersion{{Version: "version1"}, registered.GroupOrDie(api.GroupName).GroupVersion}, expectedVersion: &uapi.GroupVersion{Version: "version1"}, statusCode: http.StatusNotFound, }, { name: "discovery fails due to 403 Forbidden errors and thus serverVersions is empty, no fallback GroupVersion", config: &rest.Config{}, clientVersions: []uapi.GroupVersion{{Version: "version1"}, registered.GroupOrDie(api.GroupName).GroupVersion}, expectErr: func(err error) bool { return strings.Contains(err.Error(), "failed to negotiate an api version;") }, statusCode: http.StatusForbidden, }, } for _, test := range tests { fakeClient := &fake.RESTClient{ NegotiatedSerializer: testapi.Default.NegotiatedSerializer(), Resp: &http.Response{ StatusCode: test.statusCode, Body: objBody(&uapi.APIVersions{Versions: test.serverVersions}), }, Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { if test.sendErr != nil { return nil, test.sendErr } header := http.Header{} header.Set("Content-Type", runtime.ContentTypeJSON) return &http.Response{StatusCode: test.statusCode, Header: header, Body: objBody(&uapi.APIVersions{Versions: test.serverVersions})}, nil }), } c := discovery.NewDiscoveryClientForConfigOrDie(test.config) c.RESTClient().(*rest.RESTClient).Client = fakeClient.Client response, err := discovery.NegotiateVersion(c, test.config, test.version, test.clientVersions) if err == nil && test.expectErr != nil { t.Errorf("expected error, got nil for [%s].", test.name) } if err != nil { if test.expectErr == nil || !test.expectErr(err) { t.Errorf("unexpected error for [%s]: %v.", test.name, err) } continue } if *response != *test.expectedVersion { t.Errorf("%s: expected version %s, got %s.", test.name, test.expectedVersion, response) } } }
func TestRESTClientRequires(t *testing.T) { if _, err := RESTClientFor(&Config{Host: "127.0.0.1", ContentConfig: ContentConfig{NegotiatedSerializer: testapi.Default.NegotiatedSerializer()}}); err == nil { t.Errorf("unexpected non-error") } if _, err := RESTClientFor(&Config{Host: "127.0.0.1", ContentConfig: ContentConfig{GroupVersion: ®istered.GroupOrDie(api.GroupName).GroupVersion}}); err == nil { t.Errorf("unexpected non-error") } if _, err := RESTClientFor(&Config{Host: "127.0.0.1", ContentConfig: ContentConfig{GroupVersion: ®istered.GroupOrDie(api.GroupName).GroupVersion, NegotiatedSerializer: testapi.Default.NegotiatedSerializer()}}); err != nil { t.Errorf("unexpected error: %v", err) } }
func defaultContentConfig() ContentConfig { return ContentConfig{ GroupVersion: ®istered.GroupOrDie(api.GroupName).GroupVersion, NegotiatedSerializer: testapi.Default.NegotiatedSerializer(), } }