diff --git a/cmd/kubeadm/app/apis/kubeadm/fuzzer/BUILD b/cmd/kubeadm/app/apis/kubeadm/fuzzer/BUILD index b2ad5ce8695..f2c41c93f16 100644 --- a/cmd/kubeadm/app/apis/kubeadm/fuzzer/BUILD +++ b/cmd/kubeadm/app/apis/kubeadm/fuzzer/BUILD @@ -14,7 +14,7 @@ go_library( deps = [ "//cmd/kubeadm/app/apis/kubeadm:go_default_library", "//vendor/github.com/google/gofuzz:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/api/testing:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library", ], ) diff --git a/cmd/kubeadm/app/apis/kubeadm/fuzzer/fuzzer.go b/cmd/kubeadm/app/apis/kubeadm/fuzzer/fuzzer.go index e30f2c3e09e..c1293057a3f 100644 --- a/cmd/kubeadm/app/apis/kubeadm/fuzzer/fuzzer.go +++ b/cmd/kubeadm/app/apis/kubeadm/fuzzer/fuzzer.go @@ -19,11 +19,12 @@ package fuzzer import ( "github.com/google/gofuzz" - apitesting "k8s.io/apimachinery/pkg/api/testing" + runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" ) -func KubeadmFuzzerFuncs(t apitesting.TestingCommon) []interface{} { +// Funcs returns the fuzzer functions for the kubeadm apis. +func Funcs(codecs runtimeserializer.CodecFactory) []interface{} { return []interface{}{ func(obj *kubeadm.MasterConfiguration, c fuzz.Continue) { c.FuzzNoCustom(obj) diff --git a/cmd/kubeadm/app/apis/kubeadm/install/BUILD b/cmd/kubeadm/app/apis/kubeadm/install/BUILD index 6213ed8f63b..7e3da0c15d9 100644 --- a/cmd/kubeadm/app/apis/kubeadm/install/BUILD +++ b/cmd/kubeadm/app/apis/kubeadm/install/BUILD @@ -45,6 +45,6 @@ go_test( tags = ["automanaged"], deps = [ "//cmd/kubeadm/app/apis/kubeadm/fuzzer:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/api/testing:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/api/testing/roundtrip:go_default_library", ], ) diff --git a/cmd/kubeadm/app/apis/kubeadm/install/install_test.go b/cmd/kubeadm/app/apis/kubeadm/install/install_test.go index 65c2cf13c6f..116033df759 100644 --- a/cmd/kubeadm/app/apis/kubeadm/install/install_test.go +++ b/cmd/kubeadm/app/apis/kubeadm/install/install_test.go @@ -19,10 +19,10 @@ package install import ( "testing" - apitesting "k8s.io/apimachinery/pkg/api/testing" - "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/fuzzer" + "k8s.io/apimachinery/pkg/api/testing/roundtrip" + kubeadmfuzzer "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/fuzzer" ) func TestRoundTripTypes(t *testing.T) { - apitesting.RoundTripTestForAPIGroup(t, Install, fuzzer.KubeadmFuzzerFuncs(t)) + roundtrip.RoundTripTestForAPIGroup(t, Install, kubeadmfuzzer.Funcs) } diff --git a/hack/.golint_failures b/hack/.golint_failures index 74f1571a0be..a5f081d54f2 100644 --- a/hack/.golint_failures +++ b/hack/.golint_failures @@ -9,7 +9,6 @@ cmd/kube-controller-manager/app cmd/kube-proxy/app cmd/kubeadm/app cmd/kubeadm/app/apis/kubeadm -cmd/kubeadm/app/apis/kubeadm/fuzzer cmd/kubeadm/app/apis/kubeadm/v1alpha1 cmd/kubeadm/app/apis/kubeadm/validation cmd/kubeadm/app/cmd @@ -579,18 +578,19 @@ staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresource staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresourcedefinition staging/src/k8s.io/apiextensions-apiserver/test/integration/testserver staging/src/k8s.io/apimachinery/pkg/api/meta -staging/src/k8s.io/apimachinery/pkg/api/testing +staging/src/k8s.io/apimachinery/pkg/api/testing/fuzzer +staging/src/k8s.io/apimachinery/pkg/api/testing/roundtrip staging/src/k8s.io/apimachinery/pkg/api/validation staging/src/k8s.io/apimachinery/pkg/api/validation/path staging/src/k8s.io/apimachinery/pkg/apimachinery/announced staging/src/k8s.io/apimachinery/pkg/apimachinery/registered +staging/src/k8s.io/apimachinery/pkg/apis/meta/fuzzer staging/src/k8s.io/apimachinery/pkg/apis/meta/internalversion staging/src/k8s.io/apimachinery/pkg/apis/meta/v1 staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/validation staging/src/k8s.io/apimachinery/pkg/apis/meta/v1alpha1 staging/src/k8s.io/apimachinery/pkg/apis/testapigroup -staging/src/k8s.io/apimachinery/pkg/apis/testapigroup/fuzzer staging/src/k8s.io/apimachinery/pkg/apis/testapigroup/v1 staging/src/k8s.io/apimachinery/pkg/conversion staging/src/k8s.io/apimachinery/pkg/conversion/unstructured @@ -636,7 +636,6 @@ staging/src/k8s.io/apiserver/pkg/apis/audit staging/src/k8s.io/apiserver/pkg/apis/audit/v1alpha1 staging/src/k8s.io/apiserver/pkg/apis/audit/validation staging/src/k8s.io/apiserver/pkg/apis/example -staging/src/k8s.io/apiserver/pkg/apis/example/fuzzer staging/src/k8s.io/apiserver/pkg/apis/example/v1 staging/src/k8s.io/apiserver/pkg/audit staging/src/k8s.io/apiserver/pkg/audit/policy diff --git a/pkg/api/BUILD b/pkg/api/BUILD index 4a769a97ade..a19431bbb15 100644 --- a/pkg/api/BUILD +++ b/pkg/api/BUILD @@ -77,7 +77,8 @@ go_test( "//vendor/k8s.io/api/extensions/v1beta1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/equality:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/api/testing:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/api/testing/fuzzer:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/api/testing/roundtrip:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/conversion:go_default_library", "//vendor/k8s.io/apimachinery/pkg/conversion/unstructured:go_default_library", diff --git a/pkg/api/conversion_test.go b/pkg/api/conversion_test.go index dc423764cf0..b4c79696cd6 100644 --- a/pkg/api/conversion_test.go +++ b/pkg/api/conversion_test.go @@ -22,7 +22,7 @@ import ( "testing" apiequality "k8s.io/apimachinery/pkg/api/equality" - apitesting "k8s.io/apimachinery/pkg/api/testing" + "k8s.io/apimachinery/pkg/api/testing/fuzzer" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/diff" "k8s.io/kubernetes/pkg/api" @@ -31,7 +31,7 @@ import ( ) func BenchmarkPodConversion(b *testing.B) { - apiObjectFuzzer := apitesting.FuzzerFor(kapitesting.FuzzerFuncs(b, api.Codecs), rand.NewSource(benchmarkSeed)) + apiObjectFuzzer := fuzzer.FuzzerFor(kapitesting.FuzzerFuncs, rand.NewSource(benchmarkSeed), api.Codecs) items := make([]api.Pod, 4) for i := range items { apiObjectFuzzer.Fuzz(&items[i]) diff --git a/pkg/api/copy_test.go b/pkg/api/copy_test.go index 9d6ad4feb8c..d3775e0760c 100644 --- a/pkg/api/copy_test.go +++ b/pkg/api/copy_test.go @@ -22,20 +22,21 @@ import ( "reflect" "testing" - apitesting "k8s.io/apimachinery/pkg/api/testing" + "github.com/google/gofuzz" + + "k8s.io/apimachinery/pkg/api/testing/fuzzer" + "k8s.io/apimachinery/pkg/api/testing/roundtrip" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/diff" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/testapi" kapitesting "k8s.io/kubernetes/pkg/api/testing" - - "github.com/google/gofuzz" ) func TestDeepCopyApiObjects(t *testing.T) { - for i := 0; i < *apitesting.FuzzIters; i++ { + for i := 0; i < *roundtrip.FuzzIters; i++ { for _, version := range []schema.GroupVersion{testapi.Default.InternalGroupVersion(), api.Registry.GroupOrDie(api.GroupName).GroupVersion} { - f := apitesting.FuzzerFor(kapitesting.FuzzerFuncs(t, api.Codecs), rand.NewSource(rand.Int63())) + f := fuzzer.FuzzerFor(kapitesting.FuzzerFuncs, rand.NewSource(rand.Int63()), api.Codecs) for kind := range api.Scheme.KnownTypes(version) { doDeepCopyTest(t, version.WithKind(kind), f) } @@ -82,9 +83,9 @@ func doDeepCopyTest(t *testing.T, kind schema.GroupVersionKind, f *fuzz.Fuzzer) } func TestDeepCopySingleType(t *testing.T) { - for i := 0; i < *apitesting.FuzzIters; i++ { + for i := 0; i < *roundtrip.FuzzIters; i++ { for _, version := range []schema.GroupVersion{testapi.Default.InternalGroupVersion(), api.Registry.GroupOrDie(api.GroupName).GroupVersion} { - f := apitesting.FuzzerFor(kapitesting.FuzzerFuncs(t, api.Codecs), rand.NewSource(rand.Int63())) + f := fuzzer.FuzzerFor(kapitesting.FuzzerFuncs, rand.NewSource(rand.Int63()), api.Codecs) doDeepCopyTest(t, version.WithKind("Pod"), f) } } diff --git a/pkg/api/defaulting_test.go b/pkg/api/defaulting_test.go index 37480c358f9..dc7a355e132 100644 --- a/pkg/api/defaulting_test.go +++ b/pkg/api/defaulting_test.go @@ -27,7 +27,7 @@ import ( batchv2alpha1 "k8s.io/api/batch/v2alpha1" apiv1 "k8s.io/api/core/v1" extensionsv1beta1 "k8s.io/api/extensions/v1beta1" - apitesting "k8s.io/apimachinery/pkg/api/testing" + roundtrip "k8s.io/apimachinery/pkg/api/testing/roundtrip" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" @@ -163,7 +163,7 @@ func TestDefaulting(t *testing.T) { iter := 0 changedOnce := false for { - if iter > *apitesting.FuzzIters { + if iter > *roundtrip.FuzzIters { if !expectedChanged || changedOnce { break } diff --git a/pkg/api/serialization_proto_test.go b/pkg/api/serialization_proto_test.go index 4bb31f8cc42..b33d7eaeb5d 100644 --- a/pkg/api/serialization_proto_test.go +++ b/pkg/api/serialization_proto_test.go @@ -27,7 +27,7 @@ import ( "github.com/gogo/protobuf/proto" "k8s.io/api/core/v1" apiequality "k8s.io/apimachinery/pkg/api/equality" - apitesting "k8s.io/apimachinery/pkg/api/testing" + "k8s.io/apimachinery/pkg/api/testing/fuzzer" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" @@ -98,7 +98,7 @@ func fieldsHaveProtobufTags(obj reflect.Type) error { func TestProtobufRoundTrip(t *testing.T) { obj := &v1.Pod{} - apitesting.FuzzerFor(kapitesting.FuzzerFuncs(t, api.Codecs), rand.NewSource(benchmarkSeed)).Fuzz(obj) + fuzzer.FuzzerFor(kapitesting.FuzzerFuncs, rand.NewSource(benchmarkSeed), api.Codecs).Fuzz(obj) // InitContainers are turned into annotations by conversion. obj.Spec.InitContainers = nil obj.Status.InitContainerStatuses = nil diff --git a/pkg/api/serialization_test.go b/pkg/api/serialization_test.go index 08fe48b483e..ff7ca6ee3d7 100644 --- a/pkg/api/serialization_test.go +++ b/pkg/api/serialization_test.go @@ -33,7 +33,8 @@ import ( "k8s.io/api/extensions/v1beta1" apiequality "k8s.io/apimachinery/pkg/api/equality" "k8s.io/apimachinery/pkg/api/meta" - apitesting "k8s.io/apimachinery/pkg/api/testing" + "k8s.io/apimachinery/pkg/api/testing/fuzzer" + "k8s.io/apimachinery/pkg/api/testing/roundtrip" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/conversion" "k8s.io/apimachinery/pkg/runtime" @@ -53,7 +54,7 @@ import ( // fuzzInternalObject fuzzes an arbitrary runtime object using the appropriate // fuzzer registered with the apitesting package. func fuzzInternalObject(t *testing.T, forVersion schema.GroupVersion, item runtime.Object, seed int64) runtime.Object { - apitesting.FuzzerFor(kapitesting.FuzzerFuncs(t, api.Codecs), rand.NewSource(seed)).Fuzz(item) + fuzzer.FuzzerFor(kapitesting.FuzzerFuncs, rand.NewSource(seed), api.Codecs).Fuzz(item) j, err := meta.TypeAccessor(item) if err != nil { @@ -143,9 +144,9 @@ func TestSpecificKind(t *testing.T) { internalGVK := schema.GroupVersionKind{Group: "extensions", Version: runtime.APIVersionInternal, Kind: "DaemonSet"} seed := rand.Int63() - fuzzer := apitesting.FuzzerFor(kapitesting.FuzzerFuncs(t, api.Codecs), rand.NewSource(seed)) + fuzzer := fuzzer.FuzzerFor(kapitesting.FuzzerFuncs, rand.NewSource(seed), api.Codecs) - apitesting.RoundTripSpecificKind(t, internalGVK, api.Scheme, api.Codecs, fuzzer, nil) + roundtrip.RoundTripSpecificKind(t, internalGVK, api.Scheme, api.Codecs, fuzzer, nil) } var nonRoundTrippableTypes = sets.NewString( @@ -204,7 +205,7 @@ func TestCommonKindsRegistered(t *testing.T) { // in all of the API groups registered for test in the testapi package. func TestRoundTripTypes(t *testing.T) { seed := rand.Int63() - fuzzer := apitesting.FuzzerFor(kapitesting.FuzzerFuncs(t, api.Codecs), rand.NewSource(seed)) + fuzzer := fuzzer.FuzzerFor(kapitesting.FuzzerFuncs, rand.NewSource(seed), api.Codecs) nonRoundTrippableTypes := map[schema.GroupVersionKind]bool{ {Group: "componentconfig", Version: runtime.APIVersionInternal, Kind: "KubeletConfiguration"}: true, @@ -212,7 +213,7 @@ func TestRoundTripTypes(t *testing.T) { {Group: "componentconfig", Version: runtime.APIVersionInternal, Kind: "KubeSchedulerConfiguration"}: true, } - apitesting.RoundTripTypes(t, api.Scheme, api.Codecs, fuzzer, nonRoundTrippableTypes) + roundtrip.RoundTripTypes(t, api.Scheme, api.Codecs, fuzzer, nonRoundTrippableTypes) } // TestEncodePtr tests that a pointer to a golang type can be encoded and @@ -300,7 +301,7 @@ func TestUnversionedTypes(t *testing.T) { // TestObjectWatchFraming establishes that a watch event can be encoded and // decoded correctly through each of the supported RFC2046 media types. func TestObjectWatchFraming(t *testing.T) { - f := apitesting.FuzzerFor(kapitesting.FuzzerFuncs(t, api.Codecs), rand.NewSource(benchmarkSeed)) + f := fuzzer.FuzzerFor(kapitesting.FuzzerFuncs, rand.NewSource(benchmarkSeed), api.Codecs) secret := &api.Secret{} f.Fuzz(secret) secret.Data["binary"] = []byte{0x00, 0x10, 0x30, 0x55, 0xff, 0x00} @@ -382,7 +383,7 @@ func TestObjectWatchFraming(t *testing.T) { const benchmarkSeed = 100 func benchmarkItems(b *testing.B) []v1.Pod { - apiObjectFuzzer := apitesting.FuzzerFor(kapitesting.FuzzerFuncs(b, api.Codecs), rand.NewSource(benchmarkSeed)) + apiObjectFuzzer := fuzzer.FuzzerFor(kapitesting.FuzzerFuncs, rand.NewSource(benchmarkSeed), api.Codecs) items := make([]v1.Pod, 10) for i := range items { var pod api.Pod diff --git a/pkg/api/testing/BUILD b/pkg/api/testing/BUILD index e4815fb7e6c..a0858217a65 100644 --- a/pkg/api/testing/BUILD +++ b/pkg/api/testing/BUILD @@ -32,6 +32,8 @@ go_library( "//vendor/k8s.io/api/core/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/testing:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/api/testing/fuzzer:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/apis/meta/fuzzer:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/fields:go_default_library", "//vendor/k8s.io/apimachinery/pkg/labels:go_default_library", diff --git a/pkg/api/testing/fuzzer.go b/pkg/api/testing/fuzzer.go index d4cd5e33415..305131b3a53 100644 --- a/pkg/api/testing/fuzzer.go +++ b/pkg/api/testing/fuzzer.go @@ -26,6 +26,8 @@ import ( "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" apitesting "k8s.io/apimachinery/pkg/api/testing" + "k8s.io/apimachinery/pkg/api/testing/fuzzer" + genericfuzzer "k8s.io/apimachinery/pkg/apis/meta/fuzzer" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/fields" "k8s.io/apimachinery/pkg/labels" @@ -49,7 +51,7 @@ import ( // overrideGenericFuncs override some generic fuzzer funcs from k8s.io/apiserver in order to have more realistic // values in a Kubernetes context. -func overrideGenericFuncs(t apitesting.TestingCommon, codecs runtimeserializer.CodecFactory) []interface{} { +func overrideGenericFuncs(codecs runtimeserializer.CodecFactory) []interface{} { return []interface{}{ func(j *runtime.Object, c fuzz.Continue) { // TODO: uncomment when round trip starts from a versioned object @@ -83,8 +85,7 @@ func overrideGenericFuncs(t apitesting.TestingCommon, codecs runtimeserializer.C // Convert the object to raw bytes bytes, err := runtime.Encode(codec, obj) if err != nil { - t.Errorf("Failed to encode object: %v", err) - return + panic(fmt.Sprintf("Failed to encode object: %v", err)) } // Set the bytes field on the RawExtension @@ -93,7 +94,7 @@ func overrideGenericFuncs(t apitesting.TestingCommon, codecs runtimeserializer.C } } -func coreFuncs(t apitesting.TestingCommon) []interface{} { +func coreFuncs(codecs runtimeserializer.CodecFactory) []interface{} { return []interface{}{ func(q *resource.Quantity, c fuzz.Continue) { *q = *resource.NewQuantity(c.Int63n(1000), resource.DecimalExponent) @@ -500,7 +501,7 @@ func coreFuncs(t apitesting.TestingCommon) []interface{} { } } -func extensionFuncs(t apitesting.TestingCommon) []interface{} { +func extensionFuncs(codecs runtimeserializer.CodecFactory) []interface{} { return []interface{}{ func(j *extensions.DeploymentSpec, c fuzz.Continue) { c.FuzzNoCustom(j) // fuzz self without calling this function again @@ -580,7 +581,7 @@ func extensionFuncs(t apitesting.TestingCommon) []interface{} { } } -func batchFuncs(t apitesting.TestingCommon) []interface{} { +func batchFuncs(codecs runtimeserializer.CodecFactory) []interface{} { return []interface{}{ func(j *batch.JobSpec, c fuzz.Continue) { c.FuzzNoCustom(j) // fuzz self without calling this function again @@ -617,7 +618,7 @@ func batchFuncs(t apitesting.TestingCommon) []interface{} { } } -func autoscalingFuncs(t apitesting.TestingCommon) []interface{} { +func autoscalingFuncs(codecs runtimeserializer.CodecFactory) []interface{} { return []interface{}{ func(s *autoscaling.HorizontalPodAutoscalerSpec, c fuzz.Continue) { c.FuzzNoCustom(s) // fuzz self without calling this function again @@ -680,7 +681,7 @@ func autoscalingFuncs(t apitesting.TestingCommon) []interface{} { } } -func rbacFuncs(t apitesting.TestingCommon) []interface{} { +func rbacFuncs(codecs runtimeserializer.CodecFactory) []interface{} { return []interface{}{ func(r *rbac.RoleRef, c fuzz.Continue) { c.FuzzNoCustom(r) // fuzz self without calling this function again @@ -714,7 +715,7 @@ func rbacFuncs(t apitesting.TestingCommon) []interface{} { } } -func appsFuncs(t apitesting.TestingCommon) []interface{} { +func appsFuncs(codecs runtimeserializer.CodecFactory) []interface{} { return []interface{}{ func(s *apps.StatefulSet, c fuzz.Continue) { c.FuzzNoCustom(s) // fuzz self without calling this function again @@ -733,7 +734,7 @@ func appsFuncs(t apitesting.TestingCommon) []interface{} { }, } } -func policyFuncs(t apitesting.TestingCommon) []interface{} { +func policyFuncs(codecs runtimeserializer.CodecFactory) []interface{} { return []interface{}{ func(s *policy.PodDisruptionBudgetStatus, c fuzz.Continue) { c.FuzzNoCustom(s) // fuzz self without calling this function again @@ -742,7 +743,7 @@ func policyFuncs(t apitesting.TestingCommon) []interface{} { } } -func certificateFuncs(t apitesting.TestingCommon) []interface{} { +func certificateFuncs(codecs runtimeserializer.CodecFactory) []interface{} { return []interface{}{ func(obj *certificates.CertificateSigningRequestSpec, c fuzz.Continue) { c.FuzzNoCustom(obj) // fuzz self without calling this function again @@ -751,7 +752,7 @@ func certificateFuncs(t apitesting.TestingCommon) []interface{} { } } -func admissionregistrationFuncs(t apitesting.TestingCommon) []interface{} { +func admissionregistrationFuncs(codecs runtimeserializer.CodecFactory) []interface{} { return []interface{}{ func(obj *admissionregistration.ExternalAdmissionHook, c fuzz.Continue) { c.FuzzNoCustom(obj) // fuzz self without calling this function again @@ -766,22 +767,20 @@ func admissionregistrationFuncs(t apitesting.TestingCommon) []interface{} { } } -func FuzzerFuncs(t apitesting.TestingCommon, codecs runtimeserializer.CodecFactory) []interface{} { - return apitesting.MergeFuzzerFuncs(t, - apitesting.GenericFuzzerFuncs(t, codecs), - overrideGenericFuncs(t, codecs), - coreFuncs(t), - extensionFuncs(t), - appsFuncs(t), - batchFuncs(t), - autoscalingFuncs(t), - rbacFuncs(t), - kubeadmfuzzer.KubeadmFuzzerFuncs(t), - policyFuncs(t), - certificateFuncs(t), - admissionregistrationFuncs(t), - ) -} +var FuzzerFuncs = fuzzer.MergeFuzzerFuncs( + genericfuzzer.Funcs, + overrideGenericFuncs, + coreFuncs, + extensionFuncs, + appsFuncs, + batchFuncs, + autoscalingFuncs, + rbacFuncs, + kubeadmfuzzer.Funcs, + policyFuncs, + certificateFuncs, + admissionregistrationFuncs, +) func newBool(val bool) *bool { p := new(bool) diff --git a/pkg/api/unstructured_test.go b/pkg/api/unstructured_test.go index 1351ea861ec..9616d822a7b 100644 --- a/pkg/api/unstructured_test.go +++ b/pkg/api/unstructured_test.go @@ -21,19 +21,18 @@ import ( "reflect" "testing" + "github.com/google/gofuzz" + "k8s.io/api/core/v1" apiequality "k8s.io/apimachinery/pkg/api/equality" - apitesting "k8s.io/apimachinery/pkg/api/testing" - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/api/testapi" - kapitesting "k8s.io/kubernetes/pkg/api/testing" - + "k8s.io/apimachinery/pkg/api/testing/fuzzer" "k8s.io/apimachinery/pkg/conversion/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/diff" "k8s.io/apimachinery/pkg/util/json" - - "github.com/google/gofuzz" + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/testapi" + kapitesting "k8s.io/kubernetes/pkg/api/testing" ) func doRoundTrip(t *testing.T, group testapi.TestGroup, kind string) { @@ -45,7 +44,7 @@ func doRoundTrip(t *testing.T, group testapi.TestGroup, kind string) { t.Fatalf("Couldn't create internal object %v: %v", kind, err) } seed := rand.Int63() - apitesting.FuzzerFor(kapitesting.FuzzerFuncs(t, api.Codecs), rand.NewSource(seed)). + fuzzer.FuzzerFor(kapitesting.FuzzerFuncs, rand.NewSource(seed), api.Codecs). // We are explicitly overwriting custom fuzzing functions, to ensure // that InitContainers and their statuses are not generated. This is // because in thise test we are simply doing json operations, in which diff --git a/pkg/api/validation/BUILD b/pkg/api/validation/BUILD index ec08480a1ec..b4b2ed17549 100644 --- a/pkg/api/validation/BUILD +++ b/pkg/api/validation/BUILD @@ -79,7 +79,7 @@ go_test( "//vendor/k8s.io/api/core/v1:go_default_library", "//vendor/k8s.io/api/extensions/v1beta1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/api/testing:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/api/testing/fuzzer:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/intstr:go_default_library", diff --git a/pkg/api/validation/schema_test.go b/pkg/api/validation/schema_test.go index ad5daee69ac..39090bcd712 100644 --- a/pkg/api/validation/schema_test.go +++ b/pkg/api/validation/schema_test.go @@ -24,16 +24,16 @@ import ( "strings" "testing" + "github.com/ghodss/yaml" + "k8s.io/api/core/v1" "k8s.io/api/extensions/v1beta1" - apitesting "k8s.io/apimachinery/pkg/api/testing" + "k8s.io/apimachinery/pkg/api/testing/fuzzer" "k8s.io/apimachinery/pkg/runtime" k8syaml "k8s.io/apimachinery/pkg/util/yaml" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/testapi" kapitesting "k8s.io/kubernetes/pkg/api/testing" - - "github.com/ghodss/yaml" ) func readPod(filename string) ([]byte, error) { @@ -146,7 +146,7 @@ func TestValidateOk(t *testing.T) { } seed := rand.Int63() - apiObjectFuzzer := apitesting.FuzzerFor(kapitesting.FuzzerFuncs(t, api.Codecs), rand.NewSource(seed)) + apiObjectFuzzer := fuzzer.FuzzerFor(kapitesting.FuzzerFuncs, rand.NewSource(seed), api.Codecs) for i := 0; i < 5; i++ { for _, test := range tests { testObj := test.obj diff --git a/staging/src/k8s.io/apiextensions-apiserver/examples/client-go/apis/cr/v1/BUILD b/staging/src/k8s.io/apiextensions-apiserver/examples/client-go/apis/cr/v1/BUILD index d8595828255..a3c0080ee0d 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/examples/client-go/apis/cr/v1/BUILD +++ b/staging/src/k8s.io/apiextensions-apiserver/examples/client-go/apis/cr/v1/BUILD @@ -10,12 +10,14 @@ load( go_test( name = "go_default_test", - srcs = ["types_test.go"], + srcs = ["roundtrip_test.go"], library = ":go_default_library", tags = ["automanaged"], deps = [ "//vendor/github.com/google/gofuzz:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/api/testing:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/api/testing/fuzzer:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/api/testing/roundtrip:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/apis/meta/fuzzer:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library", diff --git a/staging/src/k8s.io/apiextensions-apiserver/examples/client-go/apis/cr/v1/types_test.go b/staging/src/k8s.io/apiextensions-apiserver/examples/client-go/apis/cr/v1/roundtrip_test.go similarity index 68% rename from staging/src/k8s.io/apiextensions-apiserver/examples/client-go/apis/cr/v1/types_test.go rename to staging/src/k8s.io/apiextensions-apiserver/examples/client-go/apis/cr/v1/roundtrip_test.go index 38f612d8907..7373c78b588 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/examples/client-go/apis/cr/v1/types_test.go +++ b/staging/src/k8s.io/apiextensions-apiserver/examples/client-go/apis/cr/v1/roundtrip_test.go @@ -22,10 +22,13 @@ import ( "github.com/google/gofuzz" - apitesting "k8s.io/apimachinery/pkg/api/testing" + "k8s.io/apimachinery/pkg/api/testing/fuzzer" + roundtrip "k8s.io/apimachinery/pkg/api/testing/roundtrip" + metafuzzer "k8s.io/apimachinery/pkg/apis/meta/fuzzer" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/serializer" + runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" ) var _ runtime.Object = &Example{} @@ -34,7 +37,7 @@ var _ metav1.ObjectMetaAccessor = &Example{} var _ runtime.Object = &ExampleList{} var _ metav1.ListMetaAccessor = &ExampleList{} -func exampleFuzzerFuncs(t apitesting.TestingCommon) []interface{} { +func exampleFuzzerFuncs(codecs runtimeserializer.CodecFactory) []interface{} { return []interface{}{ func(obj *ExampleList, c fuzz.Continue) { c.FuzzNoCustom(obj) @@ -55,9 +58,9 @@ func TestRoundTrip(t *testing.T) { AddToScheme(scheme) seed := rand.Int63() - fuzzerFuncs := apitesting.MergeFuzzerFuncs(t, apitesting.GenericFuzzerFuncs(t, codecs), exampleFuzzerFuncs(t)) - fuzzer := apitesting.FuzzerFor(fuzzerFuncs, rand.NewSource(seed)) + fuzzerFuncs := fuzzer.MergeFuzzerFuncs(metafuzzer.Funcs, exampleFuzzerFuncs) + fuzzer := fuzzer.FuzzerFor(fuzzerFuncs, rand.NewSource(seed), codecs) - apitesting.RoundTripSpecificKindWithoutProtobuf(t, SchemeGroupVersion.WithKind("Example"), scheme, codecs, fuzzer, nil) - apitesting.RoundTripSpecificKindWithoutProtobuf(t, SchemeGroupVersion.WithKind("ExampleList"), scheme, codecs, fuzzer, nil) + roundtrip.RoundTripSpecificKindWithoutProtobuf(t, SchemeGroupVersion.WithKind("Example"), scheme, codecs, fuzzer, nil) + roundtrip.RoundTripSpecificKindWithoutProtobuf(t, SchemeGroupVersion.WithKind("ExampleList"), scheme, codecs, fuzzer, nil) } diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/fuzzer/BUILD b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/fuzzer/BUILD new file mode 100644 index 00000000000..6d56c86e035 --- /dev/null +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/fuzzer/BUILD @@ -0,0 +1,19 @@ +package(default_visibility = ["//visibility:public"]) + +licenses(["notice"]) + +load( + "@io_bazel_rules_go//go:def.bzl", + "go_library", +) + +go_library( + name = "go_default_library", + srcs = ["fuzzer.go"], + tags = ["automanaged"], + deps = [ + "//vendor/github.com/google/gofuzz:go_default_library", + "//vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library", + ], +) diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/install/install_test.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/fuzzer/fuzzer.go similarity index 81% rename from staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/install/install_test.go rename to staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/fuzzer/fuzzer.go index 351787932ef..705fc0bd7a1 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/install/install_test.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/fuzzer/fuzzer.go @@ -14,25 +14,19 @@ See the License for the specific language governing permissions and limitations under the License. */ -package install +package fuzzer import ( "strings" - "testing" "github.com/google/gofuzz" "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions" - apitesting "k8s.io/apimachinery/pkg/api/testing" + runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" ) -func TestRoundTripTypes(t *testing.T) { - apitesting.RoundTripTestForAPIGroup(t, Install, apitesting.MergeFuzzerFuncs(t, - fuzzerFuncs(), - )) -} - -func fuzzerFuncs() []interface{} { +// Funcs returns the fuzzer functions for the apiextensions apis. +func Funcs(codecs runtimeserializer.CodecFactory) []interface{} { return []interface{}{ func(obj *apiextensions.CustomResourceDefinitionSpec, c fuzz.Continue) { c.FuzzNoCustom(obj) diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/install/BUILD b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/install/BUILD index be3f73993e2..5ff460d5200 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/install/BUILD +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/install/BUILD @@ -10,13 +10,12 @@ load( go_test( name = "go_default_test", - srcs = ["install_test.go"], + srcs = ["roundtrip_test.go"], library = ":go_default_library", tags = ["automanaged"], deps = [ - "//vendor/github.com/google/gofuzz:go_default_library", - "//vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/api/testing:go_default_library", + "//vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/fuzzer:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/api/testing/roundtrip:go_default_library", ], ) diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/install/roundtrip_test.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/install/roundtrip_test.go new file mode 100644 index 00000000000..353e81287ce --- /dev/null +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/install/roundtrip_test.go @@ -0,0 +1,28 @@ +/* +Copyright 2017 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 install + +import ( + "testing" + + apiextensionsfuzzer "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/fuzzer" + "k8s.io/apimachinery/pkg/api/testing/roundtrip" +) + +func TestRoundTrip(t *testing.T) { + roundtrip.RoundTripTestForAPIGroup(t, Install, apiextensionsfuzzer.Funcs) +} diff --git a/staging/src/k8s.io/apimachinery/pkg/api/testing/BUILD b/staging/src/k8s.io/apimachinery/pkg/api/testing/BUILD index 657cc57a917..cfd0561b3b0 100644 --- a/staging/src/k8s.io/apimachinery/pkg/api/testing/BUILD +++ b/staging/src/k8s.io/apimachinery/pkg/api/testing/BUILD @@ -5,44 +5,16 @@ licenses(["notice"]) load( "@io_bazel_rules_go//go:def.bzl", "go_library", - "go_test", -) - -go_test( - name = "go_default_test", - srcs = ["valuefuzz_test.go"], - library = ":go_default_library", - tags = ["automanaged"], ) go_library( name = "go_default_library", - srcs = [ - "codec.go", - "fuzzer.go", - "roundtrip.go", - "valuefuzz.go", - ], + srcs = ["codec.go"], tags = ["automanaged"], deps = [ - "//vendor/github.com/davecgh/go-spew/spew:go_default_library", - "//vendor/github.com/golang/protobuf/proto:go_default_library", - "//vendor/github.com/google/gofuzz:go_default_library", - "//vendor/github.com/spf13/pflag:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/api/equality:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/apimachinery/announced:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/apimachinery/registered:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/runtime/serializer/json:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime/serializer/recognizer:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/types:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/util/diff:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library", ], ) diff --git a/staging/src/k8s.io/apimachinery/pkg/api/testing/fuzzer/BUILD b/staging/src/k8s.io/apimachinery/pkg/api/testing/fuzzer/BUILD new file mode 100644 index 00000000000..56c035a3b72 --- /dev/null +++ b/staging/src/k8s.io/apimachinery/pkg/api/testing/fuzzer/BUILD @@ -0,0 +1,29 @@ +package(default_visibility = ["//visibility:public"]) + +licenses(["notice"]) + +load( + "@io_bazel_rules_go//go:def.bzl", + "go_library", + "go_test", +) + +go_test( + name = "go_default_test", + srcs = ["valuefuzz_test.go"], + library = ":go_default_library", + tags = ["automanaged"], +) + +go_library( + name = "go_default_library", + srcs = [ + "fuzzer.go", + "valuefuzz.go", + ], + tags = ["automanaged"], + deps = [ + "//vendor/github.com/google/gofuzz:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library", + ], +) diff --git a/staging/src/k8s.io/apimachinery/pkg/api/testing/fuzzer/fuzzer.go b/staging/src/k8s.io/apimachinery/pkg/api/testing/fuzzer/fuzzer.go new file mode 100644 index 00000000000..f528e9f92de --- /dev/null +++ b/staging/src/k8s.io/apimachinery/pkg/api/testing/fuzzer/fuzzer.go @@ -0,0 +1,52 @@ +/* +Copyright 2017 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 fuzzer + +import ( + "math/rand" + + "github.com/google/gofuzz" + + runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" +) + +// FuzzerFuncs returns a list of func(*SomeType, c fuzz.Continue) functions. +type FuzzerFuncs func(codecs runtimeserializer.CodecFactory) []interface{} + +// FuzzerFor can randomly populate api objects that are destined for version. +func FuzzerFor(funcs FuzzerFuncs, src rand.Source, codecs runtimeserializer.CodecFactory) *fuzz.Fuzzer { + f := fuzz.New().NilChance(.5).NumElements(0, 1) + if src != nil { + f.RandSource(src) + } + f.Funcs(funcs(codecs)...) + return f +} + +// MergeFuzzerFuncs will merge the given funcLists, overriding early funcs with later ones if there first +// argument has the same type. +func MergeFuzzerFuncs(funcs ...FuzzerFuncs) FuzzerFuncs { + return FuzzerFuncs(func(codecs runtimeserializer.CodecFactory) []interface{} { + result := []interface{}{} + for _, f := range funcs { + if f != nil { + result = append(result, f(codecs)...) + } + } + return result + }) +} diff --git a/staging/src/k8s.io/apimachinery/pkg/api/testing/valuefuzz.go b/staging/src/k8s.io/apimachinery/pkg/api/testing/fuzzer/valuefuzz.go similarity index 99% rename from staging/src/k8s.io/apimachinery/pkg/api/testing/valuefuzz.go rename to staging/src/k8s.io/apimachinery/pkg/api/testing/fuzzer/valuefuzz.go index 4cb03b7b0de..cd71c517da3 100644 --- a/staging/src/k8s.io/apimachinery/pkg/api/testing/valuefuzz.go +++ b/staging/src/k8s.io/apimachinery/pkg/api/testing/fuzzer/valuefuzz.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package testing +package fuzzer import ( "reflect" diff --git a/staging/src/k8s.io/apimachinery/pkg/api/testing/valuefuzz_test.go b/staging/src/k8s.io/apimachinery/pkg/api/testing/fuzzer/valuefuzz_test.go similarity index 98% rename from staging/src/k8s.io/apimachinery/pkg/api/testing/valuefuzz_test.go rename to staging/src/k8s.io/apimachinery/pkg/api/testing/fuzzer/valuefuzz_test.go index 07dca80227d..a935aa40c7e 100644 --- a/staging/src/k8s.io/apimachinery/pkg/api/testing/valuefuzz_test.go +++ b/staging/src/k8s.io/apimachinery/pkg/api/testing/fuzzer/valuefuzz_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package testing +package fuzzer import "testing" diff --git a/staging/src/k8s.io/apimachinery/pkg/api/testing/roundtrip/BUILD b/staging/src/k8s.io/apimachinery/pkg/api/testing/roundtrip/BUILD new file mode 100644 index 00000000000..318d634947e --- /dev/null +++ b/staging/src/k8s.io/apimachinery/pkg/api/testing/roundtrip/BUILD @@ -0,0 +1,34 @@ +package(default_visibility = ["//visibility:public"]) + +licenses(["notice"]) + +load( + "@io_bazel_rules_go//go:def.bzl", + "go_library", +) + +go_library( + name = "go_default_library", + srcs = ["roundtrip.go"], + tags = ["automanaged"], + deps = [ + "//vendor/github.com/davecgh/go-spew/spew:go_default_library", + "//vendor/github.com/golang/protobuf/proto:go_default_library", + "//vendor/github.com/google/gofuzz:go_default_library", + "//vendor/github.com/spf13/pflag:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/api/equality:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/api/testing:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/api/testing/fuzzer:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/apimachinery/announced:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/apimachinery/registered:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/apis/meta/fuzzer:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/runtime/serializer/json:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/util/diff:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library", + ], +) diff --git a/staging/src/k8s.io/apimachinery/pkg/api/testing/roundtrip.go b/staging/src/k8s.io/apimachinery/pkg/api/testing/roundtrip/roundtrip.go similarity index 81% rename from staging/src/k8s.io/apimachinery/pkg/api/testing/roundtrip.go rename to staging/src/k8s.io/apimachinery/pkg/api/testing/roundtrip/roundtrip.go index b3070599156..1d452aa8047 100644 --- a/staging/src/k8s.io/apimachinery/pkg/api/testing/roundtrip.go +++ b/staging/src/k8s.io/apimachinery/pkg/api/testing/roundtrip/roundtrip.go @@ -14,12 +14,13 @@ See the License for the specific language governing permissions and limitations under the License. */ -package testing +package roundtrip import ( "bytes" "encoding/hex" "fmt" + "math/rand" "reflect" "strings" "testing" @@ -28,16 +29,19 @@ import ( "github.com/golang/protobuf/proto" "github.com/google/gofuzz" flag "github.com/spf13/pflag" - "k8s.io/apimachinery/pkg/runtime/serializer/protobuf" apiequality "k8s.io/apimachinery/pkg/api/equality" - "k8s.io/apimachinery/pkg/api/meta" + apimeta "k8s.io/apimachinery/pkg/api/meta" + apitesting "k8s.io/apimachinery/pkg/api/testing" + "k8s.io/apimachinery/pkg/api/testing/fuzzer" "k8s.io/apimachinery/pkg/apimachinery/announced" "k8s.io/apimachinery/pkg/apimachinery/registered" + metafuzzer "k8s.io/apimachinery/pkg/apis/meta/fuzzer" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" "k8s.io/apimachinery/pkg/runtime/serializer/json" + "k8s.io/apimachinery/pkg/runtime/serializer/protobuf" "k8s.io/apimachinery/pkg/util/diff" "k8s.io/apimachinery/pkg/util/sets" ) @@ -46,7 +50,7 @@ type InstallFunc func(groupFactoryRegistry announced.APIGroupFactoryRegistry, re // RoundTripTestForAPIGroup is convenient to call from your install package to make sure that a "bare" install of your group provides // enough information to round trip -func RoundTripTestForAPIGroup(t *testing.T, installFn InstallFunc, fuzzingFuncs []interface{}) { +func RoundTripTestForAPIGroup(t *testing.T, installFn InstallFunc, fuzzingFuncs fuzzer.FuzzerFuncs) { groupFactoryRegistry := make(announced.APIGroupFactoryRegistry) registry := registered.NewOrDie("") scheme := runtime.NewScheme() @@ -56,15 +60,19 @@ func RoundTripTestForAPIGroup(t *testing.T, installFn InstallFunc, fuzzingFuncs } // RoundTripTestForScheme is convenient to call if you already have a scheme and want to make sure that its well-formed -func RoundTripTestForScheme(t *testing.T, scheme *runtime.Scheme, fuzzingFuncs []interface{}) { +func RoundTripTestForScheme(t *testing.T, scheme *runtime.Scheme, fuzzingFuncs fuzzer.FuzzerFuncs) { codecFactory := runtimeserializer.NewCodecFactory(scheme) - fuzzer := DefaultFuzzers(t, codecFactory, fuzzingFuncs) - RoundTripTypesWithoutProtobuf(t, scheme, codecFactory, fuzzer, nil) + f := fuzzer.FuzzerFor( + fuzzer.MergeFuzzerFuncs(metafuzzer.Funcs, fuzzingFuncs), + rand.NewSource(rand.Int63()), + codecFactory, + ) + RoundTripTypesWithoutProtobuf(t, scheme, codecFactory, f, nil) } // RoundTripProtobufTestForAPIGroup is convenient to call from your install package to make sure that a "bare" install of your group provides // enough information to round trip -func RoundTripProtobufTestForAPIGroup(t *testing.T, installFn InstallFunc, fuzzingFuncs []interface{}) { +func RoundTripProtobufTestForAPIGroup(t *testing.T, installFn InstallFunc, fuzzingFuncs fuzzer.FuzzerFuncs) { groupFactoryRegistry := make(announced.APIGroupFactoryRegistry) registry := registered.NewOrDie("") scheme := runtime.NewScheme() @@ -74,9 +82,13 @@ func RoundTripProtobufTestForAPIGroup(t *testing.T, installFn InstallFunc, fuzzi } // RoundTripProtobufTestForScheme is convenient to call if you already have a scheme and want to make sure that its well-formed -func RoundTripProtobufTestForScheme(t *testing.T, scheme *runtime.Scheme, fuzzingFuncs []interface{}) { +func RoundTripProtobufTestForScheme(t *testing.T, scheme *runtime.Scheme, fuzzingFuncs fuzzer.FuzzerFuncs) { codecFactory := runtimeserializer.NewCodecFactory(scheme) - fuzzer := DefaultFuzzers(t, codecFactory, fuzzingFuncs) + fuzzer := fuzzer.FuzzerFor( + fuzzer.MergeFuzzerFuncs(metafuzzer.Funcs, fuzzingFuncs), + rand.NewSource(rand.Int63()), + codecFactory, + ) RoundTripTypes(t, scheme, codecFactory, fuzzer, nil) } @@ -160,7 +172,7 @@ func roundTripSpecificKind(t *testing.T, gvk schema.GroupVersionKind, scheme *ru func fuzzInternalObject(t *testing.T, fuzzer *fuzz.Fuzzer, object runtime.Object) runtime.Object { fuzzer.Fuzz(object) - j, err := meta.TypeAccessor(object) + j, err := apimeta.TypeAccessor(object) if err != nil { t.Fatalf("Unexpected error %v for %#v", err, object) } @@ -183,7 +195,7 @@ func roundTripToAllExternalVersions(t *testing.T, scheme *runtime.Scheme, codecF if err != nil { t.Fatalf("Couldn't make a %v? %v", internalGVK, err) } - if _, err := meta.TypeAccessor(object); err != nil { + if _, err := apimeta.TypeAccessor(object); err != nil { t.Fatalf("%q is not a TypeMeta and cannot be tested - add it to nonRoundTrippableInternalTypes: %v", internalGVK, err) } @@ -204,7 +216,7 @@ func roundTripToAllExternalVersions(t *testing.T, scheme *runtime.Scheme, codecF } t.Logf("\tround tripping to %v %v", externalGVK, externalGoType) - roundTrip(t, scheme, TestCodec(codecFactory, externalGVK.GroupVersion()), object) + roundTrip(t, scheme, apitesting.TestCodec(codecFactory, externalGVK.GroupVersion()), object) // TODO remove this hack after we're past the intermediate steps if !skipProtobuf && externalGVK.Group != "kubeadm.k8s.io" { @@ -220,7 +232,7 @@ func roundTripOfExternalType(t *testing.T, scheme *runtime.Scheme, codecFactory if err != nil { t.Fatalf("Couldn't make a %v? %v", externalGVK, err) } - typeAcc, err := meta.TypeAccessor(object) + typeAcc, err := apimeta.TypeAccessor(object) if err != nil { t.Fatalf("%q is not a TypeMeta and cannot be tested - add it to nonRoundTrippableInternalTypes: %v", externalGVK, err) } @@ -279,7 +291,7 @@ func roundTrip(t *testing.T, scheme *runtime.Scheme, codec runtime.Codec, object // copy or conversion should alter the object // TODO eliminate this global if !apiequality.Semantic.DeepEqual(original, object) { - t.Errorf("0: %v: encode altered the object, diff: %v", name, diff.ObjectReflectDiff(original, object)) + t.Errorf("%v: encode altered the object, diff: %v", name, diff.ObjectReflectDiff(original, object)) return } @@ -303,14 +315,14 @@ func roundTrip(t *testing.T, scheme *runtime.Scheme, codec runtime.Codec, object // decode (deserialize) the encoded data back into an object obj2, err := runtime.Decode(codec, data) if err != nil { - t.Errorf("0: %v: %v\nCodec: %#v\nData: %s\nSource: %#v", name, err, codec, dataAsString(data), printer.Sprintf("%#v", object)) + t.Errorf("%v: %v\nCodec: %#v\nData: %s\nSource: %#v", name, err, codec, dataAsString(data), printer.Sprintf("%#v", object)) panic("failed") } // ensure that the object produced from decoding the encoded data is equal // to the original object if !apiequality.Semantic.DeepEqual(original, obj2) { - t.Errorf("1: %v: diff: %v\nCodec: %#v\nSource:\n\n%#v\n\nEncoded:\n\n%s\n\nFinal:\n\n%#v", name, diff.ObjectReflectDiff(object, obj2), codec, printer.Sprintf("%#v", object), dataAsString(data), printer.Sprintf("%#v", obj2)) + t.Errorf("%v: diff: %v\nCodec: %#v\nSource:\n\n%#v\n\nEncoded:\n\n%s\n\nFinal:\n\n%#v", name, diff.ObjectReflectDiff(object, obj2), codec, printer.Sprintf("%#v", object), dataAsString(data), printer.Sprintf("%#v", obj2)) return } @@ -318,27 +330,66 @@ func roundTrip(t *testing.T, scheme *runtime.Scheme, codec runtime.Codec, object // create a new object) obj3 := reflect.New(reflect.TypeOf(object).Elem()).Interface().(runtime.Object) if err := runtime.DecodeInto(codec, data, obj3); err != nil { - t.Errorf("2: %v: %v", name, err) + t.Errorf("%v: %v", name, err) return } + // special case for kinds which are internal and external at the same time (many in meta.k8s.io are). For those + // runtime.DecodeInto above will return the external variant and set the APIVersion and kind, while the input + // object might be internal. Hence, we clear those values for obj3 for that case to correctly compare. + intAndExt, err := internalAndExternalKind(scheme, object) + if err != nil { + t.Errorf("%v: %v", name, err) + return + } + if intAndExt { + typeAcc, err := apimeta.TypeAccessor(object) + if err != nil { + t.Fatalf("%v: error accessing TypeMeta: %v", name, err) + } + if len(typeAcc.GetAPIVersion()) == 0 { + typeAcc, err := apimeta.TypeAccessor(obj3) + if err != nil { + t.Fatalf("%v: error accessing TypeMeta: %v", name, err) + } + typeAcc.SetAPIVersion("") + typeAcc.SetKind("") + } + } + // ensure that the new runtime object is equal to the original after being // decoded into if !apiequality.Semantic.DeepEqual(object, obj3) { - t.Errorf("3: %v: diff: %v\nCodec: %#v", name, diff.ObjectReflectDiff(object, obj3), codec) + t.Errorf("%v: diff: %v\nCodec: %#v", name, diff.ObjectReflectDiff(object, obj3), codec) return } // do structure-preserving fuzzing of the deep-copied object. If it shares anything with the original, // the deep-copy was actually only a shallow copy. Then original and obj3 will be different after fuzzing. // NOTE: we use the encoding+decoding here as an alternative, guaranteed deep-copy to compare against. - ValueFuzz(object) + fuzzer.ValueFuzz(object) if !apiequality.Semantic.DeepEqual(original, obj3) { - t.Errorf("0: %v: fuzzing a copy altered the original, diff: %v", name, diff.ObjectReflectDiff(original, object)) + t.Errorf("%v: fuzzing a copy altered the original, diff: %v", name, diff.ObjectReflectDiff(original, object)) return } } +func internalAndExternalKind(scheme *runtime.Scheme, object runtime.Object) (bool, error) { + kinds, _, err := scheme.ObjectKinds(object) + if err != nil { + return false, err + } + internal, external := false, false + for _, k := range kinds { + if k.Version == runtime.APIVersionInternal { + internal = true + } else { + external = true + } + } + return internal && external, nil +} + // dataAsString returns the given byte array as a string; handles detecting // protocol buffers. func dataAsString(data []byte) string { diff --git a/staging/src/k8s.io/apimachinery/pkg/apis/meta/fuzzer/BUILD b/staging/src/k8s.io/apimachinery/pkg/apis/meta/fuzzer/BUILD new file mode 100644 index 00000000000..aeebaf535d6 --- /dev/null +++ b/staging/src/k8s.io/apimachinery/pkg/apis/meta/fuzzer/BUILD @@ -0,0 +1,25 @@ +package(default_visibility = ["//visibility:public"]) + +licenses(["notice"]) + +load( + "@io_bazel_rules_go//go:def.bzl", + "go_library", +) + +go_library( + name = "go_default_library", + srcs = ["fuzzer.go"], + tags = ["automanaged"], + deps = [ + "//vendor/github.com/google/gofuzz:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/api/testing:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/api/testing/fuzzer:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1alpha1:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/types:go_default_library", + ], +) diff --git a/staging/src/k8s.io/apimachinery/pkg/api/testing/fuzzer.go b/staging/src/k8s.io/apimachinery/pkg/apis/meta/fuzzer/fuzzer.go similarity index 64% rename from staging/src/k8s.io/apimachinery/pkg/api/testing/fuzzer.go rename to staging/src/k8s.io/apimachinery/pkg/apis/meta/fuzzer/fuzzer.go index 7655908d85d..632fae2cfcb 100644 --- a/staging/src/k8s.io/apimachinery/pkg/api/testing/fuzzer.go +++ b/staging/src/k8s.io/apimachinery/pkg/apis/meta/fuzzer/fuzzer.go @@ -14,24 +14,25 @@ See the License for the specific language governing permissions and limitations under the License. */ -package testing +package fuzzer import ( - "math/rand" - "reflect" + "fmt" "strconv" - "testing" "github.com/google/gofuzz" "k8s.io/apimachinery/pkg/api/resource" + apitesting "k8s.io/apimachinery/pkg/api/testing" + "k8s.io/apimachinery/pkg/api/testing/fuzzer" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + metav1alpha1 "k8s.io/apimachinery/pkg/apis/meta/v1alpha1" "k8s.io/apimachinery/pkg/runtime" runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" "k8s.io/apimachinery/pkg/types" ) -func GenericFuzzerFuncs(t TestingCommon, codecs runtimeserializer.CodecFactory) []interface{} { +func genericFuzzerFuncs(codecs runtimeserializer.CodecFactory) []interface{} { return []interface{}{ func(q *resource.Quantity, c fuzz.Continue) { *q = *resource.NewQuantity(c.Int63n(1000), resource.DecimalExponent) @@ -53,28 +54,6 @@ func GenericFuzzerFuncs(t TestingCommon, codecs runtimeserializer.CodecFactory) j.APIVersion = "" j.Kind = "" }, - func(j *metav1.TypeMeta, c fuzz.Continue) { - // We have to customize the randomization of TypeMetas because their - // APIVersion and Kind must remain blank in memory. - j.APIVersion = "" - j.Kind = "" - }, - func(j *metav1.ObjectMeta, c fuzz.Continue) { - j.Name = c.RandString() - j.ResourceVersion = strconv.FormatUint(c.RandUint64(), 10) - j.SelfLink = c.RandString() - j.UID = types.UID(c.RandString()) - j.GenerateName = c.RandString() - - var sec, nsec int64 - c.Fuzz(&sec) - c.Fuzz(&nsec) - j.CreationTimestamp = metav1.Unix(sec, nsec).Rfc3339Copy() - }, - func(j *metav1.ListMeta, c fuzz.Continue) { - j.ResourceVersion = strconv.FormatUint(c.RandUint64(), 10) - j.SelfLink = c.RandString() - }, func(j *runtime.Object, c fuzz.Continue) { // TODO: uncomment when round trip starts from a versioned object if true { //c.RandBool() { @@ -98,77 +77,100 @@ func GenericFuzzerFuncs(t TestingCommon, codecs runtimeserializer.CodecFactory) // Find a codec for converting the object to raw bytes. This is necessary for the // api version and kind to be correctly set be serialization. - var codec = TestCodec(codecs, metav1.SchemeGroupVersion) + var codec = apitesting.TestCodec(codecs, metav1.SchemeGroupVersion) // Convert the object to raw bytes bytes, err := runtime.Encode(codec, obj) if err != nil { - t.Errorf("Failed to encode object: %v", err) + panic(fmt.Sprintf("Failed to encode object: %v", err)) return } + // strip trailing newlines which do not survive roundtrips + for len(bytes) >= 1 && bytes[len(bytes)-1] == 10 { + bytes = bytes[:len(bytes)-1] + } + // Set the bytes field on the RawExtension r.Raw = bytes }, } } -// TestingCommon abstracts testing.T and testing.B -type TestingCommon interface { - Log(args ...interface{}) - Logf(format string, args ...interface{}) - Error(args ...interface{}) - Errorf(format string, args ...interface{}) - Fatal(args ...interface{}) - Fatalf(format string, args ...interface{}) -} +func v1FuzzerFuncs(codecs runtimeserializer.CodecFactory) []interface{} { + return []interface{}{ + func(j *metav1.TypeMeta, c fuzz.Continue) { + // We have to customize the randomization of TypeMetas because their + // APIVersion and Kind must remain blank in memory. + j.APIVersion = "" + j.Kind = "" + }, + func(j *metav1.ObjectMeta, c fuzz.Continue) { + j.Name = c.RandString() + j.ResourceVersion = strconv.FormatUint(c.RandUint64(), 10) + j.SelfLink = c.RandString() + j.UID = types.UID(c.RandString()) + j.GenerateName = c.RandString() -var ( - _ TestingCommon = &testing.T{} - _ TestingCommon = &testing.B{} -) - -// FuzzerFor can randomly populate api objects that are destined for version. -func FuzzerFor(funcs []interface{}, src rand.Source) *fuzz.Fuzzer { - f := fuzz.New().NilChance(.5).NumElements(0, 1) - if src != nil { - f.RandSource(src) + var sec, nsec int64 + c.Fuzz(&sec) + c.Fuzz(&nsec) + j.CreationTimestamp = metav1.Unix(sec, nsec).Rfc3339Copy() + }, + func(j *metav1.ListMeta, c fuzz.Continue) { + j.ResourceVersion = strconv.FormatUint(c.RandUint64(), 10) + j.SelfLink = c.RandString() + }, } - f.Funcs(funcs...) - return f } -// MergeFuzzerFuncs will merge the given funcLists, overriding early funcs with later ones if there first -// argument has the same type. -func MergeFuzzerFuncs(t TestingCommon, funcLists ...[]interface{}) []interface{} { - funcMap := map[string]interface{}{} - for _, list := range funcLists { - for _, f := range list { - fT := reflect.TypeOf(f) - if fT.Kind() != reflect.Func || fT.NumIn() != 2 { - t.Errorf("Fuzzer func with invalid type: %v", fT) - continue +func v1alpha1FuzzerFuncs(codecs runtimeserializer.CodecFactory) []interface{} { + return []interface{}{ + func(r *metav1alpha1.TableRow, c fuzz.Continue) { + c.Fuzz(&r.Object) + c.Fuzz(&r.Conditions) + if len(r.Conditions) == 0 { + r.Conditions = nil } - funcMap[fT.In(0).String()] = f - } + n := c.Intn(10) + if n > 0 { + r.Cells = make([]interface{}, n) + } + for i := range r.Cells { + t := c.Intn(6) + switch t { + case 0: + r.Cells[i] = c.RandString() + case 1: + r.Cells[i] = c.Uint64() + case 2: + r.Cells[i] = c.RandBool() + case 3: + // maps roundtrip as map[interface{}]interface{}, but the json codec cannot encode that + // TODO: get maps to roundtrip properly + /* + x := map[string]interface{}{} + for j := c.Intn(10) + 1; j >= 0; j-- { + x[c.RandString()] = c.RandString() + } + r.Cells[i] = x + */ + case 4: + x := make([]interface{}, c.Intn(10)) + for i := range x { + x[i] = c.Uint64() + } + r.Cells[i] = x + default: + r.Cells[i] = nil + } + } + }, } - - result := []interface{}{} - for _, f := range funcMap { - result = append(result, f) - } - return result } -func DefaultFuzzers(t TestingCommon, codecFactory runtimeserializer.CodecFactory, fuzzerFuncs []interface{}) *fuzz.Fuzzer { - seed := rand.Int63() - - return FuzzerFor( - MergeFuzzerFuncs(t, - GenericFuzzerFuncs(t, codecFactory), - fuzzerFuncs, - ), - rand.NewSource(seed), - ) - -} +var Funcs = fuzzer.MergeFuzzerFuncs( + genericFuzzerFuncs, + v1FuzzerFuncs, + v1alpha1FuzzerFuncs, +) diff --git a/staging/src/k8s.io/apimachinery/pkg/apis/meta/internalversion/BUILD b/staging/src/k8s.io/apimachinery/pkg/apis/meta/internalversion/BUILD index f9c8d882618..7a84a4d13c7 100644 --- a/staging/src/k8s.io/apimachinery/pkg/apis/meta/internalversion/BUILD +++ b/staging/src/k8s.io/apimachinery/pkg/apis/meta/internalversion/BUILD @@ -10,10 +10,15 @@ load( go_test( name = "go_default_test", - srcs = ["register_test.go"], + srcs = [ + "register_test.go", + "roundtrip_test.go", + ], library = ":go_default_library", tags = ["automanaged"], deps = [ + "//vendor/k8s.io/apimachinery/pkg/api/testing/roundtrip:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/apis/meta/fuzzer:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/diff:go_default_library", ], diff --git a/staging/src/k8s.io/apimachinery/pkg/apis/meta/internalversion/roundtrip_test.go b/staging/src/k8s.io/apimachinery/pkg/apis/meta/internalversion/roundtrip_test.go new file mode 100644 index 00000000000..725aa316d06 --- /dev/null +++ b/staging/src/k8s.io/apimachinery/pkg/apis/meta/internalversion/roundtrip_test.go @@ -0,0 +1,28 @@ +/* +Copyright 2017 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 internalversion + +import ( + "testing" + + "k8s.io/apimachinery/pkg/api/testing/roundtrip" + "k8s.io/apimachinery/pkg/apis/meta/fuzzer" +) + +func TestRoundTrip(t *testing.T) { + roundtrip.RoundTripTestForScheme(t, scheme, fuzzer.Funcs) +} diff --git a/staging/src/k8s.io/apimachinery/pkg/apis/testapigroup/fuzzer/BUILD b/staging/src/k8s.io/apimachinery/pkg/apis/testapigroup/fuzzer/BUILD index c97f83a5b75..4689e79a06d 100644 --- a/staging/src/k8s.io/apimachinery/pkg/apis/testapigroup/fuzzer/BUILD +++ b/staging/src/k8s.io/apimachinery/pkg/apis/testapigroup/fuzzer/BUILD @@ -14,6 +14,7 @@ go_library( deps = [ "//vendor/github.com/google/gofuzz:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/testing:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/api/testing/fuzzer:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/testapigroup:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/testapigroup/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library", diff --git a/staging/src/k8s.io/apimachinery/pkg/apis/testapigroup/fuzzer/fuzzer.go b/staging/src/k8s.io/apimachinery/pkg/apis/testapigroup/fuzzer/fuzzer.go index 573045eebdf..8d5195cc2e1 100644 --- a/staging/src/k8s.io/apimachinery/pkg/apis/testapigroup/fuzzer/fuzzer.go +++ b/staging/src/k8s.io/apimachinery/pkg/apis/testapigroup/fuzzer/fuzzer.go @@ -17,18 +17,21 @@ limitations under the License. package fuzzer import ( + "fmt" + "github.com/google/gofuzz" apitesting "k8s.io/apimachinery/pkg/api/testing" + "k8s.io/apimachinery/pkg/api/testing/fuzzer" "k8s.io/apimachinery/pkg/apis/testapigroup" "k8s.io/apimachinery/pkg/apis/testapigroup/v1" "k8s.io/apimachinery/pkg/runtime" runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" ) -// overrideGenericFuncs override some generic fuzzer funcs from k8s.io/apimachinery in order to have more realistic +// overrideMetaFuncs override some generic fuzzer funcs from k8s.io/apimachinery in order to have more realistic // values in a Kubernetes context. -func overrideGenericFuncs(t apitesting.TestingCommon, codecs runtimeserializer.CodecFactory) []interface{} { +func overrideMetaFuncs(codecs runtimeserializer.CodecFactory) []interface{} { return []interface{}{ func(j *runtime.Object, c fuzz.Continue) { // TODO: uncomment when round trip starts from a versioned object @@ -54,7 +57,7 @@ func overrideGenericFuncs(t apitesting.TestingCommon, codecs runtimeserializer.C // Convert the object to raw bytes bytes, err := runtime.Encode(apitesting.TestCodec(codecs, v1.SchemeGroupVersion), obj) if err != nil { - t.Errorf("Failed to encode object: %v", err) + panic(fmt.Sprintf("Failed to encode object: %v", err)) return } @@ -64,7 +67,7 @@ func overrideGenericFuncs(t apitesting.TestingCommon, codecs runtimeserializer.C } } -func testapigroupFuncs(t apitesting.TestingCommon) []interface{} { +func testapigroupFuncs(codecs runtimeserializer.CodecFactory) []interface{} { return []interface{}{ func(s *testapigroup.CarpSpec, c fuzz.Continue) { c.FuzzNoCustom(s) @@ -90,10 +93,8 @@ func testapigroupFuncs(t apitesting.TestingCommon) []interface{} { } } -func Funcs(t apitesting.TestingCommon, codecs runtimeserializer.CodecFactory) []interface{} { - return apitesting.MergeFuzzerFuncs(t, - apitesting.GenericFuzzerFuncs(t, codecs), - overrideGenericFuncs(t, codecs), - testapigroupFuncs(t), - ) -} +// Funcs returns the fuzzer functions for the testapigroup. +var Funcs = fuzzer.MergeFuzzerFuncs( + overrideMetaFuncs, + testapigroupFuncs, +) diff --git a/staging/src/k8s.io/apimachinery/pkg/apis/testapigroup/install/BUILD b/staging/src/k8s.io/apimachinery/pkg/apis/testapigroup/install/BUILD index 2f00d9507cf..320edcc76ba 100644 --- a/staging/src/k8s.io/apimachinery/pkg/apis/testapigroup/install/BUILD +++ b/staging/src/k8s.io/apimachinery/pkg/apis/testapigroup/install/BUILD @@ -5,6 +5,7 @@ licenses(["notice"]) load( "@io_bazel_rules_go//go:def.bzl", "go_library", + "go_test", ) go_library( @@ -19,3 +20,14 @@ go_library( "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library", ], ) + +go_test( + name = "go_default_test", + srcs = ["roundtrip_test.go"], + library = ":go_default_library", + tags = ["automanaged"], + deps = [ + "//vendor/k8s.io/apimachinery/pkg/api/testing/roundtrip:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/apis/testapigroup/fuzzer:go_default_library", + ], +) diff --git a/staging/src/k8s.io/apimachinery/pkg/apis/testapigroup/install/roundtrip_test.go b/staging/src/k8s.io/apimachinery/pkg/apis/testapigroup/install/roundtrip_test.go new file mode 100644 index 00000000000..da1a9c8ad97 --- /dev/null +++ b/staging/src/k8s.io/apimachinery/pkg/apis/testapigroup/install/roundtrip_test.go @@ -0,0 +1,28 @@ +/* +Copyright 2017 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 install + +import ( + "testing" + + "k8s.io/apimachinery/pkg/api/testing/roundtrip" + testapigroupfuzzer "k8s.io/apimachinery/pkg/apis/testapigroup/fuzzer" +) + +func TestRoundTrip(t *testing.T) { + roundtrip.RoundTripTestForAPIGroup(t, Install, testapigroupfuzzer.Funcs) +} diff --git a/staging/src/k8s.io/apiserver/pkg/apis/example/fuzzer/BUILD b/staging/src/k8s.io/apiserver/pkg/apis/example/fuzzer/BUILD index 6ecad013b2b..46f644c434a 100644 --- a/staging/src/k8s.io/apiserver/pkg/apis/example/fuzzer/BUILD +++ b/staging/src/k8s.io/apiserver/pkg/apis/example/fuzzer/BUILD @@ -14,6 +14,7 @@ go_library( deps = [ "//vendor/github.com/google/gofuzz:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/testing:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/api/testing/fuzzer:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library", "//vendor/k8s.io/apiserver/pkg/apis/example:go_default_library", diff --git a/staging/src/k8s.io/apiserver/pkg/apis/example/fuzzer/fuzzer.go b/staging/src/k8s.io/apiserver/pkg/apis/example/fuzzer/fuzzer.go index 1f62fbfc0b3..51f9f7674f5 100644 --- a/staging/src/k8s.io/apiserver/pkg/apis/example/fuzzer/fuzzer.go +++ b/staging/src/k8s.io/apiserver/pkg/apis/example/fuzzer/fuzzer.go @@ -17,18 +17,21 @@ limitations under the License. package fuzzer import ( + "fmt" + "github.com/google/gofuzz" apitesting "k8s.io/apimachinery/pkg/api/testing" + "k8s.io/apimachinery/pkg/api/testing/fuzzer" "k8s.io/apimachinery/pkg/runtime" runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" "k8s.io/apiserver/pkg/apis/example" examplev1 "k8s.io/apiserver/pkg/apis/example/v1" ) -// overrideGenericFuncs override some generic fuzzer funcs from k8s.io/apiserver in order to have more realistic +// overrideMetaFuncs override some generic fuzzer funcs from k8s.io/apiserver in order to have more realistic // values in a Kubernetes context. -func overrideGenericFuncs(t apitesting.TestingCommon, codecs runtimeserializer.CodecFactory) []interface{} { +func overrideMetaFuncs(codecs runtimeserializer.CodecFactory) []interface{} { return []interface{}{ func(j *runtime.Object, c fuzz.Continue) { // TODO: uncomment when round trip starts from a versioned object @@ -54,7 +57,7 @@ func overrideGenericFuncs(t apitesting.TestingCommon, codecs runtimeserializer.C // Convert the object to raw bytes bytes, err := runtime.Encode(apitesting.TestCodec(codecs, examplev1.SchemeGroupVersion), obj) if err != nil { - t.Errorf("Failed to encode object: %v", err) + panic(fmt.Sprintf("Failed to encode object: %v", err)) return } @@ -64,7 +67,7 @@ func overrideGenericFuncs(t apitesting.TestingCommon, codecs runtimeserializer.C } } -func exampleFuncs(t apitesting.TestingCommon) []interface{} { +func exampleFuncs(codecs runtimeserializer.CodecFactory) []interface{} { return []interface{}{ func(s *example.PodSpec, c fuzz.Continue) { c.FuzzNoCustom(s) @@ -90,10 +93,8 @@ func exampleFuncs(t apitesting.TestingCommon) []interface{} { } } -func Funcs(t apitesting.TestingCommon, codecs runtimeserializer.CodecFactory) []interface{} { - return apitesting.MergeFuzzerFuncs(t, - apitesting.GenericFuzzerFuncs(t, codecs), - overrideGenericFuncs(t, codecs), - exampleFuncs(t), - ) -} +// Funcs returns the fuzzer functions for the example api group. +var Funcs = fuzzer.MergeFuzzerFuncs( + overrideMetaFuncs, + exampleFuncs, +) diff --git a/staging/src/k8s.io/apiserver/pkg/apis/example/install/BUILD b/staging/src/k8s.io/apiserver/pkg/apis/example/install/BUILD index 74d45e4e8e3..2b6dff58cdb 100644 --- a/staging/src/k8s.io/apiserver/pkg/apis/example/install/BUILD +++ b/staging/src/k8s.io/apiserver/pkg/apis/example/install/BUILD @@ -5,6 +5,7 @@ licenses(["notice"]) load( "@io_bazel_rules_go//go:def.bzl", "go_library", + "go_test", ) go_library( @@ -19,3 +20,14 @@ go_library( "//vendor/k8s.io/apiserver/pkg/apis/example/v1:go_default_library", ], ) + +go_test( + name = "go_default_test", + srcs = ["roundtrip_test.go"], + library = ":go_default_library", + tags = ["automanaged"], + deps = [ + "//vendor/k8s.io/apimachinery/pkg/api/testing/roundtrip:go_default_library", + "//vendor/k8s.io/apiserver/pkg/apis/example/fuzzer:go_default_library", + ], +) diff --git a/staging/src/k8s.io/apiserver/pkg/apis/example/install/roundtrip_test.go b/staging/src/k8s.io/apiserver/pkg/apis/example/install/roundtrip_test.go new file mode 100644 index 00000000000..7f8d4e82a6a --- /dev/null +++ b/staging/src/k8s.io/apiserver/pkg/apis/example/install/roundtrip_test.go @@ -0,0 +1,28 @@ +/* +Copyright 2017 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 install + +import ( + "testing" + + "k8s.io/apimachinery/pkg/api/testing/roundtrip" + examplefuzzer "k8s.io/apiserver/pkg/apis/example/fuzzer" +) + +func TestRoundTrip(t *testing.T) { + roundtrip.RoundTripTestForAPIGroup(t, Install, examplefuzzer.Funcs) +} diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/BUILD b/staging/src/k8s.io/apiserver/pkg/endpoints/BUILD index efc94f379a0..465cbc9b13b 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/BUILD +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/BUILD @@ -25,7 +25,7 @@ go_test( "//vendor/k8s.io/apimachinery/pkg/api/equality:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/api/testing:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/api/testing/fuzzer:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library", diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/apiserver_test.go b/staging/src/k8s.io/apiserver/pkg/endpoints/apiserver_test.go index 14f87fa8249..b28dbc1a1a1 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/apiserver_test.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/apiserver_test.go @@ -41,7 +41,7 @@ import ( apiequality "k8s.io/apimachinery/pkg/api/equality" apierrs "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/meta" - apitesting "k8s.io/apimachinery/pkg/api/testing" + fuzzer "k8s.io/apimachinery/pkg/api/testing/fuzzer" metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -4104,7 +4104,7 @@ func newTestRequestInfoResolver() *request.RequestInfoFactory { const benchmarkSeed = 100 func benchmarkItems(b *testing.B) []example.Pod { - clientapiObjectFuzzer := apitesting.FuzzerFor(examplefuzzer.Funcs(b, codecs), rand.NewSource(benchmarkSeed)) + clientapiObjectFuzzer := fuzzer.FuzzerFor(examplefuzzer.Funcs, rand.NewSource(benchmarkSeed), codecs) items := make([]example.Pod, 3) for i := range items { clientapiObjectFuzzer.Fuzz(&items[i]) diff --git a/staging/src/k8s.io/sample-apiserver/pkg/apis/wardle/install/BUILD b/staging/src/k8s.io/sample-apiserver/pkg/apis/wardle/install/BUILD index de8179e119d..6a483a457f4 100644 --- a/staging/src/k8s.io/sample-apiserver/pkg/apis/wardle/install/BUILD +++ b/staging/src/k8s.io/sample-apiserver/pkg/apis/wardle/install/BUILD @@ -10,10 +10,10 @@ load( go_test( name = "go_default_test", - srcs = ["install_test.go"], + srcs = ["roundtrip_test.go"], library = ":go_default_library", tags = ["automanaged"], - deps = ["//vendor/k8s.io/apimachinery/pkg/api/testing:go_default_library"], + deps = ["//vendor/k8s.io/apimachinery/pkg/api/testing/roundtrip:go_default_library"], ) go_library( diff --git a/staging/src/k8s.io/sample-apiserver/pkg/apis/wardle/install/install_test.go b/staging/src/k8s.io/sample-apiserver/pkg/apis/wardle/install/roundtrip_test.go similarity index 85% rename from staging/src/k8s.io/sample-apiserver/pkg/apis/wardle/install/install_test.go rename to staging/src/k8s.io/sample-apiserver/pkg/apis/wardle/install/roundtrip_test.go index de4aaf18684..ecdc81ca0de 100644 --- a/staging/src/k8s.io/sample-apiserver/pkg/apis/wardle/install/install_test.go +++ b/staging/src/k8s.io/sample-apiserver/pkg/apis/wardle/install/roundtrip_test.go @@ -19,9 +19,9 @@ package install import ( "testing" - apitesting "k8s.io/apimachinery/pkg/api/testing" + roundtrip "k8s.io/apimachinery/pkg/api/testing/roundtrip" ) func TestRoundTripTypes(t *testing.T) { - apitesting.RoundTripTestForAPIGroup(t, Install, nil) + roundtrip.RoundTripTestForAPIGroup(t, Install, nil) } diff --git a/staging/src/k8s.io/sample-apiserver/pkg/apiserver/BUILD b/staging/src/k8s.io/sample-apiserver/pkg/apiserver/BUILD index cb52000262b..e229dfabc6f 100644 --- a/staging/src/k8s.io/sample-apiserver/pkg/apiserver/BUILD +++ b/staging/src/k8s.io/sample-apiserver/pkg/apiserver/BUILD @@ -13,7 +13,7 @@ go_test( srcs = ["scheme_test.go"], library = ":go_default_library", tags = ["automanaged"], - deps = ["//vendor/k8s.io/apimachinery/pkg/api/testing:go_default_library"], + deps = ["//vendor/k8s.io/apimachinery/pkg/api/testing/roundtrip:go_default_library"], ) go_library( diff --git a/staging/src/k8s.io/sample-apiserver/pkg/apiserver/scheme_test.go b/staging/src/k8s.io/sample-apiserver/pkg/apiserver/scheme_test.go index 6a7554bac7b..070dd3c009f 100644 --- a/staging/src/k8s.io/sample-apiserver/pkg/apiserver/scheme_test.go +++ b/staging/src/k8s.io/sample-apiserver/pkg/apiserver/scheme_test.go @@ -19,9 +19,9 @@ package apiserver import ( "testing" - apitesting "k8s.io/apimachinery/pkg/api/testing" + "k8s.io/apimachinery/pkg/api/testing/roundtrip" ) func TestRoundTripTypes(t *testing.T) { - apitesting.RoundTripTestForScheme(t, Scheme, nil) + roundtrip.RoundTripTestForScheme(t, Scheme, nil) }