diff --git a/hack/test-go.sh b/hack/test-go.sh index a63b684a4e..1586d3f3f8 100755 --- a/hack/test-go.sh +++ b/hack/test-go.sh @@ -58,6 +58,8 @@ KUBE_GOVERALLS_BIN=${KUBE_GOVERALLS_BIN:-} # Lists of API Versions of each groups that should be tested, groups are # separated by comma, lists are separated by semicolon. e.g., # "v1,compute/v1alpha1,experimental/v1alpha2;v1,compute/v2,experimental/v1alpha3" +# FIXME: due to current implementation of a test client (see: pkg/api/testapi/testapi.go) +# ONLY the last version is tested in each group. KUBE_TEST_API_VERSIONS=${KUBE_TEST_API_VERSIONS:-"v1,autoscaling/v1,batch/v1,batch/v2alpha1,extensions/v1beta1,apps/v1alpha1,federation/v1alpha1,policy/v1alpha1,rbac.authorization.k8s.io/v1alpha1"} # once we have multiple group supports # Create a junit-style XML test report in this directory if set. diff --git a/hack/test-integration.sh b/hack/test-integration.sh index dd64692f13..615fad3a7b 100755 --- a/hack/test-integration.sh +++ b/hack/test-integration.sh @@ -29,6 +29,8 @@ source "${KUBE_ROOT}/hack/lib/init.sh" # "v1,compute/v1alpha1,experimental/v1alpha2;v1,compute/v2,experimental/v1alpha3" # TODO: It's going to be: # KUBE_TEST_API_VERSIONS=${KUBE_TEST_API_VERSIONS:-"v1,extensions/v1beta1"} +# FIXME: due to current implementation of a test client (see: pkg/api/testapi/testapi.go) +# ONLY the last version is tested in each group. KUBE_TEST_API_VERSIONS=${KUBE_TEST_API_VERSIONS:-"v1,autoscaling/v1,batch/v1,apps/v1alpha1,policy/v1alpha1,extensions/v1beta1,rbac.authorization.k8s.io/v1alpha1"} # Give integration tests longer to run diff --git a/pkg/api/testapi/testapi.go b/pkg/api/testapi/testapi.go index 1c6319b7f2..518dddbfff 100644 --- a/pkg/api/testapi/testapi.go +++ b/pkg/api/testapi/testapi.go @@ -65,10 +65,9 @@ var ( ) type TestGroup struct { - // the first element in the group is meant to be the preferred version - externalGroupVersions []unversioned.GroupVersion - internalGroupVersion unversioned.GroupVersion - internalTypes map[string]reflect.Type + externalGroupVersion unversioned.GroupVersion + internalGroupVersion unversioned.GroupVersion + internalTypes map[string]reflect.Type } func init() { @@ -106,31 +105,26 @@ func init() { } internalGroupVersion := unversioned.GroupVersion{Group: groupVersion.Group, Version: runtime.APIVersionInternal} - if group, ok := Groups[groupVersion.Group]; !ok { - Groups[groupVersion.Group] = TestGroup{ - externalGroupVersions: []unversioned.GroupVersion{groupVersion}, - internalGroupVersion: internalGroupVersion, - internalTypes: api.Scheme.KnownTypes(internalGroupVersion), - } - } else { - group.externalGroupVersions = append(group.externalGroupVersions, groupVersion) - Groups[groupVersion.Group] = group + Groups[groupVersion.Group] = TestGroup{ + externalGroupVersion: groupVersion, + internalGroupVersion: internalGroupVersion, + internalTypes: api.Scheme.KnownTypes(internalGroupVersion), } } } if _, ok := Groups[api.GroupName]; !ok { Groups[api.GroupName] = TestGroup{ - externalGroupVersions: []unversioned.GroupVersion{{Group: api.GroupName, Version: registered.GroupOrDie(api.GroupName).GroupVersion.Version}}, - internalGroupVersion: api.SchemeGroupVersion, - internalTypes: api.Scheme.KnownTypes(api.SchemeGroupVersion), + 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{ - externalGroupVersions: []unversioned.GroupVersion{{Group: extensions.GroupName, Version: registered.GroupOrDie(extensions.GroupName).GroupVersion.Version}}, - internalGroupVersion: extensions.SchemeGroupVersion, - internalTypes: api.Scheme.KnownTypes(extensions.SchemeGroupVersion), + 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 { @@ -142,9 +136,9 @@ func init() { internalTypes[k] = t } Groups[autoscaling.GroupName] = TestGroup{ - externalGroupVersions: []unversioned.GroupVersion{{Group: autoscaling.GroupName, Version: registered.GroupOrDie(autoscaling.GroupName).GroupVersion.Version}}, - internalGroupVersion: extensions.SchemeGroupVersion, - internalTypes: internalTypes, + 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 { @@ -156,48 +150,44 @@ func init() { } } Groups[autoscaling.GroupName] = TestGroup{ - externalGroupVersions: []unversioned.GroupVersion{{Group: autoscaling.GroupName, Version: registered.GroupOrDie(autoscaling.GroupName).GroupVersion.Version}}, - internalGroupVersion: autoscaling.SchemeGroupVersion, - internalTypes: internalTypes, + externalGroupVersion: unversioned.GroupVersion{Group: autoscaling.GroupName, Version: registered.GroupOrDie(autoscaling.GroupName).GroupVersion.Version}, + internalGroupVersion: autoscaling.SchemeGroupVersion, + internalTypes: internalTypes, } } if _, ok := Groups[batch.GroupName]; !ok { - var gvs []unversioned.GroupVersion - for _, gv := range registered.GroupOrDie(batch.GroupName).GroupVersions { - gvs = append(gvs, gv) - } Groups[batch.GroupName] = TestGroup{ - externalGroupVersions: gvs, - internalGroupVersion: batch.SchemeGroupVersion, - internalTypes: api.Scheme.KnownTypes(batch.SchemeGroupVersion), + 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{ - externalGroupVersions: []unversioned.GroupVersion{{Group: apps.GroupName, Version: registered.GroupOrDie(apps.GroupName).GroupVersion.Version}}, - internalGroupVersion: extensions.SchemeGroupVersion, - internalTypes: api.Scheme.KnownTypes(extensions.SchemeGroupVersion), + 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{ - externalGroupVersions: []unversioned.GroupVersion{{Group: policy.GroupName, Version: registered.GroupOrDie(policy.GroupName).GroupVersion.Version}}, - internalGroupVersion: policy.SchemeGroupVersion, - internalTypes: api.Scheme.KnownTypes(policy.SchemeGroupVersion), + 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{ - externalGroupVersions: []unversioned.GroupVersion{{Group: federation.GroupName, Version: registered.GroupOrDie(federation.GroupName).GroupVersion.Version}}, - internalGroupVersion: federation.SchemeGroupVersion, - internalTypes: api.Scheme.KnownTypes(federation.SchemeGroupVersion), + 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{ - externalGroupVersions: []unversioned.GroupVersion{{Group: rbac.GroupName, Version: registered.GroupOrDie(rbac.GroupName).GroupVersion.Version}}, - internalGroupVersion: rbac.SchemeGroupVersion, - internalTypes: api.Scheme.KnownTypes(rbac.SchemeGroupVersion), + externalGroupVersion: unversioned.GroupVersion{Group: rbac.GroupName, Version: registered.GroupOrDie(rbac.GroupName).GroupVersion.Version}, + internalGroupVersion: rbac.SchemeGroupVersion, + internalTypes: api.Scheme.KnownTypes(rbac.SchemeGroupVersion), } } @@ -216,14 +206,10 @@ func (g TestGroup) ContentConfig() (string, *unversioned.GroupVersion, runtime.C } func (g TestGroup) GroupVersion() *unversioned.GroupVersion { - copyOfGroupVersion := g.externalGroupVersions[0] + copyOfGroupVersion := g.externalGroupVersion return ©OfGroupVersion } -func (g TestGroup) GroupVersions() []unversioned.GroupVersion { - return append([]unversioned.GroupVersion{}, g.externalGroupVersions...) -} - // InternalGroupVersion returns the group,version used to identify the internal // types for this API func (g TestGroup) InternalGroupVersion() unversioned.GroupVersion { @@ -239,9 +225,9 @@ func (g TestGroup) InternalTypes() map[string]reflect.Type { // KUBE_TEST_API_TYPE env var. func (g TestGroup) Codec() runtime.Codec { if serializer.Serializer == nil { - return api.Codecs.LegacyCodec(g.externalGroupVersions[0]) + return api.Codecs.LegacyCodec(g.externalGroupVersion) } - return api.Codecs.CodecForVersions(serializer, api.Codecs.UniversalDeserializer(), g.externalGroupVersions, nil) + return api.Codecs.CodecForVersions(serializer, api.Codecs.UniversalDeserializer(), []unversioned.GroupVersion{g.externalGroupVersion}, nil) } // NegotiatedSerializer returns the negotiated serializer for the server. @@ -259,7 +245,7 @@ func (g TestGroup) StorageCodec() runtime.Codec { s := storageSerializer.Serializer if s == nil { - return api.Codecs.LegacyCodec(g.externalGroupVersions[0]) + return api.Codecs.LegacyCodec(g.externalGroupVersion) } // etcd2 only supports string data - we must wrap any result before returning @@ -269,13 +255,13 @@ func (g TestGroup) StorageCodec() runtime.Codec { } ds := recognizer.NewDecoder(s, api.Codecs.UniversalDeserializer()) - return api.Codecs.CodecForVersions(s, ds, g.externalGroupVersions, nil) + return api.Codecs.CodecForVersions(s, ds, []unversioned.GroupVersion{g.externalGroupVersion}, nil) } // 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.externalGroupVersions[0].Group).InterfacesFor(g.externalGroupVersions[0]) + interfaces, err := registered.GroupOrDie(g.externalGroupVersion.Group).InterfacesFor(g.externalGroupVersion) if err != nil { panic(err) } @@ -285,7 +271,7 @@ func (g TestGroup) Converter() runtime.ObjectConvertor { // 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.externalGroupVersions[0].Group).InterfacesFor(g.externalGroupVersions[0]) + interfaces, err := registered.GroupOrDie(g.externalGroupVersion.Group).InterfacesFor(g.externalGroupVersion) if err != nil { panic(err) } @@ -296,18 +282,18 @@ func (g TestGroup) MetadataAccessor() meta.MetadataAccessor { // 'resource' should be the resource path, e.g. "pods" for the Pod type. 'name' should be // empty for lists. func (g TestGroup) SelfLink(resource, name string) string { - if g.externalGroupVersions[0].Group == api.GroupName { + if g.externalGroupVersion.Group == api.GroupName { if name == "" { - return fmt.Sprintf("/api/%s/%s", g.externalGroupVersions[0].Version, resource) + return fmt.Sprintf("/api/%s/%s", g.externalGroupVersion.Version, resource) } - return fmt.Sprintf("/api/%s/%s/%s", g.externalGroupVersions[0].Version, resource, name) + return fmt.Sprintf("/api/%s/%s/%s", g.externalGroupVersion.Version, resource, name) } else { // TODO: will need a /apis prefix once we have proper multi-group // support if name == "" { - return fmt.Sprintf("/apis/%s/%s/%s", g.externalGroupVersions[0].Group, g.externalGroupVersions[0].Version, resource) + return fmt.Sprintf("/apis/%s/%s/%s", g.externalGroupVersion.Group, g.externalGroupVersion.Version, resource) } - return fmt.Sprintf("/apis/%s/%s/%s/%s", g.externalGroupVersions[0].Group, g.externalGroupVersions[0].Version, resource, name) + return fmt.Sprintf("/apis/%s/%s/%s/%s", g.externalGroupVersion.Group, g.externalGroupVersion.Version, resource, name) } } @@ -316,12 +302,12 @@ func (g TestGroup) SelfLink(resource, name string) string { // /api/v1/watch/namespaces/foo/pods/pod0 for v1. func (g TestGroup) ResourcePathWithPrefix(prefix, resource, namespace, name string) string { var path string - if g.externalGroupVersions[0].Group == api.GroupName { - path = "/api/" + g.externalGroupVersions[0].Version + if g.externalGroupVersion.Group == api.GroupName { + path = "/api/" + g.externalGroupVersion.Version } else { // TODO: switch back once we have proper multiple group support // path = "/apis/" + g.Group + "/" + Version(group...) - path = "/apis/" + g.externalGroupVersions[0].Group + "/" + g.externalGroupVersions[0].Version + path = "/apis/" + g.externalGroupVersion.Group + "/" + g.externalGroupVersion.Version } if prefix != "" { @@ -391,9 +377,5 @@ func GetCodecForObject(obj runtime.Object) (runtime.Codec, error) { } func NewTestGroup(external, internal unversioned.GroupVersion, internalTypes map[string]reflect.Type) TestGroup { - return TestGroup{ - externalGroupVersions: []unversioned.GroupVersion{external}, - internalGroupVersion: internal, - internalTypes: internalTypes, - } + return TestGroup{external, internal, internalTypes} } diff --git a/pkg/api/testing/fuzzer.go b/pkg/api/testing/fuzzer.go index 8e3094ad82..dfd15fec3e 100644 --- a/pkg/api/testing/fuzzer.go +++ b/pkg/api/testing/fuzzer.go @@ -169,6 +169,10 @@ func FuzzerFor(t *testing.T, version unversioned.GroupVersion, src rand.Source) j.ManualSelector = nil } }, + func(cp *batch.ConcurrencyPolicy, c fuzz.Continue) { + policies := []batch.ConcurrencyPolicy{batch.AllowConcurrent, batch.ForbidConcurrent, batch.ReplaceConcurrent} + *cp = policies[c.Rand.Intn(len(policies))] + }, func(j *api.List, c fuzz.Continue) { c.FuzzNoCustom(j) // fuzz self without calling this function again // TODO: uncomment when round trip starts from a versioned object diff --git a/pkg/master/master_test.go b/pkg/master/master_test.go index b0eb668acc..317f0f32e6 100644 --- a/pkg/master/master_test.go +++ b/pkg/master/master_test.go @@ -429,6 +429,19 @@ func TestDiscoveryAtAPIS(t *testing.T) { 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(), @@ -442,15 +455,6 @@ func TestDiscoveryAtAPIS(t *testing.T) { }, }, } - var batchVersions []unversioned.GroupVersionForDiscovery - for _, gv := range testapi.Batch.GroupVersions() { - batchVersions = append(batchVersions, unversioned.GroupVersionForDiscovery{ - GroupVersion: gv.String(), - Version: gv.Version, - }) - } - expectVersions[batch.GroupName] = batchVersions - expectPreferredVersion := map[string]unversioned.GroupVersionForDiscovery{ autoscaling.GroupName: { GroupVersion: registered.GroupOrDie(autoscaling.GroupName).GroupVersion.String(), diff --git a/test/integration/master_test.go b/test/integration/master_test.go index 49b87e1da8..35f9e5cafc 100644 --- a/test/integration/master_test.go +++ b/test/integration/master_test.go @@ -33,6 +33,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/testapi" + "k8s.io/kubernetes/pkg/apis/batch/v2alpha1" "k8s.io/kubernetes/pkg/client/restclient" client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/master" @@ -257,6 +258,9 @@ var deleteResp string = ` // Job share storage. This test can be deleted when Jobs is removed from ext/v1beta1, // (expected to happen in 1.4). func TestBatchGroupBackwardCompatibility(t *testing.T) { + if *testapi.Batch.GroupVersion() == v2alpha1.SchemeGroupVersion { + t.Skip("Shared job storage is not required for batch/v2alpha1.") + } _, s := framework.RunAMaster(t) defer s.Close() transport := http.DefaultTransport