func fuzzInternalObject(t *testing.T, forVersion string, item runtime.Object, seed int64) runtime.Object { apitesting.FuzzerFor(t, forVersion, rand.NewSource(seed)).Fuzz(item) j, err := meta.TypeAccessor(item) if err != nil { t.Fatalf("Unexpected error %v for %#v", err, item) } j.SetKind("") j.SetAPIVersion("") return item }
func TestTypes(t *testing.T) { for kind, reflectType := range api.Scheme.KnownTypes("") { if !strings.Contains(reflectType.PkgPath(), "/origin/") { continue } t.Logf("About to test %v", reflectType) // Try a few times, since runTest uses random values. for i := 0; i < fuzzIters; i++ { item, err := api.Scheme.New("", kind) if err != nil { t.Errorf("Couldn't make a %v? %v", kind, err) continue } if _, err := meta.TypeAccessor(item); err != nil { t.Fatalf("%q is not a TypeMeta and cannot be tested - add it to nonRoundTrippableTypes: %v", kind, err) } seed := rand.Int63() if versions, ok := skipStandardVersions[kind]; ok { for _, v := range versions { fuzzInternalObject(t, "", item, seed) roundTrip(t, runtime.CodecFor(api.Scheme, v), item) } continue } fuzzInternalObject(t, "", item, seed) roundTrip(t, osapi.Codec, item) if _, ok := skipV1beta3[kind]; !ok { fuzzInternalObject(t, "v1beta3", item, seed) roundTrip(t, v1beta3.Codec, item) } if _, ok := skipV1[kind]; !ok { fuzzInternalObject(t, "v1", item, seed) roundTrip(t, v1.Codec, item) } } } }
func TestRoundTripTypes(t *testing.T) { // api.Scheme.Log(t) // defer api.Scheme.Log(nil) for kind := range api.Scheme.KnownTypes("") { if nonRoundTrippableTypes.Has(kind) { continue } // Try a few times, since runTest uses random values. for i := 0; i < *fuzzIters; i++ { item, err := api.Scheme.New("", kind) if err != nil { t.Fatalf("Couldn't make a %v? %v", kind, err) } if _, err := meta.TypeAccessor(item); err != nil { t.Fatalf("%q is not a TypeMeta and cannot be tested - add it to nonRoundTrippableTypes: %v", kind, err) } roundTripSame(t, item, nonRoundTrippableTypesByVersion[kind]...) if !nonInternalRoundTrippableTypes.Has(kind) { roundTrip(t, api.Codec, fuzzInternalObject(t, "", item, rand.Int63())) } } } }
func fuzzInternalObject(t *testing.T, forVersion string, item runtime.Object, seed int64) runtime.Object { f := apitesting.FuzzerFor(t, forVersion, rand.NewSource(seed)) f.Funcs( // Roles and RoleBindings maps are never nil func(j *authorizationapi.Policy, c fuzz.Continue) { j.Roles = make(map[string]*authorizationapi.Role) }, func(j *authorizationapi.PolicyBinding, c fuzz.Continue) { j.RoleBindings = make(map[string]*authorizationapi.RoleBinding) }, func(j *authorizationapi.ClusterPolicy, c fuzz.Continue) { j.Roles = make(map[string]*authorizationapi.ClusterRole) }, func(j *authorizationapi.ClusterPolicyBinding, c fuzz.Continue) { j.RoleBindings = make(map[string]*authorizationapi.ClusterRoleBinding) }, func(j *template.Template, c fuzz.Continue) { c.Fuzz(&j.ObjectMeta) c.Fuzz(&j.Parameters) // TODO: replace with structured type definition j.Objects = []runtime.Object{} }, func(j *image.Image, c fuzz.Continue) { c.Fuzz(&j.ObjectMeta) c.Fuzz(&j.DockerImageMetadata) j.DockerImageMetadata.APIVersion = "" j.DockerImageMetadata.Kind = "" j.DockerImageMetadataVersion = []string{"pre012", "1.0"}[c.Rand.Intn(2)] j.DockerImageReference = c.RandString() }, func(j *image.ImageStreamMapping, c fuzz.Continue) { c.FuzzNoCustom(j) j.DockerImageRepository = "" }, func(j *image.ImageStreamImage, c fuzz.Continue) { c.Fuzz(&j.Image) // because we de-embedded Image from ImageStreamImage, in order to round trip // successfully, the ImageStreamImage's ObjectMeta must match the Image's. j.ObjectMeta = j.Image.ObjectMeta }, func(j *image.ImageStreamTag, c fuzz.Continue) { c.Fuzz(&j.Image) // because we de-embedded Image from ImageStreamTag, in order to round trip // successfully, the ImageStreamTag's ObjectMeta must match the Image's. j.ObjectMeta = j.Image.ObjectMeta }, func(j *image.TagReference, c fuzz.Continue) { c.FuzzNoCustom(j) if j.From != nil { specs := []string{"", "ImageStreamTag", "ImageStreamImage"} j.From.Kind = specs[c.Intn(len(specs))] } }, func(j *build.SourceBuildStrategy, c fuzz.Continue) { c.FuzzNoCustom(j) j.From.Kind = "ImageStreamTag" j.From.Name = "image:tag" j.From.APIVersion = "" j.From.ResourceVersion = "" j.From.FieldPath = "" }, func(j *build.CustomBuildStrategy, c fuzz.Continue) { c.FuzzNoCustom(j) j.From.Kind = "ImageStreamTag" j.From.Name = "image:tag" j.From.APIVersion = "" j.From.ResourceVersion = "" j.From.FieldPath = "" }, func(j *build.DockerBuildStrategy, c fuzz.Continue) { c.FuzzNoCustom(j) j.From.Kind = "ImageStreamTag" j.From.Name = "image:tag" j.From.APIVersion = "" j.From.ResourceVersion = "" j.From.FieldPath = "" }, func(j *build.BuildOutput, c fuzz.Continue) { c.FuzzNoCustom(j) if j.To != nil && (len(j.To.Kind) == 0 || j.To.Kind == "ImageStream") { j.To.Kind = "ImageStreamTag" } if j.To != nil && strings.Contains(j.To.Name, ":") { j.To.Name = strings.Replace(j.To.Name, ":", "-", -1) } }, func(j *deploy.DeploymentStrategy, c fuzz.Continue) { c.FuzzNoCustom(j) mkintp := func(i int) *int64 { v := int64(i) return &v } switch c.Intn(3) { case 0: // TODO: we should not have to set defaults, instead we should be able // to detect defaults were applied. j.Type = deploy.DeploymentStrategyTypeRolling j.RollingParams = &deploy.RollingDeploymentStrategyParams{ IntervalSeconds: mkintp(1), UpdatePeriodSeconds: mkintp(1), TimeoutSeconds: mkintp(120), } case 1: j.Type = deploy.DeploymentStrategyTypeRecreate j.RollingParams = nil case 2: j.Type = deploy.DeploymentStrategyTypeCustom j.RollingParams = nil } }, func(j *deploy.DeploymentCauseImageTrigger, c fuzz.Continue) { c.FuzzNoCustom(j) specs := []string{"", "a/b", "a/b/c", "a:5000/b/c", "a/b", "a/b"} tags := []string{"", "stuff", "other"} j.RepositoryName = specs[c.Intn(len(specs))] if len(j.RepositoryName) > 0 { j.Tag = tags[c.Intn(len(tags))] } else { j.Tag = "" } }, func(j *deploy.DeploymentTriggerImageChangeParams, c fuzz.Continue) { c.FuzzNoCustom(j) specs := []string{"a/b", "a/b/c", "a:5000/b/c", "a/b:latest", "a/b@test"} j.From.Kind = "DockerImage" j.From.Name = specs[c.Intn(len(specs))] if ref, err := image.ParseDockerImageReference(j.From.Name); err == nil { j.Tag = ref.Tag ref.Tag, ref.ID = "", "" j.RepositoryName = ref.String() } }, func(j *runtime.EmbeddedObject, c fuzz.Continue) { // runtime.EmbeddedObject causes a panic inside of fuzz because runtime.Object isn't handled. }, func(t *time.Time, c fuzz.Continue) { // This is necessary because the standard fuzzed time.Time object is // completely nil, but when JSON unmarshals dates it fills in the // unexported loc field with the time.UTC object, resulting in // reflect.DeepEqual returning false in the round trip tests. We solve it // by using a date that will be identical to the one JSON unmarshals. *t = time.Date(2000, 1, 1, 1, 1, 1, 0, time.UTC) }, func(u64 *uint64, c fuzz.Continue) { // TODO: uint64's are NOT handled right. *u64 = c.RandUint64() >> 8 }, ) f.Fuzz(item) j, err := meta.TypeAccessor(item) if err != nil { t.Fatalf("Unexpected error %v for %#v", err, item) } j.SetKind("") j.SetAPIVersion("") return item }