From 78a3a4a2b1dae52f8db0b49dd03c6aa8caf806b3 Mon Sep 17 00:00:00 2001 From: Jordan Liggitt Date: Fri, 13 Dec 2019 11:50:20 -0500 Subject: [PATCH] Remove testapi use from pkg/api/testing --- pkg/api/testing/BUILD | 25 +++++++- pkg/api/testing/conversion_test.go | 6 +- pkg/api/testing/deep_copy_test.go | 7 ++- pkg/api/testing/install.go | 44 ++++++++++++++ pkg/api/testing/serialization_test.go | 46 ++++++++------- pkg/api/testing/unstructured_test.go | 82 ++++++++++++++------------- 6 files changed, 143 insertions(+), 67 deletions(-) create mode 100644 pkg/api/testing/install.go diff --git a/pkg/api/testing/BUILD b/pkg/api/testing/BUILD index 66a98efbe00..cf7b178e2e1 100644 --- a/pkg/api/testing/BUILD +++ b/pkg/api/testing/BUILD @@ -12,27 +12,51 @@ go_library( "conversion.go", "doc.go", "fuzzer.go", + "install.go", "pod_specs.go", ], importpath = "k8s.io/kubernetes/pkg/api/testing", deps = [ "//pkg/api/legacyscheme:go_default_library", + "//pkg/apis/admission/install:go_default_library", "//pkg/apis/admissionregistration/fuzzer:go_default_library", + "//pkg/apis/admissionregistration/install:go_default_library", "//pkg/apis/apps:go_default_library", "//pkg/apis/apps/fuzzer:go_default_library", + "//pkg/apis/apps/install:go_default_library", "//pkg/apis/auditregistration/fuzzer:go_default_library", + "//pkg/apis/auditregistration/install:go_default_library", + "//pkg/apis/authentication/install:go_default_library", + "//pkg/apis/authorization/install:go_default_library", "//pkg/apis/autoscaling/fuzzer:go_default_library", + "//pkg/apis/autoscaling/install:go_default_library", "//pkg/apis/batch/fuzzer:go_default_library", + "//pkg/apis/batch/install:go_default_library", "//pkg/apis/certificates/fuzzer:go_default_library", + "//pkg/apis/certificates/install:go_default_library", + "//pkg/apis/coordination/install:go_default_library", "//pkg/apis/core:go_default_library", "//pkg/apis/core/fuzzer:go_default_library", + "//pkg/apis/core/install:go_default_library", "//pkg/apis/discovery/fuzzer:go_default_library", + "//pkg/apis/discovery/install:go_default_library", + "//pkg/apis/events/install:go_default_library", "//pkg/apis/extensions/fuzzer:go_default_library", + "//pkg/apis/extensions/install:go_default_library", + "//pkg/apis/flowcontrol/install:go_default_library", + "//pkg/apis/imagepolicy/install:go_default_library", "//pkg/apis/networking/fuzzer:go_default_library", + "//pkg/apis/networking/install:go_default_library", + "//pkg/apis/node/install:go_default_library", "//pkg/apis/policy/fuzzer:go_default_library", + "//pkg/apis/policy/install:go_default_library", "//pkg/apis/rbac/fuzzer:go_default_library", + "//pkg/apis/rbac/install:go_default_library", "//pkg/apis/scheduling/fuzzer:go_default_library", + "//pkg/apis/scheduling/install:go_default_library", + "//pkg/apis/settings/install:go_default_library", "//pkg/apis/storage/fuzzer:go_default_library", + "//pkg/apis/storage/install:go_default_library", "//staging/src/k8s.io/api/apps/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/apitesting:go_default_library", @@ -78,7 +102,6 @@ go_test( embed = [":go_default_library"], deps = [ "//pkg/api/legacyscheme:go_default_library", - "//pkg/api/testapi:go_default_library", "//pkg/api/testing/compat:go_default_library", "//pkg/apis/apps:go_default_library", "//pkg/apis/apps/v1:go_default_library", diff --git a/pkg/api/testing/conversion_test.go b/pkg/api/testing/conversion_test.go index 1064e050c8c..6dd3408cf54 100644 --- a/pkg/api/testing/conversion_test.go +++ b/pkg/api/testing/conversion_test.go @@ -21,13 +21,13 @@ import ( "math/rand" "testing" + v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/apitesting/fuzzer" apiequality "k8s.io/apimachinery/pkg/api/equality" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/diff" "k8s.io/kubernetes/pkg/api/legacyscheme" - "k8s.io/kubernetes/pkg/api/testapi" api "k8s.io/kubernetes/pkg/apis/core" ) @@ -63,7 +63,7 @@ func BenchmarkNodeConversion(b *testing.B) { b.Fatalf("Unexpected error while reading file: %v", err) } var node api.Node - if err := runtime.DecodeInto(testapi.Default.Codec(), data, &node); err != nil { + if err := runtime.DecodeInto(legacyscheme.Codecs.LegacyCodec(v1.SchemeGroupVersion), data, &node); err != nil { b.Fatalf("Unexpected error decoding node: %v", err) } @@ -93,7 +93,7 @@ func BenchmarkReplicationControllerConversion(b *testing.B) { b.Fatalf("Unexpected error while reading file: %v", err) } var replicationController api.ReplicationController - if err := runtime.DecodeInto(testapi.Default.Codec(), data, &replicationController); err != nil { + if err := runtime.DecodeInto(legacyscheme.Codecs.LegacyCodec(v1.SchemeGroupVersion), data, &replicationController); err != nil { b.Fatalf("Unexpected error decoding node: %v", err) } diff --git a/pkg/api/testing/deep_copy_test.go b/pkg/api/testing/deep_copy_test.go index b29b2f5a313..be6bdea61a9 100644 --- a/pkg/api/testing/deep_copy_test.go +++ b/pkg/api/testing/deep_copy_test.go @@ -21,11 +21,12 @@ import ( "testing" "time" + v1 "k8s.io/api/core/v1" apiequality "k8s.io/apimachinery/pkg/api/equality" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" - "k8s.io/kubernetes/pkg/api/testapi" + "k8s.io/kubernetes/pkg/api/legacyscheme" api "k8s.io/kubernetes/pkg/apis/core" ) @@ -144,7 +145,7 @@ func BenchmarkNodeCopy(b *testing.B) { b.Fatalf("Unexpected error while reading file: %v", err) } var node api.Node - if err := runtime.DecodeInto(testapi.Default.Codec(), data, &node); err != nil { + if err := runtime.DecodeInto(legacyscheme.Codecs.LegacyCodec(v1.SchemeGroupVersion), data, &node); err != nil { b.Fatalf("Unexpected error decoding node: %v", err) } @@ -163,7 +164,7 @@ func BenchmarkReplicationControllerCopy(b *testing.B) { b.Fatalf("Unexpected error while reading file: %v", err) } var replicationController api.ReplicationController - if err := runtime.DecodeInto(testapi.Default.Codec(), data, &replicationController); err != nil { + if err := runtime.DecodeInto(legacyscheme.Codecs.LegacyCodec(v1.SchemeGroupVersion), data, &replicationController); err != nil { b.Fatalf("Unexpected error decoding node: %v", err) } diff --git a/pkg/api/testing/install.go b/pkg/api/testing/install.go new file mode 100644 index 00000000000..0e26f65bf22 --- /dev/null +++ b/pkg/api/testing/install.go @@ -0,0 +1,44 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package testing + +import ( + // Initialize install packages + _ "k8s.io/kubernetes/pkg/apis/admission/install" + _ "k8s.io/kubernetes/pkg/apis/admissionregistration/install" + _ "k8s.io/kubernetes/pkg/apis/apps/install" + _ "k8s.io/kubernetes/pkg/apis/auditregistration/install" + _ "k8s.io/kubernetes/pkg/apis/authentication/install" + _ "k8s.io/kubernetes/pkg/apis/authorization/install" + _ "k8s.io/kubernetes/pkg/apis/autoscaling/install" + _ "k8s.io/kubernetes/pkg/apis/batch/install" + _ "k8s.io/kubernetes/pkg/apis/certificates/install" + _ "k8s.io/kubernetes/pkg/apis/coordination/install" + _ "k8s.io/kubernetes/pkg/apis/core/install" + _ "k8s.io/kubernetes/pkg/apis/discovery/install" + _ "k8s.io/kubernetes/pkg/apis/events/install" + _ "k8s.io/kubernetes/pkg/apis/extensions/install" + _ "k8s.io/kubernetes/pkg/apis/flowcontrol/install" + _ "k8s.io/kubernetes/pkg/apis/imagepolicy/install" + _ "k8s.io/kubernetes/pkg/apis/networking/install" + _ "k8s.io/kubernetes/pkg/apis/node/install" + _ "k8s.io/kubernetes/pkg/apis/policy/install" + _ "k8s.io/kubernetes/pkg/apis/rbac/install" + _ "k8s.io/kubernetes/pkg/apis/scheduling/install" + _ "k8s.io/kubernetes/pkg/apis/settings/install" + _ "k8s.io/kubernetes/pkg/apis/storage/install" +) diff --git a/pkg/api/testing/serialization_test.go b/pkg/api/testing/serialization_test.go index 5ad56a82e10..b3865203a21 100644 --- a/pkg/api/testing/serialization_test.go +++ b/pkg/api/testing/serialization_test.go @@ -42,7 +42,6 @@ import ( "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/watch" "k8s.io/kubernetes/pkg/api/legacyscheme" - "k8s.io/kubernetes/pkg/api/testapi" "k8s.io/kubernetes/pkg/apis/apps" k8s_apps_v1 "k8s.io/kubernetes/pkg/apis/apps/v1" api "k8s.io/kubernetes/pkg/apis/core" @@ -173,9 +172,16 @@ var commonKinds = []string{"Status", "ListOptions", "DeleteOptions", "ExportOpti // TestCommonKindsRegistered verifies that all group/versions registered with // the testapi package have the common kinds. func TestCommonKindsRegistered(t *testing.T) { + gvs := map[schema.GroupVersion]bool{} + for gvk := range legacyscheme.Scheme.AllKnownTypes() { + if gvk.Version == runtime.APIVersionInternal { + continue + } + gvs[gvk.GroupVersion()] = true + } + for _, kind := range commonKinds { - for _, group := range testapi.Groups { - gv := group.GroupVersion() + for gv := range gvs { gvk := gv.WithKind(kind) obj, err := legacyscheme.Scheme.New(gvk) if err != nil { @@ -186,7 +192,7 @@ func TestCommonKindsRegistered(t *testing.T) { if obj, got, err = legacyscheme.Codecs.LegacyCodec().Decode([]byte(`{"kind":"`+kind+`"}`), &defaults, obj); err != nil || gvk != *got { t.Errorf("expected %v: %v %v", gvk, got, err) } - data, err := runtime.Encode(legacyscheme.Codecs.LegacyCodec(*gv), obj) + data, err := runtime.Encode(legacyscheme.Codecs.LegacyCodec(gv), obj) if err != nil { t.Errorf("expected %v: %v\n%s", gvk, err, string(data)) continue @@ -239,8 +245,8 @@ func TestEncodePtr(t *testing.T) { }, } obj := runtime.Object(pod) - data, err := runtime.Encode(testapi.Default.Codec(), obj) - obj2, err2 := runtime.Decode(testapi.Default.Codec(), data) + data, err := runtime.Encode(legacyscheme.Codecs.LegacyCodec(v1.SchemeGroupVersion), obj) + obj2, err2 := runtime.Decode(legacyscheme.Codecs.LegacyCodec(v1.SchemeGroupVersion), data) if err != nil || err2 != nil { t.Fatalf("Failure: '%v' '%v'", err, err2) } @@ -262,7 +268,7 @@ metadata: spec: containers: null status: {}`) - if obj, err := runtime.Decode(testapi.Default.Codec(), testYAML); err != nil { + if obj, err := runtime.Decode(legacyscheme.Codecs.LegacyCodec(v1.SchemeGroupVersion), testYAML); err != nil { t.Fatalf("unable to decode yaml: %v", err) } else { if obj2, ok := obj.(*api.Pod); !ok { @@ -279,11 +285,11 @@ status: {}`) // an unknown kind will not be decoded without error. func TestBadJSONRejection(t *testing.T) { badJSONMissingKind := []byte(`{ }`) - if _, err := runtime.Decode(testapi.Default.Codec(), badJSONMissingKind); err == nil { + if _, err := runtime.Decode(legacyscheme.Codecs.LegacyCodec(v1.SchemeGroupVersion), badJSONMissingKind); err == nil { t.Errorf("Did not reject despite lack of kind field: %s", badJSONMissingKind) } badJSONUnknownType := []byte(`{"kind": "bar"}`) - if _, err1 := runtime.Decode(testapi.Default.Codec(), badJSONUnknownType); err1 == nil { + if _, err1 := runtime.Decode(legacyscheme.Codecs.LegacyCodec(v1.SchemeGroupVersion), badJSONUnknownType); err1 == nil { t.Errorf("Did not reject despite use of unknown type: %s", badJSONUnknownType) } /*badJSONKindMismatch := []byte(`{"kind": "Pod"}`) @@ -305,14 +311,14 @@ func TestUnversionedTypes(t *testing.T) { for _, obj := range testcases { // Make sure the unversioned codec can encode - unversionedJSON, err := runtime.Encode(testapi.Default.Codec(), obj) + unversionedJSON, err := runtime.Encode(legacyscheme.Codecs.LegacyCodec(v1.SchemeGroupVersion), obj) if err != nil { t.Errorf("%v: unexpected error: %v", obj, err) continue } // Make sure the versioned codec under test can decode - versionDecodedObject, err := runtime.Decode(testapi.Default.Codec(), unversionedJSON) + versionDecodedObject, err := runtime.Decode(legacyscheme.Codecs.LegacyCodec(v1.SchemeGroupVersion), unversionedJSON) if err != nil { t.Errorf("%v: unexpected error: %v", obj, err) continue @@ -454,7 +460,7 @@ func BenchmarkEncodeCodec(b *testing.B) { width := len(items) b.ResetTimer() for i := 0; i < b.N; i++ { - if _, err := runtime.Encode(testapi.Default.Codec(), &items[i%width]); err != nil { + if _, err := runtime.Encode(legacyscheme.Codecs.LegacyCodec(v1.SchemeGroupVersion), &items[i%width]); err != nil { b.Fatal(err) } } @@ -474,7 +480,7 @@ func BenchmarkEncodeCodecFromInternal(b *testing.B) { } b.ResetTimer() for i := 0; i < b.N; i++ { - if _, err := runtime.Encode(testapi.Default.Codec(), &encodable[i%width]); err != nil { + if _, err := runtime.Encode(legacyscheme.Codecs.LegacyCodec(v1.SchemeGroupVersion), &encodable[i%width]); err != nil { b.Fatal(err) } } @@ -495,7 +501,7 @@ func BenchmarkEncodeJSONMarshal(b *testing.B) { } func BenchmarkDecodeCodec(b *testing.B) { - codec := testapi.Default.Codec() + codec := legacyscheme.Codecs.LegacyCodec(v1.SchemeGroupVersion) items := benchmarkItems(b) width := len(items) encoded := make([][]byte, width) @@ -517,7 +523,7 @@ func BenchmarkDecodeCodec(b *testing.B) { } func BenchmarkDecodeIntoExternalCodec(b *testing.B) { - codec := testapi.Default.Codec() + codec := legacyscheme.Codecs.LegacyCodec(v1.SchemeGroupVersion) items := benchmarkItems(b) width := len(items) encoded := make([][]byte, width) @@ -540,7 +546,7 @@ func BenchmarkDecodeIntoExternalCodec(b *testing.B) { } func BenchmarkDecodeIntoInternalCodec(b *testing.B) { - codec := testapi.Default.Codec() + codec := legacyscheme.Codecs.LegacyCodec(v1.SchemeGroupVersion) items := benchmarkItems(b) width := len(items) encoded := make([][]byte, width) @@ -564,7 +570,7 @@ func BenchmarkDecodeIntoInternalCodec(b *testing.B) { // BenchmarkDecodeJSON provides a baseline for regular JSON decode performance func BenchmarkDecodeIntoJSON(b *testing.B) { - codec := testapi.Default.Codec() + codec := legacyscheme.Codecs.LegacyCodec(v1.SchemeGroupVersion) items := benchmarkItems(b) width := len(items) encoded := make([][]byte, width) @@ -589,7 +595,7 @@ func BenchmarkDecodeIntoJSON(b *testing.B) { // BenchmarkDecodeIntoJSONCodecGenConfigFast provides a baseline // for JSON decode performance with jsoniter.ConfigFast func BenchmarkDecodeIntoJSONCodecGenConfigFast(b *testing.B) { - kcodec := testapi.Default.Codec() + kcodec := legacyscheme.Codecs.LegacyCodec(v1.SchemeGroupVersion) items := benchmarkItems(b) width := len(items) encoded := make([][]byte, width) @@ -616,7 +622,7 @@ func BenchmarkDecodeIntoJSONCodecGenConfigFast(b *testing.B) { // jsoniter.ConfigCompatibleWithStandardLibrary, but with case sensitivity set // to true func BenchmarkDecodeIntoJSONCodecGenConfigCompatibleWithStandardLibrary(b *testing.B) { - kcodec := testapi.Default.Codec() + kcodec := legacyscheme.Codecs.LegacyCodec(v1.SchemeGroupVersion) items := benchmarkItems(b) width := len(items) encoded := make([][]byte, width) @@ -654,7 +660,7 @@ func BenchmarkEncodeYAMLMarshal(b *testing.B) { // BenchmarkDecodeYAML provides a baseline for regular YAML decode performance func BenchmarkDecodeIntoYAML(b *testing.B) { - codec := testapi.Default.Codec() + codec := legacyscheme.Codecs.LegacyCodec(v1.SchemeGroupVersion) items := benchmarkItems(b) width := len(items) encoded := make([][]byte, width) diff --git a/pkg/api/testing/unstructured_test.go b/pkg/api/testing/unstructured_test.go index 922be30b54a..32d51183402 100644 --- a/pkg/api/testing/unstructured_test.go +++ b/pkg/api/testing/unstructured_test.go @@ -36,7 +36,6 @@ import ( "k8s.io/apimachinery/pkg/util/diff" "k8s.io/apimachinery/pkg/util/json" "k8s.io/kubernetes/pkg/api/legacyscheme" - "k8s.io/kubernetes/pkg/api/testapi" api "k8s.io/kubernetes/pkg/apis/core" ) @@ -120,55 +119,58 @@ func doRoundTrip(t *testing.T, internalVersion schema.GroupVersion, externalVers } func TestRoundTrip(t *testing.T) { - for groupKey, group := range testapi.Groups { - for kind := range legacyscheme.Scheme.KnownTypes(*group.GroupVersion()) { - if nonRoundTrippableTypes.Has(kind) { - continue - } - t.Logf("Testing: %v in %v", kind, groupKey) - for i := 0; i < 50; i++ { - doRoundTrip(t, schema.GroupVersion{Group: groupKey, Version: runtime.APIVersionInternal}, *group.GroupVersion(), kind) - if t.Failed() { - break - } + for gvk := range legacyscheme.Scheme.AllKnownTypes() { + if nonRoundTrippableTypes.Has(gvk.Kind) { + continue + } + if gvk.Version == runtime.APIVersionInternal { + continue + } + t.Logf("Testing: %v in %v", gvk.Kind, gvk.GroupVersion().String()) + for i := 0; i < 50; i++ { + doRoundTrip(t, schema.GroupVersion{Group: gvk.Group, Version: runtime.APIVersionInternal}, gvk.GroupVersion(), gvk.Kind) + if t.Failed() { + break } } } } func TestRoundTripWithEmptyCreationTimestamp(t *testing.T) { - for groupKey, group := range testapi.Groups { - for kind := range legacyscheme.Scheme.KnownTypes(*group.GroupVersion()) { - if nonRoundTrippableTypes.Has(kind) { - continue - } - item, err := legacyscheme.Scheme.New(group.GroupVersion().WithKind(kind)) - if err != nil { - t.Fatalf("Couldn't create external object %v: %v", kind, err) - } - t.Logf("Testing: %v in %v", kind, groupKey) + for gvk := range legacyscheme.Scheme.AllKnownTypes() { + if nonRoundTrippableTypes.Has(gvk.Kind) { + continue + } + if gvk.Version == runtime.APIVersionInternal { + continue + } - unstrBody, err := runtime.DefaultUnstructuredConverter.ToUnstructured(item) - if err != nil { - t.Fatalf("ToUnstructured failed: %v", err) - } + item, err := legacyscheme.Scheme.New(gvk) + if err != nil { + t.Fatalf("Couldn't create external object %v: %v", gvk, err) + } + t.Logf("Testing: %v in %v", gvk.Kind, gvk.GroupVersion().String()) - unstructObj := &metaunstruct.Unstructured{} - unstructObj.Object = unstrBody + unstrBody, err := runtime.DefaultUnstructuredConverter.ToUnstructured(item) + if err != nil { + t.Fatalf("ToUnstructured failed: %v", err) + } - if meta, err := meta.Accessor(unstructObj); err == nil { - meta.SetCreationTimestamp(metav1.Time{}) - } else { - t.Fatalf("Unable to set creation timestamp: %v", err) - } + unstructObj := &metaunstruct.Unstructured{} + unstructObj.Object = unstrBody - // attempt to re-convert unstructured object - conversion should not fail - // based on empty metadata fields, such as creationTimestamp - newObj := reflect.New(reflect.TypeOf(item).Elem()).Interface().(runtime.Object) - err = runtime.DefaultUnstructuredConverter.FromUnstructured(unstructObj.Object, newObj) - if err != nil { - t.Fatalf("FromUnstructured failed: %v", err) - } + if meta, err := meta.Accessor(unstructObj); err == nil { + meta.SetCreationTimestamp(metav1.Time{}) + } else { + t.Fatalf("Unable to set creation timestamp: %v", err) + } + + // attempt to re-convert unstructured object - conversion should not fail + // based on empty metadata fields, such as creationTimestamp + newObj := reflect.New(reflect.TypeOf(item).Elem()).Interface().(runtime.Object) + err = runtime.DefaultUnstructuredConverter.FromUnstructured(unstructObj.Object, newObj) + if err != nil { + t.Fatalf("FromUnstructured failed: %v", err) } } }