// Verifies that AddGroupVersions works as expected. func TestInstallAPIGroups(t *testing.T) { _, etcdserver, config, assert := setUp(t) defer etcdserver.Terminate(t) config.ProxyDialer = func(network, addr string) (net.Conn, error) { return nil, nil } config.ProxyTLSClientConfig = &tls.Config{} config.APIPrefix = "/apiPrefix" config.APIGroupPrefix = "/apiGroupPrefix" config.Serializer = api.Codecs s, err := New(&config) if err != nil { t.Fatalf("Error in bringing up the server: %v", err) } apiGroupMeta := registered.GroupOrDie(api.GroupName) extensionsGroupMeta := registered.GroupOrDie(extensions.GroupName) apiGroupsInfo := []APIGroupInfo{ { // legacy group version GroupMeta: *apiGroupMeta, VersionedResourcesStorageMap: map[string]map[string]rest.Storage{}, IsLegacyGroup: true, ParameterCodec: api.ParameterCodec, NegotiatedSerializer: api.Codecs, }, { // extensions group version GroupMeta: *extensionsGroupMeta, VersionedResourcesStorageMap: map[string]map[string]rest.Storage{}, OptionsExternalVersion: &apiGroupMeta.GroupVersion, ParameterCodec: api.ParameterCodec, NegotiatedSerializer: api.Codecs, }, } s.InstallAPIGroups(apiGroupsInfo) server := httptest.NewServer(s.HandlerContainer.ServeMux) defer server.Close() validPaths := []string{ // "/api" config.APIPrefix, // "/api/v1" config.APIPrefix + "/" + apiGroupMeta.GroupVersion.Version, // "/apis/extensions" config.APIGroupPrefix + "/" + extensionsGroupMeta.GroupVersion.Group, // "/apis/extensions/v1beta1" config.APIGroupPrefix + "/" + extensionsGroupMeta.GroupVersion.String(), } for _, path := range validPaths { _, err := http.Get(server.URL + path) if !assert.NoError(err) { t.Errorf("unexpected error: %v, for path: %s", err, path) } } }
func TestInterfacesFor(t *testing.T) { if _, err := registered.GroupOrDie(extensions.GroupName).InterfacesFor(extensions.SchemeGroupVersion); err == nil { t.Fatalf("unexpected non-error: %v", err) } for i, version := range registered.GroupOrDie(extensions.GroupName).GroupVersions { if vi, err := registered.GroupOrDie(extensions.GroupName).InterfacesFor(version); err != nil || vi == nil { t.Fatalf("%d: unexpected result: %v", i, err) } } }
// 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 TestCodec(t *testing.T) { daemonSet := extensions.DaemonSet{} // We do want to use package registered rather than testapi here, because we // want to test if the package install and package registered work as expected. data, err := runtime.Encode(api.Codecs.LegacyCodec(registered.GroupOrDie(extensions.GroupName).GroupVersion), &daemonSet) if err != nil { t.Fatalf("unexpected error: %v", err) } other := extensions.DaemonSet{} if err := json.Unmarshal(data, &other); err != nil { t.Fatalf("unexpected error: %v", err) } if other.APIVersion != registered.GroupOrDie(extensions.GroupName).GroupVersion.String() || other.Kind != "DaemonSet" { t.Errorf("unexpected unmarshalled object %#v", other) } }
// SavePodToFile will encode and save a pod to a given path & permissions func SavePodToFile(pod *api.Pod, filePath string, perm os.FileMode) error { if filePath == "" { return fmt.Errorf("file path not specified") } codec := api.Codecs.LegacyCodec(registered.GroupOrDie(api.GroupName).GroupVersion) data, err := runtime.Encode(codec, pod) if err != nil { return fmt.Errorf("failed encoding pod: %v", err) } return ioutil.WriteFile(filePath, data, perm) }
func TestRESTMapper(t *testing.T) { gv := v1beta1.SchemeGroupVersion daemonSetGVK := gv.WithKind("DaemonSet") if gvk, err := registered.GroupOrDie(extensions.GroupName).RESTMapper.KindFor(gv.WithResource("daemonsets")); err != nil || gvk != daemonSetGVK { t.Errorf("unexpected version mapping: %v %v", gvk, err) } if m, err := registered.GroupOrDie(extensions.GroupName).RESTMapper.RESTMapping(daemonSetGVK.GroupKind(), ""); err != nil || m.GroupVersionKind != daemonSetGVK || m.Resource != "daemonsets" { t.Errorf("unexpected version mapping: %#v %v", m, err) } for _, version := range registered.GroupOrDie(extensions.GroupName).GroupVersions { mapping, err := registered.GroupOrDie(extensions.GroupName).RESTMapper.RESTMapping(daemonSetGVK.GroupKind(), version.Version) if err != nil { t.Errorf("unexpected error: %v", err) } if mapping.Resource != "daemonsets" { t.Errorf("incorrect resource name: %#v", mapping) } if mapping.GroupVersionKind.GroupVersion() != version { t.Errorf("incorrect groupVersion: %v", mapping) } interfaces, _ := registered.GroupOrDie(extensions.GroupName).InterfacesFor(version) if mapping.ObjectConvertor != interfaces.ObjectConvertor { t.Errorf("unexpected: %#v, expected: %#v", mapping, interfaces) } rc := &extensions.DaemonSet{ObjectMeta: api.ObjectMeta{Name: "foo"}} name, err := mapping.MetadataAccessor.Name(rc) if err != nil { t.Errorf("unexpected error: %v", err) } if name != "foo" { t.Errorf("unable to retrieve object meta with: %v", mapping.MetadataAccessor) } } }
// LoadPodFromFile will read, decode, and return a Pod from a file. func LoadPodFromFile(filePath string) (*api.Pod, error) { if filePath == "" { return nil, fmt.Errorf("file path not specified") } podDef, err := ioutil.ReadFile(filePath) if err != nil { return nil, fmt.Errorf("failed to read file path %s: %+v", filePath, err) } if len(podDef) == 0 { return nil, fmt.Errorf("file was empty: %s", filePath) } pod := &api.Pod{} codec := api.Codecs.LegacyCodec(registered.GroupOrDie(api.GroupName).GroupVersion) if err := runtime.DecodeInto(codec, podDef, pod); err != nil { return nil, fmt.Errorf("failed decoding file: %v", err) } return pod, nil }
func TestSavePodToFile(t *testing.T) { pod := volume.NewPersistentVolumeRecyclerPodTemplate() // sets all default values on a pod for equality comparison after decoding from file codec := api.Codecs.LegacyCodec(registered.GroupOrDie(api.GroupName).GroupVersion) encoded, err := runtime.Encode(codec, pod) runtime.DecodeInto(codec, encoded, pod) tmpDir := utiltesting.MkTmpdirOrDie("kube-io-test") defer os.RemoveAll(tmpDir) path := fmt.Sprintf("/%s/kube-io-test-%s", tmpDir, uuid.New()) if err := io.SavePodToFile(pod, path, 777); err != nil { t.Fatalf("failed to save pod to file: %v", err) } podFromFile, err := io.LoadPodFromFile(path) if err != nil { t.Fatalf("failed to load pod from file: %v", err) } if !api.Semantic.DeepEqual(pod, podFromFile) { t.Errorf("\nexpected %#v\ngot %#v\n", pod, podFromFile) } }
func TestDiscoveryAtAPIS(t *testing.T) { master, etcdserver, _, assert := newLimitedMaster(t) defer etcdserver.Terminate(t) server := httptest.NewServer(master.HandlerContainer.ServeMux) resp, err := http.Get(server.URL + "/apis") if !assert.NoError(err) { t.Errorf("unexpected error: %v", err) } assert.Equal(http.StatusOK, resp.StatusCode) groupList := unversioned.APIGroupList{} assert.NoError(decodeResponse(resp, &groupList)) if err != nil { t.Fatalf("unexpected error: %v", err) } expectGroupNames := sets.NewString(autoscaling.GroupName, batch.GroupName, apps.GroupName, extensions.GroupName) expectVersions := map[string][]unversioned.GroupVersionForDiscovery{ autoscaling.GroupName: { { GroupVersion: testapi.Autoscaling.GroupVersion().String(), Version: testapi.Autoscaling.GroupVersion().Version, }, }, // batch is using its pkg/apis/batch/ types here since during installation // both versions get installed and testapi.go currently does not support // multi-versioned clients batch.GroupName: { { GroupVersion: batchapiv1.SchemeGroupVersion.String(), Version: batchapiv1.SchemeGroupVersion.Version, }, { GroupVersion: batchapiv2alpha1.SchemeGroupVersion.String(), Version: batchapiv2alpha1.SchemeGroupVersion.Version, }, }, apps.GroupName: { { GroupVersion: testapi.Apps.GroupVersion().String(), Version: testapi.Apps.GroupVersion().Version, }, }, extensions.GroupName: { { GroupVersion: testapi.Extensions.GroupVersion().String(), Version: testapi.Extensions.GroupVersion().Version, }, }, } expectPreferredVersion := map[string]unversioned.GroupVersionForDiscovery{ autoscaling.GroupName: { GroupVersion: registered.GroupOrDie(autoscaling.GroupName).GroupVersion.String(), Version: registered.GroupOrDie(autoscaling.GroupName).GroupVersion.Version, }, batch.GroupName: { GroupVersion: registered.GroupOrDie(batch.GroupName).GroupVersion.String(), Version: registered.GroupOrDie(batch.GroupName).GroupVersion.Version, }, apps.GroupName: { GroupVersion: registered.GroupOrDie(apps.GroupName).GroupVersion.String(), Version: registered.GroupOrDie(apps.GroupName).GroupVersion.Version, }, extensions.GroupName: { GroupVersion: registered.GroupOrDie(extensions.GroupName).GroupVersion.String(), Version: registered.GroupOrDie(extensions.GroupName).GroupVersion.Version, }, } assert.Equal(3, len(groupList.Groups)) for _, group := range groupList.Groups { if !expectGroupNames.Has(group.Name) { t.Errorf("got unexpected group %s", group.Name) } assert.Equal(expectVersions[group.Name], group.Versions) assert.Equal(expectPreferredVersion[group.Name], group.PreferredVersion) } thirdPartyGV := unversioned.GroupVersionForDiscovery{GroupVersion: "company.com/v1", Version: "v1"} master.addThirdPartyResourceStorage("/apis/company.com/v1", nil, unversioned.APIGroup{ Name: "company.com", Versions: []unversioned.GroupVersionForDiscovery{thirdPartyGV}, PreferredVersion: thirdPartyGV, }) resp, err = http.Get(server.URL + "/apis") if !assert.NoError(err) { t.Errorf("unexpected error: %v", err) } assert.Equal(http.StatusOK, resp.StatusCode) assert.NoError(decodeResponse(resp, &groupList)) if err != nil { t.Fatalf("unexpected error: %v", err) } assert.Equal(4, len(groupList.Groups)) expectGroupNames.Insert("company.com") expectVersions["company.com"] = []unversioned.GroupVersionForDiscovery{thirdPartyGV} expectPreferredVersion["company.com"] = thirdPartyGV for _, group := range groupList.Groups { if !expectGroupNames.Has(group.Name) { t.Errorf("got unexpected group %s", group.Name) } assert.Equal(expectVersions[group.Name], group.Versions) assert.Equal(expectPreferredVersion[group.Name], group.PreferredVersion) } }
func init() { if apiMediaType := os.Getenv("KUBE_TEST_API_TYPE"); len(apiMediaType) > 0 { var ok bool mediaType, options, err := mime.ParseMediaType(apiMediaType) if err != nil { panic(err) } serializer, ok = api.Codecs.SerializerForMediaType(mediaType, options) if !ok { panic(fmt.Sprintf("no serializer for %s", apiMediaType)) } } if storageMediaType := StorageMediaType(); len(storageMediaType) > 0 { var ok bool mediaType, options, err := mime.ParseMediaType(storageMediaType) if err != nil { panic(err) } storageSerializer, ok = api.Codecs.SerializerForMediaType(mediaType, options) if !ok { panic(fmt.Sprintf("no serializer for %s", storageMediaType)) } } kubeTestAPI := os.Getenv("KUBE_TEST_API") if len(kubeTestAPI) != 0 { testGroupVersions := strings.Split(kubeTestAPI, ",") for _, gvString := range testGroupVersions { groupVersion, err := unversioned.ParseGroupVersion(gvString) if err != nil { panic(fmt.Sprintf("Error parsing groupversion %v: %v", gvString, err)) } internalGroupVersion := unversioned.GroupVersion{Group: groupVersion.Group, Version: runtime.APIVersionInternal} Groups[groupVersion.Group] = TestGroup{ externalGroupVersion: groupVersion, internalGroupVersion: internalGroupVersion, internalTypes: api.Scheme.KnownTypes(internalGroupVersion), } } } if _, ok := Groups[api.GroupName]; !ok { Groups[api.GroupName] = TestGroup{ externalGroupVersion: unversioned.GroupVersion{Group: api.GroupName, Version: registered.GroupOrDie(api.GroupName).GroupVersion.Version}, internalGroupVersion: api.SchemeGroupVersion, internalTypes: api.Scheme.KnownTypes(api.SchemeGroupVersion), } } if _, ok := Groups[extensions.GroupName]; !ok { Groups[extensions.GroupName] = TestGroup{ externalGroupVersion: unversioned.GroupVersion{Group: extensions.GroupName, Version: registered.GroupOrDie(extensions.GroupName).GroupVersion.Version}, internalGroupVersion: extensions.SchemeGroupVersion, internalTypes: api.Scheme.KnownTypes(extensions.SchemeGroupVersion), } } 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 } Groups[autoscaling.GroupName] = TestGroup{ externalGroupVersion: unversioned.GroupVersion{Group: autoscaling.GroupName, Version: registered.GroupOrDie(autoscaling.GroupName).GroupVersion.Version}, internalGroupVersion: extensions.SchemeGroupVersion, internalTypes: internalTypes, } } 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 } } Groups[autoscaling.GroupName] = TestGroup{ externalGroupVersion: unversioned.GroupVersion{Group: autoscaling.GroupName, Version: registered.GroupOrDie(autoscaling.GroupName).GroupVersion.Version}, internalGroupVersion: autoscaling.SchemeGroupVersion, internalTypes: internalTypes, } } if _, ok := Groups[batch.GroupName]; !ok { Groups[batch.GroupName] = TestGroup{ externalGroupVersion: unversioned.GroupVersion{Group: batch.GroupName, Version: registered.GroupOrDie(batch.GroupName).GroupVersion.Version}, internalGroupVersion: batch.SchemeGroupVersion, internalTypes: api.Scheme.KnownTypes(batch.SchemeGroupVersion), } } if _, ok := Groups[apps.GroupName]; !ok { Groups[apps.GroupName] = TestGroup{ externalGroupVersion: unversioned.GroupVersion{Group: apps.GroupName, Version: registered.GroupOrDie(apps.GroupName).GroupVersion.Version}, internalGroupVersion: extensions.SchemeGroupVersion, internalTypes: api.Scheme.KnownTypes(extensions.SchemeGroupVersion), } } if _, ok := Groups[policy.GroupName]; !ok { Groups[policy.GroupName] = TestGroup{ externalGroupVersion: unversioned.GroupVersion{Group: policy.GroupName, Version: registered.GroupOrDie(policy.GroupName).GroupVersion.Version}, internalGroupVersion: policy.SchemeGroupVersion, internalTypes: api.Scheme.KnownTypes(policy.SchemeGroupVersion), } } if _, ok := Groups[federation.GroupName]; !ok { Groups[federation.GroupName] = TestGroup{ externalGroupVersion: unversioned.GroupVersion{Group: federation.GroupName, Version: registered.GroupOrDie(federation.GroupName).GroupVersion.Version}, internalGroupVersion: federation.SchemeGroupVersion, internalTypes: api.Scheme.KnownTypes(federation.SchemeGroupVersion), } } if _, ok := Groups[rbac.GroupName]; !ok { Groups[rbac.GroupName] = TestGroup{ externalGroupVersion: unversioned.GroupVersion{Group: rbac.GroupName, Version: registered.GroupOrDie(rbac.GroupName).GroupVersion.Version}, internalGroupVersion: rbac.SchemeGroupVersion, internalTypes: api.Scheme.KnownTypes(rbac.SchemeGroupVersion), } } if _, ok := Groups[certificates.GroupName]; !ok { Groups[certificates.GroupName] = TestGroup{ externalGroupVersion: unversioned.GroupVersion{Group: certificates.GroupName, Version: registered.GroupOrDie(certificates.GroupName).GroupVersion.Version}, internalGroupVersion: certificates.SchemeGroupVersion, internalTypes: api.Scheme.KnownTypes(certificates.SchemeGroupVersion), } } 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] }