Use randfill, do API renames

This commit is contained in:
Tim Hockin 2025-02-20 09:45:22 -08:00
parent 0eaee48ecb
commit e54719bb66
No known key found for this signature in database
87 changed files with 874 additions and 872 deletions

View File

@ -17,7 +17,7 @@ limitations under the License.
package fuzzer package fuzzer
import ( import (
fuzz "github.com/google/gofuzz" "sigs.k8s.io/randfill"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -46,8 +46,8 @@ func Funcs(codecs runtimeserializer.CodecFactory) []interface{} {
} }
} }
func fuzzInitConfiguration(obj *kubeadm.InitConfiguration, c fuzz.Continue) { func fuzzInitConfiguration(obj *kubeadm.InitConfiguration, c randfill.Continue) {
c.FuzzNoCustom(obj) c.FillNoCustom(obj)
// Pinning values for fields that get defaults if fuzz value is empty string or nil (thus making the round trip test fail) // Pinning values for fields that get defaults if fuzz value is empty string or nil (thus making the round trip test fail)
@ -71,16 +71,16 @@ func fuzzInitConfiguration(obj *kubeadm.InitConfiguration, c fuzz.Continue) {
kubeadm.SetDefaultTimeouts(&obj.Timeouts) kubeadm.SetDefaultTimeouts(&obj.Timeouts)
} }
func fuzzNodeRegistration(obj *kubeadm.NodeRegistrationOptions, c fuzz.Continue) { func fuzzNodeRegistration(obj *kubeadm.NodeRegistrationOptions, c randfill.Continue) {
c.FuzzNoCustom(obj) c.FillNoCustom(obj)
// Pinning values for fields that get defaults if fuzz value is empty string or nil (thus making the round trip test fail) // Pinning values for fields that get defaults if fuzz value is empty string or nil (thus making the round trip test fail)
obj.IgnorePreflightErrors = nil obj.IgnorePreflightErrors = nil
obj.ImagePullSerial = ptr.To(true) obj.ImagePullSerial = ptr.To(true)
} }
func fuzzClusterConfiguration(obj *kubeadm.ClusterConfiguration, c fuzz.Continue) { func fuzzClusterConfiguration(obj *kubeadm.ClusterConfiguration, c randfill.Continue) {
c.FuzzNoCustom(obj) c.FillNoCustom(obj)
// Pinning values for fields that get defaults if fuzz value is empty string or nil (thus making the round trip test fail) // Pinning values for fields that get defaults if fuzz value is empty string or nil (thus making the round trip test fail)
obj.CertificatesDir = "foo" obj.CertificatesDir = "foo"
@ -100,33 +100,33 @@ func fuzzClusterConfiguration(obj *kubeadm.ClusterConfiguration, c fuzz.Continue
obj.CACertificateValidityPeriod = &metav1.Duration{Duration: constants.CACertificateValidityPeriod} obj.CACertificateValidityPeriod = &metav1.Duration{Duration: constants.CACertificateValidityPeriod}
} }
func fuzzDNS(obj *kubeadm.DNS, c fuzz.Continue) { func fuzzDNS(obj *kubeadm.DNS, c randfill.Continue) {
c.FuzzNoCustom(obj) c.FillNoCustom(obj)
obj.Disabled = false obj.Disabled = false
} }
func fuzzComponentConfigMap(obj *kubeadm.ComponentConfigMap, c fuzz.Continue) { func fuzzComponentConfigMap(obj *kubeadm.ComponentConfigMap, c randfill.Continue) {
// This is intentionally empty because component config does not exists in the public api // This is intentionally empty because component config does not exists in the public api
// (empty mean all ComponentConfigs fields nil, and this is necessary for getting roundtrip passing) // (empty mean all ComponentConfigs fields nil, and this is necessary for getting roundtrip passing)
} }
func fuzzLocalEtcd(obj *kubeadm.LocalEtcd, c fuzz.Continue) { func fuzzLocalEtcd(obj *kubeadm.LocalEtcd, c randfill.Continue) {
c.FuzzNoCustom(obj) c.FillNoCustom(obj)
// Pinning values for fields that get defaults if fuzz value is empty string or nil (thus making the round trip test fail) // Pinning values for fields that get defaults if fuzz value is empty string or nil (thus making the round trip test fail)
obj.DataDir = "foo" obj.DataDir = "foo"
} }
func fuzzNetworking(obj *kubeadm.Networking, c fuzz.Continue) { func fuzzNetworking(obj *kubeadm.Networking, c randfill.Continue) {
c.FuzzNoCustom(obj) c.FillNoCustom(obj)
// Pinning values for fields that get defaults if fuzz value is empty string or nil (thus making the round trip test fail) // Pinning values for fields that get defaults if fuzz value is empty string or nil (thus making the round trip test fail)
obj.DNSDomain = "foo" obj.DNSDomain = "foo"
obj.ServiceSubnet = "bar" obj.ServiceSubnet = "bar"
} }
func fuzzJoinConfiguration(obj *kubeadm.JoinConfiguration, c fuzz.Continue) { func fuzzJoinConfiguration(obj *kubeadm.JoinConfiguration, c randfill.Continue) {
c.FuzzNoCustom(obj) c.FillNoCustom(obj)
// Pinning values for fields that get defaults if fuzz value is empty string or nil (thus making the round trip test fail) // Pinning values for fields that get defaults if fuzz value is empty string or nil (thus making the round trip test fail)
obj.CACertPath = "foo" obj.CACertPath = "foo"
@ -143,20 +143,20 @@ func fuzzJoinConfiguration(obj *kubeadm.JoinConfiguration, c fuzz.Continue) {
kubeadm.SetDefaultTimeouts(&obj.Timeouts) kubeadm.SetDefaultTimeouts(&obj.Timeouts)
} }
func fuzzJoinControlPlane(obj *kubeadm.JoinControlPlane, c fuzz.Continue) { func fuzzJoinControlPlane(obj *kubeadm.JoinControlPlane, c randfill.Continue) {
c.FuzzNoCustom(obj) c.FillNoCustom(obj)
} }
func fuzzResetConfiguration(obj *kubeadm.ResetConfiguration, c fuzz.Continue) { func fuzzResetConfiguration(obj *kubeadm.ResetConfiguration, c randfill.Continue) {
c.FuzzNoCustom(obj) c.FillNoCustom(obj)
// Pinning values for fields that get defaults if fuzz value is empty string or nil (thus making the round trip test fail) // Pinning values for fields that get defaults if fuzz value is empty string or nil (thus making the round trip test fail)
obj.CertificatesDir = "/tmp" obj.CertificatesDir = "/tmp"
kubeadm.SetDefaultTimeouts(&obj.Timeouts) kubeadm.SetDefaultTimeouts(&obj.Timeouts)
} }
func fuzzUpgradeConfiguration(obj *kubeadm.UpgradeConfiguration, c fuzz.Continue) { func fuzzUpgradeConfiguration(obj *kubeadm.UpgradeConfiguration, c randfill.Continue) {
c.FuzzNoCustom(obj) c.FillNoCustom(obj)
// Pinning values for fields that get defaults if fuzz value is empty string or nil (thus making the round trip test fail) // Pinning values for fields that get defaults if fuzz value is empty string or nil (thus making the round trip test fail)
obj.Node.EtcdUpgrade = ptr.To(true) obj.Node.EtcdUpgrade = ptr.To(true)

View File

@ -19,7 +19,7 @@ package fuzzer
import ( import (
"time" "time"
fuzz "github.com/google/gofuzz" "sigs.k8s.io/randfill"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer"
@ -36,8 +36,8 @@ func Funcs(codecs runtimeserializer.CodecFactory) []interface{} {
} }
} }
func fuzzBootstrapToken(obj *output.BootstrapToken, c fuzz.Continue) { func fuzzBootstrapToken(obj *output.BootstrapToken, c randfill.Continue) {
c.FuzzNoCustom(obj) c.FillNoCustom(obj)
obj.Token = &bootstraptokenv1.BootstrapTokenString{ID: "uvxdac", Secret: "fq35fuyue3kd4gda"} obj.Token = &bootstraptokenv1.BootstrapTokenString{ID: "uvxdac", Secret: "fq35fuyue3kd4gda"}
obj.Description = "" obj.Description = ""

View File

@ -22,7 +22,6 @@ import (
"testing" "testing"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
fuzz "github.com/google/gofuzz"
"k8s.io/apimachinery/pkg/api/apitesting/fuzzer" "k8s.io/apimachinery/pkg/api/apitesting/fuzzer"
apiequality "k8s.io/apimachinery/pkg/api/equality" apiequality "k8s.io/apimachinery/pkg/api/equality"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -31,6 +30,7 @@ import (
"k8s.io/apimachinery/pkg/util/json" "k8s.io/apimachinery/pkg/util/json"
"k8s.io/client-go/applyconfigurations" "k8s.io/client-go/applyconfigurations"
v1mf "k8s.io/client-go/applyconfigurations/core/v1" v1mf "k8s.io/client-go/applyconfigurations/core/v1"
"sigs.k8s.io/randfill"
"k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/api/legacyscheme"
api "k8s.io/kubernetes/pkg/apis/core" api "k8s.io/kubernetes/pkg/apis/core"
@ -166,22 +166,22 @@ func fuzzObject(t *testing.T, gvk schema.GroupVersionKind) runtime.Object {
// Ensure that InitContainers and their statuses are not generated. This // Ensure that InitContainers and their statuses are not generated. This
// is because in this test we are simply doing json operations, in which // is because in this test we are simply doing json operations, in which
// those disappear. // those disappear.
func(s *api.PodSpec, c fuzz.Continue) { func(s *api.PodSpec, c randfill.Continue) {
c.FuzzNoCustom(s) c.FillNoCustom(s)
s.InitContainers = nil s.InitContainers = nil
}, },
func(s *api.PodStatus, c fuzz.Continue) { func(s *api.PodStatus, c randfill.Continue) {
c.FuzzNoCustom(s) c.FillNoCustom(s)
s.InitContainerStatuses = nil s.InitContainerStatuses = nil
}, },
// Apply configuration types do not have managed fields, so we exclude // Apply configuration types do not have managed fields, so we exclude
// them in our fuzz test cases. // them in our fuzz test cases.
func(s *v1.ObjectMeta, c fuzz.Continue) { func(s *v1.ObjectMeta, c randfill.Continue) {
c.FuzzNoCustom(s) c.FillNoCustom(s)
s.ManagedFields = nil s.ManagedFields = nil
s.SelfLink = "" s.SelfLink = ""
}, },
).Fuzz(internalObj) ).Fill(internalObj)
item, err := legacyscheme.Scheme.New(externalVersion.WithKind(kind)) item, err := legacyscheme.Scheme.New(externalVersion.WithKind(kind))
if err != nil { if err != nil {

View File

@ -36,7 +36,7 @@ func BenchmarkPodConversion(b *testing.B) {
apiObjectFuzzer := fuzzer.FuzzerFor(FuzzerFuncs, rand.NewSource(benchmarkSeed), legacyscheme.Codecs) apiObjectFuzzer := fuzzer.FuzzerFor(FuzzerFuncs, rand.NewSource(benchmarkSeed), legacyscheme.Codecs)
items := make([]api.Pod, 4) items := make([]api.Pod, 4)
for i := range items { for i := range items {
apiObjectFuzzer.Fuzz(&items[i]) apiObjectFuzzer.Fill(&items[i])
items[i].Spec.InitContainers = nil items[i].Spec.InitContainers = nil
items[i].Status.InitContainerStatuses = nil items[i].Status.InitContainerStatuses = nil
} }

View File

@ -23,7 +23,7 @@ import (
"testing" "testing"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
fuzz "github.com/google/gofuzz" "sigs.k8s.io/randfill"
"k8s.io/apimachinery/pkg/api/apitesting/fuzzer" "k8s.io/apimachinery/pkg/api/apitesting/fuzzer"
"k8s.io/apimachinery/pkg/api/apitesting/roundtrip" "k8s.io/apimachinery/pkg/api/apitesting/roundtrip"
@ -43,12 +43,12 @@ func TestDeepCopyApiObjects(t *testing.T) {
} }
} }
func doDeepCopyTest(t *testing.T, kind schema.GroupVersionKind, f *fuzz.Fuzzer) { func doDeepCopyTest(t *testing.T, kind schema.GroupVersionKind, f *randfill.Filler) {
item, err := legacyscheme.Scheme.New(kind) item, err := legacyscheme.Scheme.New(kind)
if err != nil { if err != nil {
t.Fatalf("Could not create a %v: %s", kind, err) t.Fatalf("Could not create a %v: %s", kind, err)
} }
f.Fuzz(item) f.Fill(item)
itemCopy := item.DeepCopyObject() itemCopy := item.DeepCopyObject()
if !reflect.DeepEqual(item, itemCopy) { if !reflect.DeepEqual(item, itemCopy) {
t.Errorf("\nexpected: %#v\n\ngot: %#v\n\ndiff: %v", item, itemCopy, cmp.Diff(item, itemCopy)) t.Errorf("\nexpected: %#v\n\ngot: %#v\n\ndiff: %v", item, itemCopy, cmp.Diff(item, itemCopy))
@ -61,7 +61,7 @@ func doDeepCopyTest(t *testing.T, kind schema.GroupVersionKind, f *fuzz.Fuzzer)
} }
// Refuzz the copy, which should have no effect on the original // Refuzz the copy, which should have no effect on the original
f.Fuzz(itemCopy) f.Fill(itemCopy)
postfuzzData := &bytes.Buffer{} postfuzzData := &bytes.Buffer{}
if err := legacyscheme.Codecs.LegacyCodec(kind.GroupVersion()).Encode(item, postfuzzData); err != nil { if err := legacyscheme.Codecs.LegacyCodec(kind.GroupVersion()).Encode(item, postfuzzData); err != nil {

View File

@ -23,7 +23,7 @@ import (
"testing" "testing"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
fuzz "github.com/google/gofuzz" "sigs.k8s.io/randfill"
apiv1 "k8s.io/api/core/v1" apiv1 "k8s.io/api/core/v1"
extensionsv1beta1 "k8s.io/api/extensions/v1beta1" extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
@ -219,20 +219,20 @@ func TestDefaulting(t *testing.T) {
t.Run(gvk.String(), func(t *testing.T) { t.Run(gvk.String(), func(t *testing.T) {
// Each sub-tests gets its own fuzzer instance to make running it independent // Each sub-tests gets its own fuzzer instance to make running it independent
// from what other tests ran before. // from what other tests ran before.
f := fuzz.New().NilChance(.5).NumElements(1, 1).RandSource(rand.NewSource(1)) f := randfill.New().NilChance(.5).NumElements(1, 1).RandSource(rand.NewSource(1))
f.Funcs( f.Funcs(
func(s *runtime.RawExtension, c fuzz.Continue) {}, func(s *runtime.RawExtension, c randfill.Continue) {},
func(s *metav1.LabelSelector, c fuzz.Continue) { func(s *metav1.LabelSelector, c randfill.Continue) {
c.FuzzNoCustom(s) c.FillNoCustom(s)
s.MatchExpressions = nil // need to fuzz this specially s.MatchExpressions = nil // need to fuzz this specially
}, },
func(s *metav1.ListOptions, c fuzz.Continue) { func(s *metav1.ListOptions, c randfill.Continue) {
c.FuzzNoCustom(s) c.FillNoCustom(s)
s.LabelSelector = "" // need to fuzz requirement strings specially s.LabelSelector = "" // need to fuzz requirement strings specially
s.FieldSelector = "" // need to fuzz requirement strings specially s.FieldSelector = "" // need to fuzz requirement strings specially
}, },
func(s *extensionsv1beta1.ScaleStatus, c fuzz.Continue) { func(s *extensionsv1beta1.ScaleStatus, c randfill.Continue) {
c.FuzzNoCustom(s) c.FillNoCustom(s)
s.TargetSelector = "" // need to fuzz requirement strings specially s.TargetSelector = "" // need to fuzz requirement strings specially
}, },
) )
@ -262,7 +262,7 @@ func TestDefaulting(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
f.Fuzz(src) f.Fill(src)
src.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{}) src.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{})
@ -289,10 +289,10 @@ func TestDefaulting(t *testing.T) {
} }
func BenchmarkPodDefaulting(b *testing.B) { func BenchmarkPodDefaulting(b *testing.B) {
f := fuzz.New().NilChance(.5).NumElements(1, 1).RandSource(rand.NewSource(1)) f := randfill.New().NilChance(.5).NumElements(1, 1).RandSource(rand.NewSource(1))
items := make([]apiv1.Pod, 100) items := make([]apiv1.Pod, 100)
for i := range items { for i := range items {
f.Fuzz(&items[i]) f.Fill(&items[i])
} }
scheme := legacyscheme.Scheme scheme := legacyscheme.Scheme

View File

@ -19,7 +19,7 @@ package testing
import ( import (
"fmt" "fmt"
fuzz "github.com/google/gofuzz" "sigs.k8s.io/randfill"
appsv1 "k8s.io/api/apps/v1" appsv1 "k8s.io/api/apps/v1"
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
@ -51,9 +51,9 @@ import (
// values in a Kubernetes context. // values in a Kubernetes context.
func overrideGenericFuncs(codecs runtimeserializer.CodecFactory) []interface{} { func overrideGenericFuncs(codecs runtimeserializer.CodecFactory) []interface{} {
return []interface{}{ return []interface{}{
func(j *runtime.Object, c fuzz.Continue) { func(j *runtime.Object, c randfill.Continue) {
// TODO: uncomment when round trip starts from a versioned object // TODO: uncomment when round trip starts from a versioned object
if true { //c.RandBool() { if true { // c.Bool() {
*j = &runtime.Unknown{ *j = &runtime.Unknown{
// We do not set TypeMeta here because it is not carried through a round trip // We do not set TypeMeta here because it is not carried through a round trip
Raw: []byte(`{"apiVersion":"unknown.group/unknown","kind":"Something","someKey":"someValue"}`), Raw: []byte(`{"apiVersion":"unknown.group/unknown","kind":"Something","someKey":"someValue"}`),
@ -62,15 +62,15 @@ func overrideGenericFuncs(codecs runtimeserializer.CodecFactory) []interface{} {
} else { } else {
types := []runtime.Object{&api.Pod{}, &api.ReplicationController{}} types := []runtime.Object{&api.Pod{}, &api.ReplicationController{}}
t := types[c.Rand.Intn(len(types))] t := types[c.Rand.Intn(len(types))]
c.Fuzz(t) c.Fill(t)
*j = t *j = t
} }
}, },
func(r *runtime.RawExtension, c fuzz.Continue) { func(r *runtime.RawExtension, c randfill.Continue) {
// Pick an arbitrary type and fuzz it // Pick an arbitrary type and fuzz it
types := []runtime.Object{&api.Pod{}, &apps.Deployment{}, &api.Service{}} types := []runtime.Object{&api.Pod{}, &apps.Deployment{}, &api.Service{}}
obj := types[c.Rand.Intn(len(types))] obj := types[c.Rand.Intn(len(types))]
c.Fuzz(obj) c.Fill(obj)
var codec runtime.Codec var codec runtime.Codec
switch obj.(type) { switch obj.(type) {

View File

@ -99,7 +99,7 @@ func fieldsHaveProtobufTags(obj reflect.Type) error {
func TestProtobufRoundTrip(t *testing.T) { func TestProtobufRoundTrip(t *testing.T) {
obj := &v1.Pod{} obj := &v1.Pod{}
fuzzer.FuzzerFor(FuzzerFuncs, rand.NewSource(benchmarkSeed), legacyscheme.Codecs).Fuzz(obj) fuzzer.FuzzerFor(FuzzerFuncs, rand.NewSource(benchmarkSeed), legacyscheme.Codecs).Fill(obj)
// InitContainers are turned into annotations by conversion. // InitContainers are turned into annotations by conversion.
obj.Spec.InitContainers = nil obj.Spec.InitContainers = nil
obj.Status.InitContainerStatuses = nil obj.Status.InitContainerStatuses = nil

View File

@ -51,7 +51,7 @@ import (
// fuzzInternalObject fuzzes an arbitrary runtime object using the appropriate // fuzzInternalObject fuzzes an arbitrary runtime object using the appropriate
// fuzzer registered with the apitesting package. // fuzzer registered with the apitesting package.
func fuzzInternalObject(t *testing.T, forVersion schema.GroupVersion, item runtime.Object, seed int64) runtime.Object { func fuzzInternalObject(t *testing.T, forVersion schema.GroupVersion, item runtime.Object, seed int64) runtime.Object {
fuzzer.FuzzerFor(FuzzerFuncs, rand.NewSource(seed), legacyscheme.Codecs).Fuzz(item) fuzzer.FuzzerFor(FuzzerFuncs, rand.NewSource(seed), legacyscheme.Codecs).Fill(item)
j, err := meta.TypeAccessor(item) j, err := meta.TypeAccessor(item)
if err != nil { if err != nil {
@ -331,7 +331,7 @@ func TestUnversionedTypes(t *testing.T) {
func TestObjectWatchFraming(t *testing.T) { func TestObjectWatchFraming(t *testing.T) {
f := fuzzer.FuzzerFor(FuzzerFuncs, rand.NewSource(benchmarkSeed), legacyscheme.Codecs) f := fuzzer.FuzzerFor(FuzzerFuncs, rand.NewSource(benchmarkSeed), legacyscheme.Codecs)
secret := &api.Secret{} secret := &api.Secret{}
f.Fuzz(secret) f.Fill(secret)
if secret.Data == nil { if secret.Data == nil {
secret.Data = map[string][]byte{} secret.Data = map[string][]byte{}
} }
@ -418,7 +418,7 @@ func benchmarkItems(b *testing.B) []v1.Pod {
items := make([]v1.Pod, 10) items := make([]v1.Pod, 10)
for i := range items { for i := range items {
var pod api.Pod var pod api.Pod
apiObjectFuzzer.Fuzz(&pod) apiObjectFuzzer.Fill(&pod)
pod.Spec.InitContainers, pod.Status.InitContainerStatuses = nil, nil pod.Spec.InitContainers, pod.Status.InitContainerStatuses = nil, nil
out, err := legacyscheme.Scheme.ConvertToVersion(&pod, v1.SchemeGroupVersion) out, err := legacyscheme.Scheme.ConvertToVersion(&pod, v1.SchemeGroupVersion)
if err != nil { if err != nil {
@ -434,7 +434,7 @@ func benchmarkItemsList(b *testing.B, numItems int) v1.PodList {
items := make([]v1.Pod, numItems) items := make([]v1.Pod, numItems)
for i := range items { for i := range items {
var pod api.Pod var pod api.Pod
apiObjectFuzzer.Fuzz(&pod) apiObjectFuzzer.Fill(&pod)
pod.Spec.InitContainers, pod.Status.InitContainerStatuses = nil, nil pod.Spec.InitContainers, pod.Status.InitContainerStatuses = nil, nil
out, err := legacyscheme.Scheme.ConvertToVersion(&pod, v1.SchemeGroupVersion) out, err := legacyscheme.Scheme.ConvertToVersion(&pod, v1.SchemeGroupVersion)
if err != nil { if err != nil {

View File

@ -22,7 +22,7 @@ import (
"testing" "testing"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
fuzz "github.com/google/gofuzz" "sigs.k8s.io/randfill"
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/apitesting/fuzzer" "k8s.io/apimachinery/pkg/api/apitesting/fuzzer"
@ -54,15 +54,15 @@ func doRoundTrip(t *testing.T, internalVersion schema.GroupVersion, externalVers
// because in this test we are simply doing json operations, in which // because in this test we are simply doing json operations, in which
// those disappear. // those disappear.
Funcs( Funcs(
func(s *api.PodSpec, c fuzz.Continue) { func(s *api.PodSpec, c randfill.Continue) {
c.FuzzNoCustom(s) c.FillNoCustom(s)
s.InitContainers = nil s.InitContainers = nil
}, },
func(s *api.PodStatus, c fuzz.Continue) { func(s *api.PodStatus, c randfill.Continue) {
c.FuzzNoCustom(s) c.FillNoCustom(s)
s.InitContainerStatuses = nil s.InitContainerStatuses = nil
}, },
).Fuzz(internalObj) ).Fill(internalObj)
item, err := legacyscheme.Scheme.New(externalVersion.WithKind(kind)) item, err := legacyscheme.Scheme.New(externalVersion.WithKind(kind))
if err != nil { if err != nil {

View File

@ -17,7 +17,7 @@ limitations under the License.
package fuzzer package fuzzer
import ( import (
fuzz "github.com/google/gofuzz" "sigs.k8s.io/randfill"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
@ -27,7 +27,7 @@ import (
// Funcs returns the fuzzer functions for the admission api group. // Funcs returns the fuzzer functions for the admission api group.
var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} { var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
return []interface{}{ return []interface{}{
func(s *runtime.RawExtension, c fuzz.Continue) { func(s *runtime.RawExtension, c randfill.Continue) {
u := &unstructured.Unstructured{Object: map[string]interface{}{ u := &unstructured.Unstructured{Object: map[string]interface{}{
"apiVersion": "unknown.group/unknown", "apiVersion": "unknown.group/unknown",
"kind": "Something", "kind": "Something",

View File

@ -17,7 +17,7 @@ limitations under the License.
package fuzzer package fuzzer
import ( import (
fuzz "github.com/google/gofuzz" "sigs.k8s.io/randfill"
runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer"
@ -27,15 +27,15 @@ import (
// Funcs returns the fuzzer functions for the admissionregistration api group. // Funcs returns the fuzzer functions for the admissionregistration api group.
var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} { var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
return []interface{}{ return []interface{}{
func(obj *admissionregistration.Rule, c fuzz.Continue) { func(obj *admissionregistration.Rule, c randfill.Continue) {
c.FuzzNoCustom(obj) // fuzz self without calling this function again c.FillNoCustom(obj) // fuzz self without calling this function again
if obj.Scope == nil { if obj.Scope == nil {
s := admissionregistration.AllScopes s := admissionregistration.AllScopes
obj.Scope = &s obj.Scope = &s
} }
}, },
func(obj *admissionregistration.ValidatingWebhook, c fuzz.Continue) { func(obj *admissionregistration.ValidatingWebhook, c randfill.Continue) {
c.FuzzNoCustom(obj) // fuzz self without calling this function again c.FillNoCustom(obj) // fuzz self without calling this function again
if obj.FailurePolicy == nil { if obj.FailurePolicy == nil {
p := admissionregistration.FailurePolicyType("Fail") p := admissionregistration.FailurePolicyType("Fail")
obj.FailurePolicy = &p obj.FailurePolicy = &p
@ -54,8 +54,8 @@ var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
} }
obj.AdmissionReviewVersions = []string{"v1beta1"} obj.AdmissionReviewVersions = []string{"v1beta1"}
}, },
func(obj *admissionregistration.MutatingWebhook, c fuzz.Continue) { func(obj *admissionregistration.MutatingWebhook, c randfill.Continue) {
c.FuzzNoCustom(obj) // fuzz self without calling this function again c.FillNoCustom(obj) // fuzz self without calling this function again
if obj.FailurePolicy == nil { if obj.FailurePolicy == nil {
p := admissionregistration.FailurePolicyType("Fail") p := admissionregistration.FailurePolicyType("Fail")
obj.FailurePolicy = &p obj.FailurePolicy = &p
@ -78,28 +78,28 @@ var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
} }
obj.AdmissionReviewVersions = []string{"v1beta1"} obj.AdmissionReviewVersions = []string{"v1beta1"}
}, },
func(obj *admissionregistration.ValidatingAdmissionPolicySpec, c fuzz.Continue) { func(obj *admissionregistration.ValidatingAdmissionPolicySpec, c randfill.Continue) {
c.FuzzNoCustom(obj) // fuzz self without calling this function again c.FillNoCustom(obj) // fuzz self without calling this function again
if obj.FailurePolicy == nil { if obj.FailurePolicy == nil {
p := admissionregistration.FailurePolicyType("Fail") p := admissionregistration.FailurePolicyType("Fail")
obj.FailurePolicy = &p obj.FailurePolicy = &p
} }
}, },
func(obj *admissionregistration.ValidatingAdmissionPolicyBindingSpec, c fuzz.Continue) { func(obj *admissionregistration.ValidatingAdmissionPolicyBindingSpec, c randfill.Continue) {
c.FuzzNoCustom(obj) // fuzz self without calling this function again c.FillNoCustom(obj) // fuzz self without calling this function again
if obj.ValidationActions == nil { if obj.ValidationActions == nil {
obj.ValidationActions = []admissionregistration.ValidationAction{admissionregistration.Deny} obj.ValidationActions = []admissionregistration.ValidationAction{admissionregistration.Deny}
} }
}, },
func(obj *admissionregistration.MatchResources, c fuzz.Continue) { func(obj *admissionregistration.MatchResources, c randfill.Continue) {
c.FuzzNoCustom(obj) // fuzz self without calling this function again c.FillNoCustom(obj) // fuzz self without calling this function again
if obj.MatchPolicy == nil { if obj.MatchPolicy == nil {
m := admissionregistration.MatchPolicyType("Exact") m := admissionregistration.MatchPolicyType("Exact")
obj.MatchPolicy = &m obj.MatchPolicy = &m
} }
}, },
func(obj *admissionregistration.ParamRef, c fuzz.Continue) { func(obj *admissionregistration.ParamRef, c randfill.Continue) {
c.FuzzNoCustom(obj) // fuzz self without calling this function again c.FillNoCustom(obj) // fuzz self without calling this function again
// Populate required field // Populate required field
if obj.ParameterNotFoundAction == nil { if obj.ParameterNotFoundAction == nil {
@ -107,26 +107,26 @@ var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
obj.ParameterNotFoundAction = &v obj.ParameterNotFoundAction = &v
} }
}, },
func(obj *admissionregistration.MutatingAdmissionPolicySpec, c fuzz.Continue) { func(obj *admissionregistration.MutatingAdmissionPolicySpec, c randfill.Continue) {
c.FuzzNoCustom(obj) // fuzz self without calling this function again c.FillNoCustom(obj) // fuzz self without calling this function again
if obj.FailurePolicy == nil { if obj.FailurePolicy == nil {
p := admissionregistration.FailurePolicyType("Fail") p := admissionregistration.FailurePolicyType("Fail")
obj.FailurePolicy = &p obj.FailurePolicy = &p
} }
obj.ReinvocationPolicy = admissionregistration.NeverReinvocationPolicy obj.ReinvocationPolicy = admissionregistration.NeverReinvocationPolicy
}, },
func(obj *admissionregistration.Mutation, c fuzz.Continue) { func(obj *admissionregistration.Mutation, c randfill.Continue) {
c.FuzzNoCustom(obj) // fuzz self without calling this function again c.FillNoCustom(obj) // fuzz self without calling this function again
patchTypes := []admissionregistration.PatchType{admissionregistration.PatchTypeJSONPatch, admissionregistration.PatchTypeApplyConfiguration} patchTypes := []admissionregistration.PatchType{admissionregistration.PatchTypeJSONPatch, admissionregistration.PatchTypeApplyConfiguration}
obj.PatchType = patchTypes[c.Rand.Intn(len(patchTypes))] obj.PatchType = patchTypes[c.Rand.Intn(len(patchTypes))]
if obj.PatchType == admissionregistration.PatchTypeJSONPatch { if obj.PatchType == admissionregistration.PatchTypeJSONPatch {
obj.JSONPatch = &admissionregistration.JSONPatch{} obj.JSONPatch = &admissionregistration.JSONPatch{}
c.Fuzz(&obj.JSONPatch) c.Fill(&obj.JSONPatch)
obj.ApplyConfiguration = nil obj.ApplyConfiguration = nil
} }
if obj.PatchType == admissionregistration.PatchTypeApplyConfiguration { if obj.PatchType == admissionregistration.PatchTypeApplyConfiguration {
obj.ApplyConfiguration = &admissionregistration.ApplyConfiguration{} obj.ApplyConfiguration = &admissionregistration.ApplyConfiguration{}
c.Fuzz(obj.ApplyConfiguration) c.Fill(obj.ApplyConfiguration)
obj.JSONPatch = nil obj.JSONPatch = nil
} }
}, },

View File

@ -19,7 +19,7 @@ package fuzzer
import ( import (
"fmt" "fmt"
fuzz "github.com/google/gofuzz" "sigs.k8s.io/randfill"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
@ -31,13 +31,13 @@ import (
// Funcs returns the fuzzer functions for the apps api group. // Funcs returns the fuzzer functions for the apps api group.
var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} { var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
return []interface{}{ return []interface{}{
func(r *apps.ControllerRevision, c fuzz.Continue) { func(r *apps.ControllerRevision, c randfill.Continue) {
c.FuzzNoCustom(r) c.FillNoCustom(r)
// match the fuzzer default content for runtime.Object // match the fuzzer default content for runtime.Object
r.Data = runtime.RawExtension{Raw: []byte(`{"apiVersion":"unknown.group/unknown","kind":"Something","someKey":"someValue"}`)} r.Data = runtime.RawExtension{Raw: []byte(`{"apiVersion":"unknown.group/unknown","kind":"Something","someKey":"someValue"}`)}
}, },
func(s *apps.StatefulSet, c fuzz.Continue) { func(s *apps.StatefulSet, c randfill.Continue) {
c.FuzzNoCustom(s) // fuzz self without calling this function again c.FillNoCustom(s) // fuzz self without calling this function again
// match defaulter // match defaulter
if len(s.Spec.PodManagementPolicy) == 0 { if len(s.Spec.PodManagementPolicy) == 0 {
@ -72,8 +72,8 @@ var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
s.Labels = s.Spec.Template.Labels s.Labels = s.Spec.Template.Labels
} }
}, },
func(j *apps.Deployment, c fuzz.Continue) { func(j *apps.Deployment, c randfill.Continue) {
c.FuzzNoCustom(j) c.FillNoCustom(j)
// match defaulting // match defaulting
if j.Spec.Selector == nil { if j.Spec.Selector == nil {
@ -83,15 +83,15 @@ var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
j.Labels = j.Spec.Template.Labels j.Labels = j.Spec.Template.Labels
} }
}, },
func(j *apps.DeploymentSpec, c fuzz.Continue) { func(j *apps.DeploymentSpec, c randfill.Continue) {
c.FuzzNoCustom(j) // fuzz self without calling this function again c.FillNoCustom(j) // fuzz self without calling this function again
rhl := int32(c.Rand.Int31()) rhl := int32(c.Rand.Int31())
pds := int32(c.Rand.Int31()) pds := int32(c.Rand.Int31())
j.RevisionHistoryLimit = &rhl j.RevisionHistoryLimit = &rhl
j.ProgressDeadlineSeconds = &pds j.ProgressDeadlineSeconds = &pds
}, },
func(j *apps.DeploymentStrategy, c fuzz.Continue) { func(j *apps.DeploymentStrategy, c randfill.Continue) {
c.FuzzNoCustom(j) // fuzz self without calling this function again c.FillNoCustom(j) // fuzz self without calling this function again
// Ensure that strategyType is one of valid values. // Ensure that strategyType is one of valid values.
strategyTypes := []apps.DeploymentStrategyType{apps.RecreateDeploymentStrategyType, apps.RollingUpdateDeploymentStrategyType} strategyTypes := []apps.DeploymentStrategyType{apps.RecreateDeploymentStrategyType, apps.RollingUpdateDeploymentStrategyType}
j.Type = strategyTypes[c.Rand.Intn(len(strategyTypes))] j.Type = strategyTypes[c.Rand.Intn(len(strategyTypes))]
@ -99,7 +99,7 @@ var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
j.RollingUpdate = nil j.RollingUpdate = nil
} else { } else {
rollingUpdate := apps.RollingUpdateDeployment{} rollingUpdate := apps.RollingUpdateDeployment{}
if c.RandBool() { if c.Bool() {
rollingUpdate.MaxUnavailable = intstr.FromInt32(c.Rand.Int31()) rollingUpdate.MaxUnavailable = intstr.FromInt32(c.Rand.Int31())
rollingUpdate.MaxSurge = intstr.FromInt32(c.Rand.Int31()) rollingUpdate.MaxSurge = intstr.FromInt32(c.Rand.Int31())
} else { } else {
@ -108,8 +108,8 @@ var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
j.RollingUpdate = &rollingUpdate j.RollingUpdate = &rollingUpdate
} }
}, },
func(j *apps.DaemonSet, c fuzz.Continue) { func(j *apps.DaemonSet, c randfill.Continue) {
c.FuzzNoCustom(j) c.FillNoCustom(j)
// match defaulter // match defaulter
j.Spec.Template.Generation = 0 j.Spec.Template.Generation = 0
@ -117,13 +117,13 @@ var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
j.ObjectMeta.Labels = j.Spec.Template.ObjectMeta.Labels j.ObjectMeta.Labels = j.Spec.Template.ObjectMeta.Labels
} }
}, },
func(j *apps.DaemonSetSpec, c fuzz.Continue) { func(j *apps.DaemonSetSpec, c randfill.Continue) {
c.FuzzNoCustom(j) // fuzz self without calling this function again c.FillNoCustom(j) // fuzz self without calling this function again
rhl := int32(c.Rand.Int31()) rhl := int32(c.Rand.Int31())
j.RevisionHistoryLimit = &rhl j.RevisionHistoryLimit = &rhl
}, },
func(j *apps.DaemonSetUpdateStrategy, c fuzz.Continue) { func(j *apps.DaemonSetUpdateStrategy, c randfill.Continue) {
c.FuzzNoCustom(j) // fuzz self without calling this function again c.FillNoCustom(j) // fuzz self without calling this function again
// Ensure that strategyType is one of valid values. // Ensure that strategyType is one of valid values.
strategyTypes := []apps.DaemonSetUpdateStrategyType{apps.RollingUpdateDaemonSetStrategyType, apps.OnDeleteDaemonSetStrategyType} strategyTypes := []apps.DaemonSetUpdateStrategyType{apps.RollingUpdateDaemonSetStrategyType, apps.OnDeleteDaemonSetStrategyType}
j.Type = strategyTypes[c.Rand.Intn(len(strategyTypes))] j.Type = strategyTypes[c.Rand.Intn(len(strategyTypes))]
@ -131,8 +131,8 @@ var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
j.RollingUpdate = nil j.RollingUpdate = nil
} else { } else {
rollingUpdate := apps.RollingUpdateDaemonSet{} rollingUpdate := apps.RollingUpdateDaemonSet{}
if c.RandBool() { if c.Bool() {
if c.RandBool() { if c.Bool() {
rollingUpdate.MaxUnavailable = intstr.FromInt32(c.Rand.Int31()) rollingUpdate.MaxUnavailable = intstr.FromInt32(c.Rand.Int31())
rollingUpdate.MaxSurge = intstr.FromInt32(c.Rand.Int31()) rollingUpdate.MaxSurge = intstr.FromInt32(c.Rand.Int31())
} else { } else {
@ -143,8 +143,8 @@ var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
j.RollingUpdate = &rollingUpdate j.RollingUpdate = &rollingUpdate
} }
}, },
func(j *apps.ReplicaSet, c fuzz.Continue) { func(j *apps.ReplicaSet, c randfill.Continue) {
c.FuzzNoCustom(j) c.FillNoCustom(j)
// match defaulter // match defaulter
if j.Spec.Selector == nil { if j.Spec.Selector == nil {

View File

@ -17,7 +17,7 @@ limitations under the License.
package fuzzer package fuzzer
import ( import (
fuzz "github.com/google/gofuzz" "sigs.k8s.io/randfill"
"k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -30,22 +30,22 @@ import (
// Funcs returns the fuzzer functions for the autoscaling api group. // Funcs returns the fuzzer functions for the autoscaling api group.
var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} { var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
return []interface{}{ return []interface{}{
func(s *autoscaling.ScaleStatus, c fuzz.Continue) { func(s *autoscaling.ScaleStatus, c randfill.Continue) {
c.FuzzNoCustom(s) // fuzz self without calling this function again c.FillNoCustom(s) // fuzz self without calling this function again
// ensure we have a valid selector // ensure we have a valid selector
metaSelector := &metav1.LabelSelector{} metaSelector := &metav1.LabelSelector{}
c.Fuzz(metaSelector) c.Fill(metaSelector)
labelSelector, _ := metav1.LabelSelectorAsSelector(metaSelector) labelSelector, _ := metav1.LabelSelectorAsSelector(metaSelector)
s.Selector = labelSelector.String() s.Selector = labelSelector.String()
}, },
func(s *autoscaling.HorizontalPodAutoscalerSpec, c fuzz.Continue) { func(s *autoscaling.HorizontalPodAutoscalerSpec, c randfill.Continue) {
c.FuzzNoCustom(s) // fuzz self without calling this function again c.FillNoCustom(s) // fuzz self without calling this function again
s.MinReplicas = pointer.Int32(c.Rand.Int31()) s.MinReplicas = pointer.Int32(c.Rand.Int31())
randomQuantity := func() resource.Quantity { randomQuantity := func() resource.Quantity {
var q resource.Quantity var q resource.Quantity
c.Fuzz(&q) c.Fill(&q)
// precalc the string for benchmarking purposes // precalc the string for benchmarking purposes
_ = q.String() _ = q.String()
return q return q
@ -53,10 +53,10 @@ var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
var podMetricID autoscaling.MetricIdentifier var podMetricID autoscaling.MetricIdentifier
var objMetricID autoscaling.MetricIdentifier var objMetricID autoscaling.MetricIdentifier
c.Fuzz(&podMetricID) c.Fill(&podMetricID)
c.Fuzz(&objMetricID) c.Fill(&objMetricID)
targetUtilization := int32(c.RandUint64()) targetUtilization := int32(c.Uint64())
averageValue := randomQuantity() averageValue := randomQuantity()
s.Metrics = []autoscaling.MetricSpec{ s.Metrics = []autoscaling.MetricSpec{
{ {
@ -90,7 +90,7 @@ var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
}, },
}, },
} }
stabilizationWindow := int32(c.RandUint64()) stabilizationWindow := int32(c.Uint64())
maxPolicy := autoscaling.MaxPolicySelect maxPolicy := autoscaling.MaxPolicySelect
minPolicy := autoscaling.MinPolicySelect minPolicy := autoscaling.MinPolicySelect
s.Behavior = &autoscaling.HorizontalPodAutoscalerBehavior{ s.Behavior = &autoscaling.HorizontalPodAutoscalerBehavior{
@ -100,13 +100,13 @@ var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
Policies: []autoscaling.HPAScalingPolicy{ Policies: []autoscaling.HPAScalingPolicy{
{ {
Type: autoscaling.PodsScalingPolicy, Type: autoscaling.PodsScalingPolicy,
Value: int32(c.RandUint64()), Value: int32(c.Uint64()),
PeriodSeconds: int32(c.RandUint64()), PeriodSeconds: int32(c.Uint64()),
}, },
{ {
Type: autoscaling.PercentScalingPolicy, Type: autoscaling.PercentScalingPolicy,
Value: int32(c.RandUint64()), Value: int32(c.Uint64()),
PeriodSeconds: int32(c.RandUint64()), PeriodSeconds: int32(c.Uint64()),
}, },
}, },
}, },
@ -116,35 +116,35 @@ var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
Policies: []autoscaling.HPAScalingPolicy{ Policies: []autoscaling.HPAScalingPolicy{
{ {
Type: autoscaling.PodsScalingPolicy, Type: autoscaling.PodsScalingPolicy,
Value: int32(c.RandUint64()), Value: int32(c.Uint64()),
PeriodSeconds: int32(c.RandUint64()), PeriodSeconds: int32(c.Uint64()),
}, },
{ {
Type: autoscaling.PercentScalingPolicy, Type: autoscaling.PercentScalingPolicy,
Value: int32(c.RandUint64()), Value: int32(c.Uint64()),
PeriodSeconds: int32(c.RandUint64()), PeriodSeconds: int32(c.Uint64()),
}, },
}, },
}, },
} }
}, },
func(s *autoscaling.HorizontalPodAutoscalerStatus, c fuzz.Continue) { func(s *autoscaling.HorizontalPodAutoscalerStatus, c randfill.Continue) {
c.FuzzNoCustom(s) // fuzz self without calling this function again c.FillNoCustom(s) // fuzz self without calling this function again
randomQuantity := func() resource.Quantity { randomQuantity := func() resource.Quantity {
var q resource.Quantity var q resource.Quantity
c.Fuzz(&q) c.Fill(&q)
// precalc the string for benchmarking purposes // precalc the string for benchmarking purposes
_ = q.String() _ = q.String()
return q return q
} }
averageValue := randomQuantity() averageValue := randomQuantity()
currentUtilization := int32(c.RandUint64()) currentUtilization := int32(c.Uint64())
s.CurrentMetrics = []autoscaling.MetricStatus{ s.CurrentMetrics = []autoscaling.MetricStatus{
{ {
Type: autoscaling.PodsMetricSourceType, Type: autoscaling.PodsMetricSourceType,
Pods: &autoscaling.PodsMetricStatus{ Pods: &autoscaling.PodsMetricStatus{
Metric: autoscaling.MetricIdentifier{ Metric: autoscaling.MetricIdentifier{
Name: c.RandString(), Name: c.String(0),
}, },
Current: autoscaling.MetricValueStatus{ Current: autoscaling.MetricValueStatus{
AverageValue: &averageValue, AverageValue: &averageValue,

View File

@ -19,73 +19,73 @@ package fuzzer
import ( import (
"math" "math"
fuzz "github.com/google/gofuzz"
runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/kubernetes/pkg/apis/batch" "k8s.io/kubernetes/pkg/apis/batch"
api "k8s.io/kubernetes/pkg/apis/core" api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/utils/pointer" "k8s.io/utils/pointer"
"sigs.k8s.io/randfill"
) )
// Funcs returns the fuzzer functions for the batch api group. // Funcs returns the fuzzer functions for the batch api group.
var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} { var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
return []interface{}{ return []interface{}{
func(j *batch.Job, c fuzz.Continue) { func(j *batch.Job, c randfill.Continue) {
c.FuzzNoCustom(j) // fuzz self without calling this function again c.FillNoCustom(j) // fuzz self without calling this function again
// match defaulting // match defaulting
if len(j.Labels) == 0 { if len(j.Labels) == 0 {
j.Labels = j.Spec.Template.Labels j.Labels = j.Spec.Template.Labels
} }
}, },
func(j *batch.JobSpec, c fuzz.Continue) { func(j *batch.JobSpec, c randfill.Continue) {
c.FuzzNoCustom(j) // fuzz self without calling this function again c.FillNoCustom(j) // fuzz self without calling this function again
completions := int32(c.Rand.Int31()) completions := int32(c.Rand.Int31())
parallelism := int32(c.Rand.Int31()) parallelism := int32(c.Rand.Int31())
backoffLimit := int32(c.Rand.Int31()) backoffLimit := int32(c.Rand.Int31())
j.Completions = &completions j.Completions = &completions
j.Parallelism = &parallelism j.Parallelism = &parallelism
j.BackoffLimit = &backoffLimit j.BackoffLimit = &backoffLimit
j.ManualSelector = pointer.Bool(c.RandBool()) j.ManualSelector = pointer.Bool(c.Bool())
mode := batch.NonIndexedCompletion mode := batch.NonIndexedCompletion
if c.RandBool() { if c.Bool() {
mode = batch.IndexedCompletion mode = batch.IndexedCompletion
j.BackoffLimitPerIndex = pointer.Int32(c.Rand.Int31()) j.BackoffLimitPerIndex = pointer.Int32(c.Rand.Int31())
j.MaxFailedIndexes = pointer.Int32(c.Rand.Int31()) j.MaxFailedIndexes = pointer.Int32(c.Rand.Int31())
} }
if c.RandBool() { if c.Bool() {
j.BackoffLimit = pointer.Int32(math.MaxInt32) j.BackoffLimit = pointer.Int32(math.MaxInt32)
} }
j.CompletionMode = &mode j.CompletionMode = &mode
// We're fuzzing the internal JobSpec type, not the v1 type, so we don't // We're fuzzing the internal JobSpec type, not the v1 type, so we don't
// need to fuzz the nil value. // need to fuzz the nil value.
j.Suspend = pointer.Bool(c.RandBool()) j.Suspend = pointer.Bool(c.Bool())
podReplacementPolicy := batch.TerminatingOrFailed podReplacementPolicy := batch.TerminatingOrFailed
if c.RandBool() { if c.Bool() {
podReplacementPolicy = batch.Failed podReplacementPolicy = batch.Failed
} }
j.PodReplacementPolicy = &podReplacementPolicy j.PodReplacementPolicy = &podReplacementPolicy
if c.RandBool() { if c.Bool() {
c.Fuzz(j.ManagedBy) c.Fill(j.ManagedBy)
} }
}, },
func(sj *batch.CronJobSpec, c fuzz.Continue) { func(sj *batch.CronJobSpec, c randfill.Continue) {
c.FuzzNoCustom(sj) c.FillNoCustom(sj)
suspend := c.RandBool() suspend := c.Bool()
sj.Suspend = &suspend sj.Suspend = &suspend
sds := int64(c.RandUint64()) sds := int64(c.Uint64())
sj.StartingDeadlineSeconds = &sds sj.StartingDeadlineSeconds = &sds
sj.Schedule = c.RandString() sj.Schedule = c.String(0)
successfulJobsHistoryLimit := int32(c.Rand.Int31()) successfulJobsHistoryLimit := int32(c.Rand.Int31())
sj.SuccessfulJobsHistoryLimit = &successfulJobsHistoryLimit sj.SuccessfulJobsHistoryLimit = &successfulJobsHistoryLimit
failedJobsHistoryLimit := int32(c.Rand.Int31()) failedJobsHistoryLimit := int32(c.Rand.Int31())
sj.FailedJobsHistoryLimit = &failedJobsHistoryLimit sj.FailedJobsHistoryLimit = &failedJobsHistoryLimit
}, },
func(cp *batch.ConcurrencyPolicy, c fuzz.Continue) { func(cp *batch.ConcurrencyPolicy, c randfill.Continue) {
policies := []batch.ConcurrencyPolicy{batch.AllowConcurrent, batch.ForbidConcurrent, batch.ReplaceConcurrent} policies := []batch.ConcurrencyPolicy{batch.AllowConcurrent, batch.ForbidConcurrent, batch.ReplaceConcurrent}
*cp = policies[c.Rand.Intn(len(policies))] *cp = policies[c.Rand.Intn(len(policies))]
}, },
func(p *batch.PodFailurePolicyOnPodConditionsPattern, c fuzz.Continue) { func(p *batch.PodFailurePolicyOnPodConditionsPattern, c randfill.Continue) {
c.FuzzNoCustom(p) c.FillNoCustom(p)
if p.Status == "" { if p.Status == "" {
p.Status = api.ConditionTrue p.Status = api.ConditionTrue
} }

View File

@ -19,7 +19,7 @@ package fuzzer
import ( import (
"time" "time"
fuzz "github.com/google/gofuzz" "sigs.k8s.io/randfill"
runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/client-go/util/certificate/csr" "k8s.io/client-go/util/certificate/csr"
@ -30,14 +30,14 @@ import (
// Funcs returns the fuzzer functions for the certificates api group. // Funcs returns the fuzzer functions for the certificates api group.
var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} { var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
return []interface{}{ return []interface{}{
func(obj *certificates.CertificateSigningRequestSpec, c fuzz.Continue) { func(obj *certificates.CertificateSigningRequestSpec, c randfill.Continue) {
c.FuzzNoCustom(obj) // fuzz self without calling this function again c.FillNoCustom(obj) // fuzz self without calling this function again
obj.Usages = []certificates.KeyUsage{certificates.UsageKeyEncipherment} obj.Usages = []certificates.KeyUsage{certificates.UsageKeyEncipherment}
obj.SignerName = "example.com/custom-sample-signer" obj.SignerName = "example.com/custom-sample-signer"
obj.ExpirationSeconds = csr.DurationToExpirationSeconds(time.Hour + time.Minute + time.Second) obj.ExpirationSeconds = csr.DurationToExpirationSeconds(time.Hour + time.Minute + time.Second)
}, },
func(obj *certificates.CertificateSigningRequestCondition, c fuzz.Continue) { func(obj *certificates.CertificateSigningRequestCondition, c randfill.Continue) {
c.FuzzNoCustom(obj) // fuzz self without calling this function again c.FillNoCustom(obj) // fuzz self without calling this function again
if len(obj.Status) == 0 { if len(obj.Status) == 0 {
obj.Status = api.ConditionTrue obj.Status = api.ConditionTrue
} }

View File

@ -21,7 +21,7 @@ import (
"strconv" "strconv"
"time" "time"
fuzz "github.com/google/gofuzz" "sigs.k8s.io/randfill"
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/api/resource"
@ -37,45 +37,45 @@ import (
// Funcs returns the fuzzer functions for the core group. // Funcs returns the fuzzer functions for the core group.
var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} { var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
return []interface{}{ return []interface{}{
func(q *resource.Quantity, c fuzz.Continue) { func(q *resource.Quantity, c randfill.Continue) {
*q = *resource.NewQuantity(c.Int63n(1000), resource.DecimalExponent) *q = *resource.NewQuantity(c.Int63n(1000), resource.DecimalExponent)
}, },
func(j *core.ObjectReference, c fuzz.Continue) { func(j *core.ObjectReference, c randfill.Continue) {
// We have to customize the randomization of TypeMetas because their // We have to customize the randomization of TypeMetas because their
// APIVersion and Kind must remain blank in memory. // APIVersion and Kind must remain blank in memory.
j.APIVersion = c.RandString() j.APIVersion = c.String(0)
j.Kind = c.RandString() j.Kind = c.String(0)
j.Namespace = c.RandString() j.Namespace = c.String(0)
j.Name = c.RandString() j.Name = c.String(0)
j.ResourceVersion = strconv.FormatUint(c.RandUint64(), 10) j.ResourceVersion = strconv.FormatUint(c.Uint64(), 10)
j.FieldPath = c.RandString() j.FieldPath = c.String(0)
}, },
func(j *core.PodExecOptions, c fuzz.Continue) { func(j *core.PodExecOptions, c randfill.Continue) {
j.Stdout = true j.Stdout = true
j.Stderr = true j.Stderr = true
}, },
func(j *core.PodAttachOptions, c fuzz.Continue) { func(j *core.PodAttachOptions, c randfill.Continue) {
j.Stdout = true j.Stdout = true
j.Stderr = true j.Stderr = true
}, },
func(j *core.PodPortForwardOptions, c fuzz.Continue) { func(j *core.PodPortForwardOptions, c randfill.Continue) {
if c.RandBool() { if c.Bool() {
j.Ports = make([]int32, c.Intn(10)) j.Ports = make([]int32, c.Intn(10))
for i := range j.Ports { for i := range j.Ports {
j.Ports[i] = c.Int31n(65535) j.Ports[i] = c.Int31n(65535)
} }
} }
}, },
func(s *core.PodSpec, c fuzz.Continue) { func(s *core.PodSpec, c randfill.Continue) {
c.FuzzNoCustom(s) c.FillNoCustom(s)
// has a default value // has a default value
ttl := int64(30) ttl := int64(30)
if c.RandBool() { if c.Bool() {
ttl = int64(c.Uint32()) ttl = int64(c.Uint32())
} }
s.TerminationGracePeriodSeconds = &ttl s.TerminationGracePeriodSeconds = &ttl
c.Fuzz(s.SecurityContext) c.Fill(s.SecurityContext)
if s.SecurityContext == nil { if s.SecurityContext == nil {
s.SecurityContext = new(core.PodSecurityContext) s.SecurityContext = new(core.PodSecurityContext)
@ -91,20 +91,20 @@ var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
s.EnableServiceLinks = &enableServiceLinks s.EnableServiceLinks = &enableServiceLinks
} }
}, },
func(s *core.PodStatus, c fuzz.Continue) { func(s *core.PodStatus, c randfill.Continue) {
c.Fuzz(&s) c.Fill(&s)
s.HostIPs = []core.HostIP{{IP: s.HostIP}} s.HostIPs = []core.HostIP{{IP: s.HostIP}}
}, },
func(j *core.PodPhase, c fuzz.Continue) { func(j *core.PodPhase, c randfill.Continue) {
statuses := []core.PodPhase{core.PodPending, core.PodRunning, core.PodFailed, core.PodUnknown} statuses := []core.PodPhase{core.PodPending, core.PodRunning, core.PodFailed, core.PodUnknown}
*j = statuses[c.Rand.Intn(len(statuses))] *j = statuses[c.Rand.Intn(len(statuses))]
}, },
func(j *core.Binding, c fuzz.Continue) { func(j *core.Binding, c randfill.Continue) {
c.Fuzz(&j.ObjectMeta) c.Fill(&j.ObjectMeta)
j.Target.Name = c.RandString() j.Target.Name = c.String(0)
}, },
func(j *core.ReplicationController, c fuzz.Continue) { func(j *core.ReplicationController, c randfill.Continue) {
c.FuzzNoCustom(j) c.FillNoCustom(j)
// match defaulting // match defaulting
if j.Spec.Template != nil { if j.Spec.Template != nil {
@ -116,21 +116,21 @@ var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
} }
} }
}, },
func(j *core.ReplicationControllerSpec, c fuzz.Continue) { func(j *core.ReplicationControllerSpec, c randfill.Continue) {
c.FuzzNoCustom(j) // fuzz self without calling this function again c.FillNoCustom(j) // fuzz self without calling this function again
//j.TemplateRef = nil // this is required for round trip //j.TemplateRef = nil // this is required for round trip
}, },
func(j *core.List, c fuzz.Continue) { func(j *core.List, c randfill.Continue) {
c.FuzzNoCustom(j) // fuzz self without calling this function again c.FillNoCustom(j) // fuzz self without calling this function again
// TODO: uncomment when round trip starts from a versioned object // TODO: uncomment when round trip starts from a versioned object
if false { //j.Items == nil { if false { //j.Items == nil {
j.Items = []runtime.Object{} j.Items = []runtime.Object{}
} }
}, },
func(q *core.ResourceRequirements, c fuzz.Continue) { func(q *core.ResourceRequirements, c randfill.Continue) {
randomQuantity := func() resource.Quantity { randomQuantity := func() resource.Quantity {
var q resource.Quantity var q resource.Quantity
c.Fuzz(&q) c.Fill(&q)
// precalc the string for benchmarking purposes // precalc the string for benchmarking purposes
_ = q.String() _ = q.String()
return q return q
@ -147,9 +147,9 @@ var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
q.Limits[core.ResourceStorage] = storageLimit.DeepCopy() q.Limits[core.ResourceStorage] = storageLimit.DeepCopy()
q.Requests[core.ResourceStorage] = storageLimit.DeepCopy() q.Requests[core.ResourceStorage] = storageLimit.DeepCopy()
}, },
func(q *core.LimitRangeItem, c fuzz.Continue) { func(q *core.LimitRangeItem, c randfill.Continue) {
var cpuLimit resource.Quantity var cpuLimit resource.Quantity
c.Fuzz(&cpuLimit) c.Fill(&cpuLimit)
q.Type = core.LimitTypeContainer q.Type = core.LimitTypeContainer
q.Default = make(core.ResourceList) q.Default = make(core.ResourceList)
@ -167,79 +167,79 @@ var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
q.MaxLimitRequestRatio = make(core.ResourceList) q.MaxLimitRequestRatio = make(core.ResourceList)
q.MaxLimitRequestRatio[core.ResourceCPU] = resource.MustParse("10") q.MaxLimitRequestRatio[core.ResourceCPU] = resource.MustParse("10")
}, },
func(p *core.PullPolicy, c fuzz.Continue) { func(p *core.PullPolicy, c randfill.Continue) {
policies := []core.PullPolicy{core.PullAlways, core.PullNever, core.PullIfNotPresent} policies := []core.PullPolicy{core.PullAlways, core.PullNever, core.PullIfNotPresent}
*p = policies[c.Rand.Intn(len(policies))] *p = policies[c.Rand.Intn(len(policies))]
}, },
func(rp *core.RestartPolicy, c fuzz.Continue) { func(rp *core.RestartPolicy, c randfill.Continue) {
policies := []core.RestartPolicy{core.RestartPolicyAlways, core.RestartPolicyNever, core.RestartPolicyOnFailure} policies := []core.RestartPolicy{core.RestartPolicyAlways, core.RestartPolicyNever, core.RestartPolicyOnFailure}
*rp = policies[c.Rand.Intn(len(policies))] *rp = policies[c.Rand.Intn(len(policies))]
}, },
// core.DownwardAPIVolumeFile needs to have a specific func since FieldRef has to be // core.DownwardAPIVolumeFile needs to have a specific func since FieldRef has to be
// defaulted to a version otherwise roundtrip will fail // defaulted to a version otherwise roundtrip will fail
func(m *core.DownwardAPIVolumeFile, c fuzz.Continue) { func(m *core.DownwardAPIVolumeFile, c randfill.Continue) {
m.Path = c.RandString() m.Path = c.String(0)
versions := []string{"v1"} versions := []string{"v1"}
m.FieldRef = &core.ObjectFieldSelector{} m.FieldRef = &core.ObjectFieldSelector{}
m.FieldRef.APIVersion = versions[c.Rand.Intn(len(versions))] m.FieldRef.APIVersion = versions[c.Rand.Intn(len(versions))]
m.FieldRef.FieldPath = c.RandString() m.FieldRef.FieldPath = c.String(0)
c.Fuzz(m.Mode) c.Fill(m.Mode)
if m.Mode != nil { if m.Mode != nil {
*m.Mode &= 0777 *m.Mode &= 0777
} }
}, },
func(s *core.SecretVolumeSource, c fuzz.Continue) { func(s *core.SecretVolumeSource, c randfill.Continue) {
c.FuzzNoCustom(s) // fuzz self without calling this function again c.FillNoCustom(s) // fuzz self without calling this function again
if c.RandBool() { if c.Bool() {
opt := c.RandBool() opt := c.Bool()
s.Optional = &opt s.Optional = &opt
} }
// DefaultMode should always be set, it has a default // DefaultMode should always be set, it has a default
// value and it is expected to be between 0 and 0777 // value and it is expected to be between 0 and 0777
var mode int32 var mode int32
c.Fuzz(&mode) c.Fill(&mode)
mode &= 0777 mode &= 0777
s.DefaultMode = &mode s.DefaultMode = &mode
}, },
func(cm *core.ConfigMapVolumeSource, c fuzz.Continue) { func(cm *core.ConfigMapVolumeSource, c randfill.Continue) {
c.FuzzNoCustom(cm) // fuzz self without calling this function again c.FillNoCustom(cm) // fuzz self without calling this function again
if c.RandBool() { if c.Bool() {
opt := c.RandBool() opt := c.Bool()
cm.Optional = &opt cm.Optional = &opt
} }
// DefaultMode should always be set, it has a default // DefaultMode should always be set, it has a default
// value and it is expected to be between 0 and 0777 // value and it is expected to be between 0 and 0777
var mode int32 var mode int32
c.Fuzz(&mode) c.Fill(&mode)
mode &= 0777 mode &= 0777
cm.DefaultMode = &mode cm.DefaultMode = &mode
}, },
func(d *core.DownwardAPIVolumeSource, c fuzz.Continue) { func(d *core.DownwardAPIVolumeSource, c randfill.Continue) {
c.FuzzNoCustom(d) // fuzz self without calling this function again c.FillNoCustom(d) // fuzz self without calling this function again
// DefaultMode should always be set, it has a default // DefaultMode should always be set, it has a default
// value and it is expected to be between 0 and 0777 // value and it is expected to be between 0 and 0777
var mode int32 var mode int32
c.Fuzz(&mode) c.Fill(&mode)
mode &= 0777 mode &= 0777
d.DefaultMode = &mode d.DefaultMode = &mode
}, },
func(s *core.ProjectedVolumeSource, c fuzz.Continue) { func(s *core.ProjectedVolumeSource, c randfill.Continue) {
c.FuzzNoCustom(s) // fuzz self without calling this function again c.FillNoCustom(s) // fuzz self without calling this function again
// DefaultMode should always be set, it has a default // DefaultMode should always be set, it has a default
// value and it is expected to be between 0 and 0777 // value and it is expected to be between 0 and 0777
var mode int32 var mode int32
c.Fuzz(&mode) c.Fill(&mode)
mode &= 0777 mode &= 0777
s.DefaultMode = &mode s.DefaultMode = &mode
}, },
func(k *core.KeyToPath, c fuzz.Continue) { func(k *core.KeyToPath, c randfill.Continue) {
c.FuzzNoCustom(k) // fuzz self without calling this function again c.FillNoCustom(k) // fuzz self without calling this function again
k.Key = c.RandString() k.Key = c.String(0)
k.Path = c.RandString() k.Path = c.String(0)
// Mode is not mandatory, but if it is set, it should be // Mode is not mandatory, but if it is set, it should be
// a value between 0 and 0777 // a value between 0 and 0777
@ -247,76 +247,76 @@ var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
*k.Mode &= 0777 *k.Mode &= 0777
} }
}, },
func(vs *core.VolumeSource, c fuzz.Continue) { func(vs *core.VolumeSource, c randfill.Continue) {
// Exactly one of the fields must be set. // Exactly one of the fields must be set.
v := reflect.ValueOf(vs).Elem() v := reflect.ValueOf(vs).Elem()
i := int(c.RandUint64() % uint64(v.NumField())) i := int(c.Uint64() % uint64(v.NumField()))
t := v.Field(i).Addr() t := v.Field(i).Addr()
for v.Field(i).IsNil() { for v.Field(i).IsNil() {
c.Fuzz(t.Interface()) c.Fill(t.Interface())
} }
}, },
func(i *core.ISCSIVolumeSource, c fuzz.Continue) { func(i *core.ISCSIVolumeSource, c randfill.Continue) {
i.ISCSIInterface = c.RandString() i.ISCSIInterface = c.String(0)
if i.ISCSIInterface == "" { if i.ISCSIInterface == "" {
i.ISCSIInterface = "default" i.ISCSIInterface = "default"
} }
}, },
func(i *core.ISCSIPersistentVolumeSource, c fuzz.Continue) { func(i *core.ISCSIPersistentVolumeSource, c randfill.Continue) {
i.ISCSIInterface = c.RandString() i.ISCSIInterface = c.String(0)
if i.ISCSIInterface == "" { if i.ISCSIInterface == "" {
i.ISCSIInterface = "default" i.ISCSIInterface = "default"
} }
}, },
func(i *core.PersistentVolumeClaimSpec, c fuzz.Continue) { func(i *core.PersistentVolumeClaimSpec, c randfill.Continue) {
// Match defaulting in pkg/apis/core/v1/defaults.go. // Match defaulting in pkg/apis/core/v1/defaults.go.
volumeMode := core.PersistentVolumeMode(c.RandString()) volumeMode := core.PersistentVolumeMode(c.String(0))
if volumeMode == "" { if volumeMode == "" {
volumeMode = core.PersistentVolumeFilesystem volumeMode = core.PersistentVolumeFilesystem
} }
i.VolumeMode = &volumeMode i.VolumeMode = &volumeMode
}, },
func(d *core.DNSPolicy, c fuzz.Continue) { func(d *core.DNSPolicy, c randfill.Continue) {
policies := []core.DNSPolicy{core.DNSClusterFirst, core.DNSDefault} policies := []core.DNSPolicy{core.DNSClusterFirst, core.DNSDefault}
*d = policies[c.Rand.Intn(len(policies))] *d = policies[c.Rand.Intn(len(policies))]
}, },
func(p *core.Protocol, c fuzz.Continue) { func(p *core.Protocol, c randfill.Continue) {
protocols := []core.Protocol{core.ProtocolTCP, core.ProtocolUDP, core.ProtocolSCTP} protocols := []core.Protocol{core.ProtocolTCP, core.ProtocolUDP, core.ProtocolSCTP}
*p = protocols[c.Rand.Intn(len(protocols))] *p = protocols[c.Rand.Intn(len(protocols))]
}, },
func(p *core.ServiceAffinity, c fuzz.Continue) { func(p *core.ServiceAffinity, c randfill.Continue) {
types := []core.ServiceAffinity{core.ServiceAffinityClientIP, core.ServiceAffinityNone} types := []core.ServiceAffinity{core.ServiceAffinityClientIP, core.ServiceAffinityNone}
*p = types[c.Rand.Intn(len(types))] *p = types[c.Rand.Intn(len(types))]
}, },
func(p *core.ServiceType, c fuzz.Continue) { func(p *core.ServiceType, c randfill.Continue) {
types := []core.ServiceType{core.ServiceTypeClusterIP, core.ServiceTypeNodePort, core.ServiceTypeLoadBalancer} types := []core.ServiceType{core.ServiceTypeClusterIP, core.ServiceTypeNodePort, core.ServiceTypeLoadBalancer}
*p = types[c.Rand.Intn(len(types))] *p = types[c.Rand.Intn(len(types))]
}, },
func(p *core.IPFamily, c fuzz.Continue) { func(p *core.IPFamily, c randfill.Continue) {
types := []core.IPFamily{core.IPv4Protocol, core.IPv6Protocol} types := []core.IPFamily{core.IPv4Protocol, core.IPv6Protocol}
selected := types[c.Rand.Intn(len(types))] selected := types[c.Rand.Intn(len(types))]
*p = selected *p = selected
}, },
func(p *core.ServiceExternalTrafficPolicy, c fuzz.Continue) { func(p *core.ServiceExternalTrafficPolicy, c randfill.Continue) {
types := []core.ServiceExternalTrafficPolicy{core.ServiceExternalTrafficPolicyCluster, core.ServiceExternalTrafficPolicyLocal} types := []core.ServiceExternalTrafficPolicy{core.ServiceExternalTrafficPolicyCluster, core.ServiceExternalTrafficPolicyLocal}
*p = types[c.Rand.Intn(len(types))] *p = types[c.Rand.Intn(len(types))]
}, },
func(p *core.ServiceInternalTrafficPolicy, c fuzz.Continue) { func(p *core.ServiceInternalTrafficPolicy, c randfill.Continue) {
types := []core.ServiceInternalTrafficPolicy{core.ServiceInternalTrafficPolicyCluster, core.ServiceInternalTrafficPolicyLocal} types := []core.ServiceInternalTrafficPolicy{core.ServiceInternalTrafficPolicyCluster, core.ServiceInternalTrafficPolicyLocal}
*p = types[c.Rand.Intn(len(types))] *p = types[c.Rand.Intn(len(types))]
}, },
func(ct *core.Container, c fuzz.Continue) { func(ct *core.Container, c randfill.Continue) {
c.FuzzNoCustom(ct) // fuzz self without calling this function again c.FillNoCustom(ct) // fuzz self without calling this function again
ct.TerminationMessagePath = "/" + ct.TerminationMessagePath // Must be non-empty ct.TerminationMessagePath = "/" + ct.TerminationMessagePath // Must be non-empty
ct.TerminationMessagePolicy = "File" ct.TerminationMessagePolicy = "File"
}, },
func(ep *core.EphemeralContainer, c fuzz.Continue) { func(ep *core.EphemeralContainer, c randfill.Continue) {
c.FuzzNoCustom(ep) // fuzz self without calling this function again c.FillNoCustom(ep) // fuzz self without calling this function again
ep.EphemeralContainerCommon.TerminationMessagePath = "/" + ep.TerminationMessagePath // Must be non-empty ep.EphemeralContainerCommon.TerminationMessagePath = "/" + ep.TerminationMessagePath // Must be non-empty
ep.EphemeralContainerCommon.TerminationMessagePolicy = "File" ep.EphemeralContainerCommon.TerminationMessagePolicy = "File"
}, },
func(p *core.Probe, c fuzz.Continue) { func(p *core.Probe, c randfill.Continue) {
c.FuzzNoCustom(p) c.FillNoCustom(p)
// These fields have default values. // These fields have default values.
intFieldsWithDefaults := [...]string{"TimeoutSeconds", "PeriodSeconds", "SuccessThreshold", "FailureThreshold"} intFieldsWithDefaults := [...]string{"TimeoutSeconds", "PeriodSeconds", "SuccessThreshold", "FailureThreshold"}
v := reflect.ValueOf(p).Elem() v := reflect.ValueOf(p).Elem()
@ -327,10 +327,10 @@ var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
} }
} }
}, },
func(ev *core.EnvVar, c fuzz.Continue) { func(ev *core.EnvVar, c randfill.Continue) {
ev.Name = c.RandString() ev.Name = c.String(0)
if c.RandBool() { if c.Bool() {
ev.Value = c.RandString() ev.Value = c.String(0)
} else { } else {
ev.ValueFrom = &core.EnvVarSource{} ev.ValueFrom = &core.EnvVarSource{}
ev.ValueFrom.FieldRef = &core.ObjectFieldSelector{} ev.ValueFrom.FieldRef = &core.ObjectFieldSelector{}
@ -343,79 +343,79 @@ var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
} }
ev.ValueFrom.FieldRef.APIVersion = versions[c.Rand.Intn(len(versions))].String() ev.ValueFrom.FieldRef.APIVersion = versions[c.Rand.Intn(len(versions))].String()
ev.ValueFrom.FieldRef.FieldPath = c.RandString() ev.ValueFrom.FieldRef.FieldPath = c.String(0)
} }
}, },
func(ev *core.EnvFromSource, c fuzz.Continue) { func(ev *core.EnvFromSource, c randfill.Continue) {
if c.RandBool() { if c.Bool() {
ev.Prefix = "p_" ev.Prefix = "p_"
} }
if c.RandBool() { if c.Bool() {
c.Fuzz(&ev.ConfigMapRef) c.Fill(&ev.ConfigMapRef)
} else { } else {
c.Fuzz(&ev.SecretRef) c.Fill(&ev.SecretRef)
} }
}, },
func(cm *core.ConfigMapEnvSource, c fuzz.Continue) { func(cm *core.ConfigMapEnvSource, c randfill.Continue) {
c.FuzzNoCustom(cm) // fuzz self without calling this function again c.FillNoCustom(cm) // fuzz self without calling this function again
if c.RandBool() { if c.Bool() {
opt := c.RandBool() opt := c.Bool()
cm.Optional = &opt cm.Optional = &opt
} }
}, },
func(s *core.SecretEnvSource, c fuzz.Continue) { func(s *core.SecretEnvSource, c randfill.Continue) {
c.FuzzNoCustom(s) // fuzz self without calling this function again c.FillNoCustom(s) // fuzz self without calling this function again
}, },
func(sc *core.SecurityContext, c fuzz.Continue) { func(sc *core.SecurityContext, c randfill.Continue) {
c.FuzzNoCustom(sc) // fuzz self without calling this function again c.FillNoCustom(sc) // fuzz self without calling this function again
if c.RandBool() { if c.Bool() {
priv := c.RandBool() priv := c.Bool()
sc.Privileged = &priv sc.Privileged = &priv
} }
if c.RandBool() { if c.Bool() {
sc.Capabilities = &core.Capabilities{ sc.Capabilities = &core.Capabilities{
Add: make([]core.Capability, 0), Add: make([]core.Capability, 0),
Drop: make([]core.Capability, 0), Drop: make([]core.Capability, 0),
} }
c.Fuzz(&sc.Capabilities.Add) c.Fill(&sc.Capabilities.Add)
c.Fuzz(&sc.Capabilities.Drop) c.Fill(&sc.Capabilities.Drop)
} }
}, },
func(s *core.Secret, c fuzz.Continue) { func(s *core.Secret, c randfill.Continue) {
c.FuzzNoCustom(s) // fuzz self without calling this function again c.FillNoCustom(s) // fuzz self without calling this function again
s.Type = core.SecretTypeOpaque s.Type = core.SecretTypeOpaque
}, },
func(r *core.RBDVolumeSource, c fuzz.Continue) { func(r *core.RBDVolumeSource, c randfill.Continue) {
r.RBDPool = c.RandString() r.RBDPool = c.String(0)
if r.RBDPool == "" { if r.RBDPool == "" {
r.RBDPool = "rbd" r.RBDPool = "rbd"
} }
r.RadosUser = c.RandString() r.RadosUser = c.String(0)
if r.RadosUser == "" { if r.RadosUser == "" {
r.RadosUser = "admin" r.RadosUser = "admin"
} }
r.Keyring = c.RandString() r.Keyring = c.String(0)
if r.Keyring == "" { if r.Keyring == "" {
r.Keyring = "/etc/ceph/keyring" r.Keyring = "/etc/ceph/keyring"
} }
}, },
func(r *core.RBDPersistentVolumeSource, c fuzz.Continue) { func(r *core.RBDPersistentVolumeSource, c randfill.Continue) {
r.RBDPool = c.RandString() r.RBDPool = c.String(0)
if r.RBDPool == "" { if r.RBDPool == "" {
r.RBDPool = "rbd" r.RBDPool = "rbd"
} }
r.RadosUser = c.RandString() r.RadosUser = c.String(0)
if r.RadosUser == "" { if r.RadosUser == "" {
r.RadosUser = "admin" r.RadosUser = "admin"
} }
r.Keyring = c.RandString() r.Keyring = c.String(0)
if r.Keyring == "" { if r.Keyring == "" {
r.Keyring = "/etc/ceph/keyring" r.Keyring = "/etc/ceph/keyring"
} }
}, },
func(obj *core.HostPathVolumeSource, c fuzz.Continue) { func(obj *core.HostPathVolumeSource, c randfill.Continue) {
c.FuzzNoCustom(obj) c.FillNoCustom(obj)
types := []core.HostPathType{core.HostPathUnset, core.HostPathDirectoryOrCreate, core.HostPathDirectory, types := []core.HostPathType{core.HostPathUnset, core.HostPathDirectoryOrCreate, core.HostPathDirectory,
core.HostPathFileOrCreate, core.HostPathFile, core.HostPathSocket, core.HostPathCharDev, core.HostPathBlockDev} core.HostPathFileOrCreate, core.HostPathFile, core.HostPathSocket, core.HostPathCharDev, core.HostPathBlockDev}
typeVol := types[c.Rand.Intn(len(types))] typeVol := types[c.Rand.Intn(len(types))]
@ -423,24 +423,24 @@ var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
obj.Type = &typeVol obj.Type = &typeVol
} }
}, },
func(pv *core.PersistentVolume, c fuzz.Continue) { func(pv *core.PersistentVolume, c randfill.Continue) {
c.FuzzNoCustom(pv) // fuzz self without calling this function again c.FillNoCustom(pv) // fuzz self without calling this function again
types := []core.PersistentVolumePhase{core.VolumeAvailable, core.VolumePending, core.VolumeBound, core.VolumeReleased, core.VolumeFailed} types := []core.PersistentVolumePhase{core.VolumeAvailable, core.VolumePending, core.VolumeBound, core.VolumeReleased, core.VolumeFailed}
pv.Status.Phase = types[c.Rand.Intn(len(types))] pv.Status.Phase = types[c.Rand.Intn(len(types))]
pv.Status.Message = c.RandString() pv.Status.Message = c.String(0)
reclamationPolicies := []core.PersistentVolumeReclaimPolicy{core.PersistentVolumeReclaimRecycle, core.PersistentVolumeReclaimRetain} reclamationPolicies := []core.PersistentVolumeReclaimPolicy{core.PersistentVolumeReclaimRecycle, core.PersistentVolumeReclaimRetain}
pv.Spec.PersistentVolumeReclaimPolicy = reclamationPolicies[c.Rand.Intn(len(reclamationPolicies))] pv.Spec.PersistentVolumeReclaimPolicy = reclamationPolicies[c.Rand.Intn(len(reclamationPolicies))]
volumeModes := []core.PersistentVolumeMode{core.PersistentVolumeFilesystem, core.PersistentVolumeBlock} volumeModes := []core.PersistentVolumeMode{core.PersistentVolumeFilesystem, core.PersistentVolumeBlock}
pv.Spec.VolumeMode = &volumeModes[c.Rand.Intn(len(volumeModes))] pv.Spec.VolumeMode = &volumeModes[c.Rand.Intn(len(volumeModes))]
}, },
func(pvc *core.PersistentVolumeClaim, c fuzz.Continue) { func(pvc *core.PersistentVolumeClaim, c randfill.Continue) {
c.FuzzNoCustom(pvc) // fuzz self without calling this function again c.FillNoCustom(pvc) // fuzz self without calling this function again
types := []core.PersistentVolumeClaimPhase{core.ClaimBound, core.ClaimPending, core.ClaimLost} types := []core.PersistentVolumeClaimPhase{core.ClaimBound, core.ClaimPending, core.ClaimLost}
pvc.Status.Phase = types[c.Rand.Intn(len(types))] pvc.Status.Phase = types[c.Rand.Intn(len(types))]
volumeModes := []core.PersistentVolumeMode{core.PersistentVolumeFilesystem, core.PersistentVolumeBlock} volumeModes := []core.PersistentVolumeMode{core.PersistentVolumeFilesystem, core.PersistentVolumeBlock}
pvc.Spec.VolumeMode = &volumeModes[c.Rand.Intn(len(volumeModes))] pvc.Spec.VolumeMode = &volumeModes[c.Rand.Intn(len(volumeModes))]
}, },
func(obj *core.AzureDiskVolumeSource, c fuzz.Continue) { func(obj *core.AzureDiskVolumeSource, c randfill.Continue) {
if obj.CachingMode == nil { if obj.CachingMode == nil {
obj.CachingMode = new(core.AzureDataDiskCachingMode) obj.CachingMode = new(core.AzureDataDiskCachingMode)
*obj.CachingMode = core.AzureDataDiskCachingReadWrite *obj.CachingMode = core.AzureDataDiskCachingReadWrite
@ -458,31 +458,31 @@ var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
*obj.ReadOnly = false *obj.ReadOnly = false
} }
}, },
func(sio *core.ScaleIOVolumeSource, c fuzz.Continue) { func(sio *core.ScaleIOVolumeSource, c randfill.Continue) {
sio.StorageMode = c.RandString() sio.StorageMode = c.String(0)
if sio.StorageMode == "" { if sio.StorageMode == "" {
sio.StorageMode = "ThinProvisioned" sio.StorageMode = "ThinProvisioned"
} }
sio.FSType = c.RandString() sio.FSType = c.String(0)
if sio.FSType == "" { if sio.FSType == "" {
sio.FSType = "xfs" sio.FSType = "xfs"
} }
}, },
func(sio *core.ScaleIOPersistentVolumeSource, c fuzz.Continue) { func(sio *core.ScaleIOPersistentVolumeSource, c randfill.Continue) {
sio.StorageMode = c.RandString() sio.StorageMode = c.String(0)
if sio.StorageMode == "" { if sio.StorageMode == "" {
sio.StorageMode = "ThinProvisioned" sio.StorageMode = "ThinProvisioned"
} }
sio.FSType = c.RandString() sio.FSType = c.String(0)
if sio.FSType == "" { if sio.FSType == "" {
sio.FSType = "xfs" sio.FSType = "xfs"
} }
}, },
func(s *core.NamespaceSpec, c fuzz.Continue) { func(s *core.NamespaceSpec, c randfill.Continue) {
s.Finalizers = []core.FinalizerName{core.FinalizerKubernetes} s.Finalizers = []core.FinalizerName{core.FinalizerKubernetes}
}, },
func(s *core.Namespace, c fuzz.Continue) { func(s *core.Namespace, c randfill.Continue) {
c.FuzzNoCustom(s) // fuzz self without calling this function again c.FillNoCustom(s) // fuzz self without calling this function again
// Match name --> label defaulting // Match name --> label defaulting
if len(s.Name) > 0 { if len(s.Name) > 0 {
if s.Labels == nil { if s.Labels == nil {
@ -491,20 +491,20 @@ var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
s.Labels["kubernetes.io/metadata.name"] = s.Name s.Labels["kubernetes.io/metadata.name"] = s.Name
} }
}, },
func(s *core.NamespaceStatus, c fuzz.Continue) { func(s *core.NamespaceStatus, c randfill.Continue) {
s.Phase = core.NamespaceActive s.Phase = core.NamespaceActive
}, },
func(http *core.HTTPGetAction, c fuzz.Continue) { func(http *core.HTTPGetAction, c randfill.Continue) {
c.FuzzNoCustom(http) // fuzz self without calling this function again c.FillNoCustom(http) // fuzz self without calling this function again
http.Path = "/" + http.Path // can't be blank http.Path = "/" + http.Path // can't be blank
http.Scheme = "x" + http.Scheme // can't be blank http.Scheme = "x" + http.Scheme // can't be blank
}, },
func(ss *core.ServiceSpec, c fuzz.Continue) { func(ss *core.ServiceSpec, c randfill.Continue) {
c.FuzzNoCustom(ss) // fuzz self without calling this function again c.FillNoCustom(ss) // fuzz self without calling this function again
if len(ss.Ports) == 0 { if len(ss.Ports) == 0 {
// There must be at least 1 port. // There must be at least 1 port.
ss.Ports = append(ss.Ports, core.ServicePort{}) ss.Ports = append(ss.Ports, core.ServicePort{})
c.Fuzz(&ss.Ports[0]) c.Fill(&ss.Ports[0])
} }
for i := range ss.Ports { for i := range ss.Ports {
switch ss.Ports[i].TargetPort.Type { switch ss.Ports[i].TargetPort.Type {
@ -531,24 +531,24 @@ var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
ss.AllocateLoadBalancerNodePorts = utilpointer.Bool(true) ss.AllocateLoadBalancerNodePorts = utilpointer.Bool(true)
} }
}, },
func(s *core.NodeStatus, c fuzz.Continue) { func(s *core.NodeStatus, c randfill.Continue) {
c.FuzzNoCustom(s) c.FillNoCustom(s)
s.Allocatable = s.Capacity s.Allocatable = s.Capacity
}, },
func(e *core.Event, c fuzz.Continue) { func(e *core.Event, c randfill.Continue) {
c.FuzzNoCustom(e) c.FillNoCustom(e)
e.EventTime = metav1.MicroTime{Time: time.Unix(1, 1000)} e.EventTime = metav1.MicroTime{Time: time.Unix(1, 1000)}
if e.Series != nil { if e.Series != nil {
e.Series.LastObservedTime = metav1.MicroTime{Time: time.Unix(3, 3000)} e.Series.LastObservedTime = metav1.MicroTime{Time: time.Unix(3, 3000)}
} }
}, },
func(j *core.GRPCAction, c fuzz.Continue) { func(j *core.GRPCAction, c randfill.Continue) {
empty := "" empty := ""
if j.Service == nil { if j.Service == nil {
j.Service = &empty j.Service = &empty
} }
}, },
func(j *core.LoadBalancerStatus, c fuzz.Continue) { func(j *core.LoadBalancerStatus, c randfill.Continue) {
ipMode := core.LoadBalancerIPModeVIP ipMode := core.LoadBalancerIPModeVIP
for i := range j.Ingress { for i := range j.Ingress {
if j.Ingress[i].IPMode == nil { if j.Ingress[i].IPMode == nil {

View File

@ -292,7 +292,7 @@ func TestReplicationControllerConversion(t *testing.T) {
apiObjectFuzzer := fuzzer.FuzzerFor(fuzzer.MergeFuzzerFuncs(metafuzzer.Funcs, corefuzzer.Funcs), rand.NewSource(152), legacyscheme.Codecs) apiObjectFuzzer := fuzzer.FuzzerFor(fuzzer.MergeFuzzerFuncs(metafuzzer.Funcs, corefuzzer.Funcs), rand.NewSource(152), legacyscheme.Codecs)
for i := 0; i < 100; i++ { for i := 0; i < 100; i++ {
rc := &v1.ReplicationController{} rc := &v1.ReplicationController{}
apiObjectFuzzer.Fuzz(rc) apiObjectFuzzer.Fill(rc)
// Sometimes the fuzzer decides to leave Spec.Template nil. // Sometimes the fuzzer decides to leave Spec.Template nil.
// We can't support that because Spec.Template is not a pointer in RS, // We can't support that because Spec.Template is not a pointer in RS,
// so it will round-trip as non-nil but empty. // so it will round-trip as non-nil but empty.

View File

@ -17,7 +17,7 @@ limitations under the License.
package fuzzer package fuzzer
import ( import (
fuzz "github.com/google/gofuzz" "sigs.k8s.io/randfill"
runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer"
api "k8s.io/kubernetes/pkg/apis/core" api "k8s.io/kubernetes/pkg/apis/core"
@ -27,8 +27,8 @@ import (
// Funcs returns the fuzzer functions for the discovery api group. // Funcs returns the fuzzer functions for the discovery api group.
var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} { var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
return []interface{}{ return []interface{}{
func(obj *discovery.EndpointSlice, c fuzz.Continue) { func(obj *discovery.EndpointSlice, c randfill.Continue) {
c.FuzzNoCustom(obj) // fuzz self without calling this function again c.FillNoCustom(obj) // fuzz self without calling this function again
addressTypes := []discovery.AddressType{discovery.AddressTypeIPv4, discovery.AddressTypeIPv6, discovery.AddressTypeFQDN} addressTypes := []discovery.AddressType{discovery.AddressTypeIPv4, discovery.AddressTypeIPv6, discovery.AddressTypeFQDN}
obj.AddressType = addressTypes[c.Rand.Intn(len(addressTypes))] obj.AddressType = addressTypes[c.Rand.Intn(len(addressTypes))]

View File

@ -17,7 +17,7 @@ limitations under the License.
package fuzzer package fuzzer
import ( import (
fuzz "github.com/google/gofuzz" "sigs.k8s.io/randfill"
runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/kubernetes/pkg/apis/flowcontrol" "k8s.io/kubernetes/pkg/apis/flowcontrol"
@ -27,8 +27,8 @@ import (
// Funcs returns the fuzzer functions for the flowcontrol api group. // Funcs returns the fuzzer functions for the flowcontrol api group.
var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} { var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
return []interface{}{ return []interface{}{
func(obj *flowcontrol.LimitedPriorityLevelConfiguration, c fuzz.Continue) { func(obj *flowcontrol.LimitedPriorityLevelConfiguration, c randfill.Continue) {
c.FuzzNoCustom(obj) // fuzz self without calling this function again c.FillNoCustom(obj) // fuzz self without calling this function again
// NOTE: setting a zero value here will cause the roundtrip // NOTE: setting a zero value here will cause the roundtrip
// test (from internal to v1beta2, v1beta1) to fail // test (from internal to v1beta2, v1beta1) to fail
@ -39,8 +39,8 @@ var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
obj.LendablePercent = ptr.To(int32(0)) obj.LendablePercent = ptr.To(int32(0))
} }
}, },
func(obj *flowcontrol.ExemptPriorityLevelConfiguration, c fuzz.Continue) { func(obj *flowcontrol.ExemptPriorityLevelConfiguration, c randfill.Continue) {
c.FuzzNoCustom(obj) // fuzz self without calling this function again c.FillNoCustom(obj) // fuzz self without calling this function again
if obj.NominalConcurrencyShares == nil { if obj.NominalConcurrencyShares == nil {
obj.NominalConcurrencyShares = ptr.To(int32(0)) obj.NominalConcurrencyShares = ptr.To(int32(0))
} }

View File

@ -20,17 +20,17 @@ import (
"fmt" "fmt"
"net/netip" "net/netip"
fuzz "github.com/google/gofuzz"
runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/kubernetes/pkg/apis/networking" "k8s.io/kubernetes/pkg/apis/networking"
utilpointer "k8s.io/utils/pointer" utilpointer "k8s.io/utils/pointer"
"sigs.k8s.io/randfill"
) )
// Funcs returns the fuzzer functions for the networking api group. // Funcs returns the fuzzer functions for the networking api group.
var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} { var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
return []interface{}{ return []interface{}{
func(np *networking.NetworkPolicyPeer, c fuzz.Continue) { func(np *networking.NetworkPolicyPeer, c randfill.Continue) {
c.FuzzNoCustom(np) // fuzz self without calling this function again c.FillNoCustom(np) // fuzz self without calling this function again
// TODO: Implement a fuzzer to generate valid keys, values and operators for // TODO: Implement a fuzzer to generate valid keys, values and operators for
// selector requirements. // selector requirements.
if np.IPBlock != nil { if np.IPBlock != nil {
@ -40,23 +40,23 @@ var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
} }
} }
}, },
func(np *networking.NetworkPolicy, c fuzz.Continue) { func(np *networking.NetworkPolicy, c randfill.Continue) {
c.FuzzNoCustom(np) // fuzz self without calling this function again c.FillNoCustom(np) // fuzz self without calling this function again
// TODO: Implement a fuzzer to generate valid keys, values and operators for // TODO: Implement a fuzzer to generate valid keys, values and operators for
// selector requirements. // selector requirements.
if len(np.Spec.PolicyTypes) == 0 { if len(np.Spec.PolicyTypes) == 0 {
np.Spec.PolicyTypes = []networking.PolicyType{networking.PolicyTypeIngress} np.Spec.PolicyTypes = []networking.PolicyType{networking.PolicyTypeIngress}
} }
}, },
func(path *networking.HTTPIngressPath, c fuzz.Continue) { func(path *networking.HTTPIngressPath, c randfill.Continue) {
c.FuzzNoCustom(path) // fuzz self without calling this function again c.FillNoCustom(path) // fuzz self without calling this function again
pathTypes := []networking.PathType{networking.PathTypeExact, networking.PathTypePrefix, networking.PathTypeImplementationSpecific} pathTypes := []networking.PathType{networking.PathTypeExact, networking.PathTypePrefix, networking.PathTypeImplementationSpecific}
path.PathType = &pathTypes[c.Rand.Intn(len(pathTypes))] path.PathType = &pathTypes[c.Rand.Intn(len(pathTypes))]
}, },
func(p *networking.ServiceBackendPort, c fuzz.Continue) { func(p *networking.ServiceBackendPort, c randfill.Continue) {
c.FuzzNoCustom(p) c.FillNoCustom(p)
// clear one of the fields // clear one of the fields
if c.RandBool() { if c.Bool() {
p.Name = "" p.Name = ""
if p.Number == 0 { if p.Number == 0 {
p.Number = 1 p.Number = 1
@ -68,8 +68,8 @@ var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
} }
} }
}, },
func(p *networking.IngressClass, c fuzz.Continue) { func(p *networking.IngressClass, c randfill.Continue) {
c.FuzzNoCustom(p) // fuzz self without calling this function again c.FillNoCustom(p) // fuzz self without calling this function again
// default Parameters to Cluster // default Parameters to Cluster
if p.Spec.Parameters == nil || p.Spec.Parameters.Scope == nil { if p.Spec.Parameters == nil || p.Spec.Parameters.Scope == nil {
p.Spec.Parameters = &networking.IngressClassParametersReference{ p.Spec.Parameters = &networking.IngressClassParametersReference{
@ -77,16 +77,16 @@ var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
} }
} }
}, },
func(obj *networking.IPAddress, c fuzz.Continue) { func(obj *networking.IPAddress, c randfill.Continue) {
c.FuzzNoCustom(obj) // fuzz self without calling this function again c.FillNoCustom(obj) // fuzz self without calling this function again
// length in bytes of the IP Family: IPv4: 4 bytes IPv6: 16 bytes // length in bytes of the IP Family: IPv4: 4 bytes IPv6: 16 bytes
boolean := []bool{false, true} boolean := []bool{false, true}
is6 := boolean[c.Rand.Intn(2)] is6 := boolean[c.Rand.Intn(2)]
ip := generateRandomIP(is6, c) ip := generateRandomIP(is6, c)
obj.Name = ip obj.Name = ip
}, },
func(obj *networking.ServiceCIDR, c fuzz.Continue) { func(obj *networking.ServiceCIDR, c randfill.Continue) {
c.FuzzNoCustom(obj) // fuzz self without calling this function again c.FillNoCustom(obj) // fuzz self without calling this function again
boolean := []bool{false, true} boolean := []bool{false, true}
is6 := boolean[c.Rand.Intn(2)] is6 := boolean[c.Rand.Intn(2)]
@ -100,7 +100,7 @@ var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
} }
} }
func generateRandomIP(is6 bool, c fuzz.Continue) string { func generateRandomIP(is6 bool, c randfill.Continue) string {
n := 4 n := 4
if is6 { if is6 {
n = 16 n = 16
@ -118,7 +118,7 @@ func generateRandomIP(is6 bool, c fuzz.Continue) string {
panic(fmt.Sprintf("invalid IP %v", bytes)) panic(fmt.Sprintf("invalid IP %v", bytes))
} }
func generateRandomCIDR(is6 bool, c fuzz.Continue) string { func generateRandomCIDR(is6 bool, c randfill.Continue) string {
ip, err := netip.ParseAddr(generateRandomIP(is6, c)) ip, err := netip.ParseAddr(generateRandomIP(is6, c))
if err != nil { if err != nil {
// generateRandomIP already panics if returns a not valid ip // generateRandomIP already panics if returns a not valid ip

View File

@ -17,7 +17,7 @@ limitations under the License.
package fuzzer package fuzzer
import ( import (
fuzz "github.com/google/gofuzz" "sigs.k8s.io/randfill"
runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/kubernetes/pkg/apis/policy" "k8s.io/kubernetes/pkg/apis/policy"
@ -26,8 +26,8 @@ import (
// Funcs returns the fuzzer functions for the policy api group. // Funcs returns the fuzzer functions for the policy api group.
var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} { var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
return []interface{}{ return []interface{}{
func(s *policy.PodDisruptionBudgetStatus, c fuzz.Continue) { func(s *policy.PodDisruptionBudgetStatus, c randfill.Continue) {
c.FuzzNoCustom(s) // fuzz self without calling this function again c.FillNoCustom(s) // fuzz self without calling this function again
s.DisruptionsAllowed = int32(c.Rand.Intn(2)) s.DisruptionsAllowed = int32(c.Rand.Intn(2))
}, },
} }

View File

@ -17,7 +17,7 @@ limitations under the License.
package fuzzer package fuzzer
import ( import (
fuzz "github.com/google/gofuzz" "sigs.k8s.io/randfill"
runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/kubernetes/pkg/apis/rbac" "k8s.io/kubernetes/pkg/apis/rbac"
@ -26,33 +26,33 @@ import (
// Funcs returns the fuzzer functions for the rbac api group. // Funcs returns the fuzzer functions for the rbac api group.
var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} { var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
return []interface{}{ return []interface{}{
func(r *rbac.RoleRef, c fuzz.Continue) { func(r *rbac.RoleRef, c randfill.Continue) {
c.FuzzNoCustom(r) // fuzz self without calling this function again c.FillNoCustom(r) // fuzz self without calling this function again
// match defaulter // match defaulter
if len(r.APIGroup) == 0 { if len(r.APIGroup) == 0 {
r.APIGroup = rbac.GroupName r.APIGroup = rbac.GroupName
} }
}, },
func(r *rbac.Subject, c fuzz.Continue) { func(r *rbac.Subject, c randfill.Continue) {
switch c.Int31n(3) { switch c.Int31n(3) {
case 0: case 0:
r.Kind = rbac.ServiceAccountKind r.Kind = rbac.ServiceAccountKind
r.APIGroup = "" r.APIGroup = ""
c.FuzzNoCustom(&r.Name) c.FillNoCustom(&r.Name)
c.FuzzNoCustom(&r.Namespace) c.FillNoCustom(&r.Namespace)
case 1: case 1:
r.Kind = rbac.UserKind r.Kind = rbac.UserKind
r.APIGroup = rbac.GroupName r.APIGroup = rbac.GroupName
c.FuzzNoCustom(&r.Name) c.FillNoCustom(&r.Name)
// user "*" won't round trip because we convert it to the system:authenticated group. try again. // user "*" won't round trip because we convert it to the system:authenticated group. try again.
for r.Name == "*" { for r.Name == "*" {
c.FuzzNoCustom(&r.Name) c.FillNoCustom(&r.Name)
} }
case 2: case 2:
r.Kind = rbac.GroupKind r.Kind = rbac.GroupKind
r.APIGroup = rbac.GroupName r.APIGroup = rbac.GroupName
c.FuzzNoCustom(&r.Name) c.FillNoCustom(&r.Name)
} }
}, },
} }

View File

@ -17,10 +17,10 @@ limitations under the License.
package fuzzer package fuzzer
import ( import (
fuzz "github.com/google/gofuzz"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/kubernetes/pkg/apis/resource" "k8s.io/kubernetes/pkg/apis/resource"
"sigs.k8s.io/randfill"
) )
// Funcs contains the fuzzer functions for the resource group. // Funcs contains the fuzzer functions for the resource group.
@ -29,8 +29,8 @@ import (
// leads to errors during roundtrip tests. // leads to errors during roundtrip tests.
var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} { var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
return []interface{}{ return []interface{}{
func(r *resource.DeviceRequest, c fuzz.Continue) { func(r *resource.DeviceRequest, c randfill.Continue) {
c.FuzzNoCustom(r) // fuzz self without calling this function again c.FillNoCustom(r) // fuzz self without calling this function again
if r.AllocationMode == "" { if r.AllocationMode == "" {
r.AllocationMode = []resource.DeviceAllocationMode{ r.AllocationMode = []resource.DeviceAllocationMode{
@ -39,8 +39,8 @@ var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
}[c.Int31n(2)] }[c.Int31n(2)]
} }
}, },
func(r *resource.DeviceAllocationConfiguration, c fuzz.Continue) { func(r *resource.DeviceAllocationConfiguration, c randfill.Continue) {
c.FuzzNoCustom(r) c.FillNoCustom(r)
if r.Source == "" { if r.Source == "" {
r.Source = []resource.AllocationConfigSource{ r.Source = []resource.AllocationConfigSource{
resource.AllocationConfigSourceClass, resource.AllocationConfigSourceClass,
@ -48,16 +48,16 @@ var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
}[c.Int31n(2)] }[c.Int31n(2)]
} }
}, },
func(r *resource.OpaqueDeviceConfiguration, c fuzz.Continue) { func(r *resource.OpaqueDeviceConfiguration, c randfill.Continue) {
c.FuzzNoCustom(r) c.FillNoCustom(r)
// Match the fuzzer default content for runtime.Object. // Match the fuzzer default content for runtime.Object.
// //
// This is necessary because randomly generated content // This is necessary because randomly generated content
// might be valid JSON which changes during re-encoding. // might be valid JSON which changes during re-encoding.
r.Parameters = runtime.RawExtension{Raw: []byte(`{"apiVersion":"unknown.group/unknown","kind":"Something","someKey":"someValue"}`)} r.Parameters = runtime.RawExtension{Raw: []byte(`{"apiVersion":"unknown.group/unknown","kind":"Something","someKey":"someValue"}`)}
}, },
func(r *resource.AllocatedDeviceStatus, c fuzz.Continue) { func(r *resource.AllocatedDeviceStatus, c randfill.Continue) {
c.FuzzNoCustom(r) c.FillNoCustom(r)
// Match the fuzzer default content for runtime.Object. // Match the fuzzer default content for runtime.Object.
// //
// This is necessary because randomly generated content // This is necessary because randomly generated content

View File

@ -17,17 +17,17 @@ limitations under the License.
package fuzzer package fuzzer
import ( import (
"github.com/google/gofuzz"
runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/kubernetes/pkg/apis/core" "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/apis/scheduling" "k8s.io/kubernetes/pkg/apis/scheduling"
"sigs.k8s.io/randfill"
) )
// Funcs returns the fuzzer functions for the scheduling api group. // Funcs returns the fuzzer functions for the scheduling api group.
var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} { var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
return []interface{}{ return []interface{}{
func(s *scheduling.PriorityClass, c fuzz.Continue) { func(s *scheduling.PriorityClass, c randfill.Continue) {
c.FuzzNoCustom(s) c.FillNoCustom(s)
if s.PreemptionPolicy == nil { if s.PreemptionPolicy == nil {
preemptLowerPriority := core.PreemptLowerPriority preemptLowerPriority := core.PreemptLowerPriority
s.PreemptionPolicy = &preemptLowerPriority s.PreemptionPolicy = &preemptLowerPriority

View File

@ -19,7 +19,7 @@ package fuzzer
import ( import (
"fmt" "fmt"
fuzz "github.com/google/gofuzz" "sigs.k8s.io/randfill"
runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer"
api "k8s.io/kubernetes/pkg/apis/core" api "k8s.io/kubernetes/pkg/apis/core"
@ -29,15 +29,15 @@ import (
// Funcs returns the fuzzer functions for the storage api group. // Funcs returns the fuzzer functions for the storage api group.
var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} { var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
return []interface{}{ return []interface{}{
func(obj *storage.StorageClass, c fuzz.Continue) { func(obj *storage.StorageClass, c randfill.Continue) {
c.FuzzNoCustom(obj) // fuzz self without calling this function again c.FillNoCustom(obj) // fuzz self without calling this function again
reclamationPolicies := []api.PersistentVolumeReclaimPolicy{api.PersistentVolumeReclaimDelete, api.PersistentVolumeReclaimRetain} reclamationPolicies := []api.PersistentVolumeReclaimPolicy{api.PersistentVolumeReclaimDelete, api.PersistentVolumeReclaimRetain}
obj.ReclaimPolicy = &reclamationPolicies[c.Rand.Intn(len(reclamationPolicies))] obj.ReclaimPolicy = &reclamationPolicies[c.Rand.Intn(len(reclamationPolicies))]
bindingModes := []storage.VolumeBindingMode{storage.VolumeBindingImmediate, storage.VolumeBindingWaitForFirstConsumer} bindingModes := []storage.VolumeBindingMode{storage.VolumeBindingImmediate, storage.VolumeBindingWaitForFirstConsumer}
obj.VolumeBindingMode = &bindingModes[c.Rand.Intn(len(bindingModes))] obj.VolumeBindingMode = &bindingModes[c.Rand.Intn(len(bindingModes))]
}, },
func(obj *storage.CSIDriver, c fuzz.Continue) { func(obj *storage.CSIDriver, c randfill.Continue) {
c.FuzzNoCustom(obj) // fuzz self without calling this function again c.FillNoCustom(obj) // fuzz self without calling this function again
// Custom fuzzing for volume modes. // Custom fuzzing for volume modes.
switch c.Rand.Intn(7) { switch c.Rand.Intn(7) {

View File

@ -19,7 +19,7 @@ package fuzzer
import ( import (
"fmt" "fmt"
"github.com/google/gofuzz" "sigs.k8s.io/randfill"
runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer"
kubectrlmgrconfig "k8s.io/kubernetes/pkg/controller/apis/config" kubectrlmgrconfig "k8s.io/kubernetes/pkg/controller/apis/config"
@ -28,20 +28,20 @@ import (
// Funcs returns the fuzzer functions for the kube-controller manager apis. // Funcs returns the fuzzer functions for the kube-controller manager apis.
func Funcs(codecs runtimeserializer.CodecFactory) []interface{} { func Funcs(codecs runtimeserializer.CodecFactory) []interface{} {
return []interface{}{ return []interface{}{
func(obj *kubectrlmgrconfig.KubeControllerManagerConfiguration, c fuzz.Continue) { func(obj *kubectrlmgrconfig.KubeControllerManagerConfiguration, c randfill.Continue) {
c.FuzzNoCustom(obj) c.FillNoCustom(obj)
obj.Generic.Address = fmt.Sprintf("%d.%d.%d.%d", c.Intn(256), c.Intn(256), c.Intn(256), c.Intn(256)) obj.Generic.Address = fmt.Sprintf("%d.%d.%d.%d", c.Intn(256), c.Intn(256), c.Intn(256), c.Intn(256))
obj.Generic.ClientConnection.ContentType = fmt.Sprintf("%s/%s.%s.%s", c.RandString(), c.RandString(), c.RandString(), c.RandString()) obj.Generic.ClientConnection.ContentType = fmt.Sprintf("%s/%s.%s.%s", c.String(0), c.String(0), c.String(0), c.String(0))
if obj.Generic.LeaderElection.ResourceLock == "" { if obj.Generic.LeaderElection.ResourceLock == "" {
obj.Generic.LeaderElection.ResourceLock = "endpoints" obj.Generic.LeaderElection.ResourceLock = "endpoints"
} }
obj.Generic.Controllers = []string{fmt.Sprintf("%s", c.RandString())} obj.Generic.Controllers = []string{c.String(0)}
if obj.KubeCloudShared.ClusterName == "" { if obj.KubeCloudShared.ClusterName == "" {
obj.KubeCloudShared.ClusterName = "kubernetes" obj.KubeCloudShared.ClusterName = "kubernetes"
} }
obj.CSRSigningController.ClusterSigningCertFile = fmt.Sprintf("/%s", c.RandString()) obj.CSRSigningController.ClusterSigningCertFile = fmt.Sprintf("/%s", c.String(0))
obj.CSRSigningController.ClusterSigningKeyFile = fmt.Sprintf("/%s", c.RandString()) obj.CSRSigningController.ClusterSigningKeyFile = fmt.Sprintf("/%s", c.String(0))
obj.PersistentVolumeBinderController.VolumeConfiguration.FlexVolumePluginDir = fmt.Sprintf("/%s", c.RandString()) obj.PersistentVolumeBinderController.VolumeConfiguration.FlexVolumePluginDir = fmt.Sprintf("/%s", c.String(0))
obj.TTLAfterFinishedController.ConcurrentTTLSyncs = c.Int31() obj.TTLAfterFinishedController.ConcurrentTTLSyncs = c.Int31()
}, },
} }

View File

@ -20,7 +20,7 @@ import (
"math/rand" "math/rand"
"time" "time"
fuzz "github.com/google/gofuzz" "sigs.k8s.io/randfill"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer"
@ -38,8 +38,8 @@ import (
func Funcs(codecs runtimeserializer.CodecFactory) []interface{} { func Funcs(codecs runtimeserializer.CodecFactory) []interface{} {
return []interface{}{ return []interface{}{
// provide non-empty values for fields with defaults, so the defaulter doesn't change values during round-trip // provide non-empty values for fields with defaults, so the defaulter doesn't change values during round-trip
func(obj *kubeletconfig.KubeletConfiguration, c fuzz.Continue) { func(obj *kubeletconfig.KubeletConfiguration, c randfill.Continue) {
c.FuzzNoCustom(obj) c.FillNoCustom(obj)
obj.EnableServer = true obj.EnableServer = true
obj.Authentication.Anonymous.Enabled = true obj.Authentication.Anonymous.Enabled = true
obj.Authentication.Webhook.Enabled = false obj.Authentication.Webhook.Enabled = false

View File

@ -24,8 +24,8 @@ import (
"testing" "testing"
"time" "time"
fuzz "github.com/google/gofuzz"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"sigs.k8s.io/randfill"
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -313,45 +313,45 @@ func TestSummaryProviderGetCPUAndMemoryStats(t *testing.T) {
} }
func getFsStats() *statsapi.FsStats { func getFsStats() *statsapi.FsStats {
f := fuzz.New().NilChance(0) f := randfill.New().NilChance(0)
v := &statsapi.FsStats{} v := &statsapi.FsStats{}
f.Fuzz(v) f.Fill(v)
return v return v
} }
func getContainerStats() *statsapi.ContainerStats { func getContainerStats() *statsapi.ContainerStats {
f := fuzz.New().NilChance(0) f := randfill.New().NilChance(0)
v := &statsapi.ContainerStats{} v := &statsapi.ContainerStats{}
f.Fuzz(v) f.Fill(v)
return v return v
} }
func getVolumeCPUAndMemoryStats() *statsapi.ContainerStats { func getVolumeCPUAndMemoryStats() *statsapi.ContainerStats {
f := fuzz.New().NilChance(0) f := randfill.New().NilChance(0)
v := &statsapi.ContainerStats{} v := &statsapi.ContainerStats{}
f.Fuzz(&v.Name) f.Fill(&v.Name)
f.Fuzz(&v.StartTime) f.Fill(&v.StartTime)
f.Fuzz(v.CPU) f.Fill(v.CPU)
f.Fuzz(v.Memory) f.Fill(v.Memory)
return v return v
} }
func getVolumeStats() *statsapi.VolumeStats { func getVolumeStats() *statsapi.VolumeStats {
f := fuzz.New().NilChance(0) f := randfill.New().NilChance(0)
v := &statsapi.VolumeStats{} v := &statsapi.VolumeStats{}
f.Fuzz(v) f.Fill(v)
return v return v
} }
func getNetworkStats() *statsapi.NetworkStats { func getNetworkStats() *statsapi.NetworkStats {
f := fuzz.New().NilChance(0) f := randfill.New().NilChance(0)
v := &statsapi.NetworkStats{} v := &statsapi.NetworkStats{}
f.Fuzz(v) f.Fill(v)
return v return v
} }
func getRlimitStats() *statsapi.RlimitStats { func getRlimitStats() *statsapi.RlimitStats {
f := fuzz.New().NilChance(0) f := randfill.New().NilChance(0)
v := &statsapi.RlimitStats{} v := &statsapi.RlimitStats{}
f.Fuzz(v) f.Fill(v)
return v return v
} }

View File

@ -24,8 +24,8 @@ import (
"testing" "testing"
"time" "time"
fuzz "github.com/google/gofuzz"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"sigs.k8s.io/randfill"
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -95,16 +95,16 @@ func TestSummaryProvider(t *testing.T) {
} }
func getFsStats() *statsapi.FsStats { func getFsStats() *statsapi.FsStats {
f := fuzz.New().NilChance(0) f := randfill.New().NilChance(0)
v := &statsapi.FsStats{} v := &statsapi.FsStats{}
f.Fuzz(v) f.Fill(v)
return v return v
} }
func getContainerStats() *statsapi.ContainerStats { func getContainerStats() *statsapi.ContainerStats {
f := fuzz.New().NilChance(0) f := randfill.New().NilChance(0)
v := &statsapi.ContainerStats{} v := &statsapi.ContainerStats{}
f.Fuzz(v) f.Fill(v)
return v return v
} }

View File

@ -26,9 +26,9 @@ import (
cadvisorapiv1 "github.com/google/cadvisor/info/v1" cadvisorapiv1 "github.com/google/cadvisor/info/v1"
cadvisorapiv2 "github.com/google/cadvisor/info/v2" cadvisorapiv2 "github.com/google/cadvisor/info/v2"
fuzz "github.com/google/gofuzz"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"sigs.k8s.io/randfill"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
@ -389,9 +389,9 @@ func getPodVolumeStats(seed int, volumeName string) statsapi.VolumeStats {
} }
func generateCustomMetricSpec() []cadvisorapiv1.MetricSpec { func generateCustomMetricSpec() []cadvisorapiv1.MetricSpec {
f := fuzz.New().NilChance(0).Funcs( f := randfill.New().NilChance(0).Funcs(
func(e *cadvisorapiv1.MetricSpec, c fuzz.Continue) { func(e *cadvisorapiv1.MetricSpec, c randfill.Continue) {
c.Fuzz(&e.Name) c.Fill(&e.Name)
switch c.Intn(3) { switch c.Intn(3) {
case 0: case 0:
e.Type = cadvisorapiv1.MetricGauge e.Type = cadvisorapiv1.MetricGauge
@ -406,28 +406,28 @@ func generateCustomMetricSpec() []cadvisorapiv1.MetricSpec {
case 1: case 1:
e.Format = cadvisorapiv1.FloatType e.Format = cadvisorapiv1.FloatType
} }
c.Fuzz(&e.Units) c.Fill(&e.Units)
}) })
var ret []cadvisorapiv1.MetricSpec var ret []cadvisorapiv1.MetricSpec
f.Fuzz(&ret) f.Fill(&ret)
return ret return ret
} }
func generateCustomMetrics(spec []cadvisorapiv1.MetricSpec) map[string][]cadvisorapiv1.MetricVal { func generateCustomMetrics(spec []cadvisorapiv1.MetricSpec) map[string][]cadvisorapiv1.MetricVal {
ret := map[string][]cadvisorapiv1.MetricVal{} ret := map[string][]cadvisorapiv1.MetricVal{}
for _, metricSpec := range spec { for _, metricSpec := range spec {
f := fuzz.New().NilChance(0).Funcs( f := randfill.New().NilChance(0).Funcs(
func(e *cadvisorapiv1.MetricVal, c fuzz.Continue) { func(e *cadvisorapiv1.MetricVal, c randfill.Continue) {
switch metricSpec.Format { switch metricSpec.Format {
case cadvisorapiv1.IntType: case cadvisorapiv1.IntType:
c.Fuzz(&e.IntValue) c.Fill(&e.IntValue)
case cadvisorapiv1.FloatType: case cadvisorapiv1.FloatType:
c.Fuzz(&e.FloatValue) c.Fill(&e.FloatValue)
} }
}) })
var metrics []cadvisorapiv1.MetricVal var metrics []cadvisorapiv1.MetricVal
f.Fuzz(&metrics) f.Fill(&metrics)
ret[metricSpec.Name] = metrics ret[metricSpec.Name] = metrics
} }
return ret return ret

View File

@ -21,7 +21,7 @@ import (
"net/netip" "net/netip"
"time" "time"
"github.com/google/gofuzz" "sigs.k8s.io/randfill"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer"
@ -30,7 +30,7 @@ import (
) )
// generateRandomIP is copied from pkg/apis/networking/fuzzer/fuzzer.go // generateRandomIP is copied from pkg/apis/networking/fuzzer/fuzzer.go
func generateRandomIP(is6 bool, c fuzz.Continue) string { func generateRandomIP(is6 bool, c randfill.Continue) string {
n := 4 n := 4
if is6 { if is6 {
n = 16 n = 16
@ -49,7 +49,7 @@ func generateRandomIP(is6 bool, c fuzz.Continue) string {
} }
// generateRandomCIDR is copied from pkg/apis/networking/fuzzer/fuzzer.go // generateRandomCIDR is copied from pkg/apis/networking/fuzzer/fuzzer.go
func generateRandomCIDR(is6 bool, c fuzz.Continue) string { func generateRandomCIDR(is6 bool, c randfill.Continue) string {
ip, err := netip.ParseAddr(generateRandomIP(is6, c)) ip, err := netip.ParseAddr(generateRandomIP(is6, c))
if err != nil { if err != nil {
// generateRandomIP already panics if returns a not valid ip // generateRandomIP already panics if returns a not valid ip
@ -67,12 +67,12 @@ func generateRandomCIDR(is6 bool, c fuzz.Continue) string {
} }
// getRandomDualStackCIDR returns a random dual-stack CIDR. // getRandomDualStackCIDR returns a random dual-stack CIDR.
func getRandomDualStackCIDR(c fuzz.Continue) []string { func getRandomDualStackCIDR(c randfill.Continue) []string {
cidrIPv4 := generateRandomCIDR(false, c) cidrIPv4 := generateRandomCIDR(false, c)
cidrIPv6 := generateRandomCIDR(true, c) cidrIPv6 := generateRandomCIDR(true, c)
cidrs := []string{cidrIPv4, cidrIPv6} cidrs := []string{cidrIPv4, cidrIPv6}
if c.RandBool() { if c.Bool() {
cidrs = []string{cidrIPv6, cidrIPv4} cidrs = []string{cidrIPv6, cidrIPv4}
} }
return cidrs[:1+c.Intn(2)] return cidrs[:1+c.Intn(2)]
@ -81,19 +81,19 @@ func getRandomDualStackCIDR(c fuzz.Continue) []string {
// Funcs returns the fuzzer functions for the kube-proxy apis. // Funcs returns the fuzzer functions for the kube-proxy apis.
func Funcs(codecs runtimeserializer.CodecFactory) []interface{} { func Funcs(codecs runtimeserializer.CodecFactory) []interface{} {
return []interface{}{ return []interface{}{
func(obj *kubeproxyconfig.KubeProxyConfiguration, c fuzz.Continue) { func(obj *kubeproxyconfig.KubeProxyConfiguration, c randfill.Continue) {
c.FuzzNoCustom(obj) c.FillNoCustom(obj)
obj.BindAddress = fmt.Sprintf("%d.%d.%d.%d", c.Intn(256), c.Intn(256), c.Intn(256), c.Intn(256)) obj.BindAddress = fmt.Sprintf("%d.%d.%d.%d", c.Intn(256), c.Intn(256), c.Intn(256), c.Intn(256))
obj.ClientConnection.ContentType = c.RandString() obj.ClientConnection.ContentType = c.String(0)
obj.DetectLocal.ClusterCIDRs = getRandomDualStackCIDR(c) obj.DetectLocal.ClusterCIDRs = getRandomDualStackCIDR(c)
obj.Linux.Conntrack.MaxPerCore = ptr.To(c.Int31()) obj.Linux.Conntrack.MaxPerCore = ptr.To(c.Int31())
obj.Linux.Conntrack.Min = ptr.To(c.Int31()) obj.Linux.Conntrack.Min = ptr.To(c.Int31())
obj.Linux.Conntrack.TCPCloseWaitTimeout = &metav1.Duration{Duration: time.Duration(c.Int63()) * time.Hour} obj.Linux.Conntrack.TCPCloseWaitTimeout = &metav1.Duration{Duration: time.Duration(c.Int63()) * time.Hour}
obj.Linux.Conntrack.TCPEstablishedTimeout = &metav1.Duration{Duration: time.Duration(c.Int63()) * time.Hour} obj.Linux.Conntrack.TCPEstablishedTimeout = &metav1.Duration{Duration: time.Duration(c.Int63()) * time.Hour}
obj.FeatureGates = map[string]bool{c.RandString(): true} obj.FeatureGates = map[string]bool{c.String(0): true}
obj.HealthzBindAddress = fmt.Sprintf("%d.%d.%d.%d:%d", c.Intn(256), c.Intn(256), c.Intn(256), c.Intn(256), c.Intn(65536)) obj.HealthzBindAddress = fmt.Sprintf("%d.%d.%d.%d:%d", c.Intn(256), c.Intn(256), c.Intn(256), c.Intn(256), c.Intn(65536))
obj.IPTables.MasqueradeBit = ptr.To(c.Int31()) obj.IPTables.MasqueradeBit = ptr.To(c.Int31())
obj.IPTables.LocalhostNodePorts = ptr.To(c.RandBool()) obj.IPTables.LocalhostNodePorts = ptr.To(c.Bool())
obj.NFTables.MasqueradeBit = ptr.To(c.Int31()) obj.NFTables.MasqueradeBit = ptr.To(c.Int31())
obj.MetricsBindAddress = fmt.Sprintf("%d.%d.%d.%d:%d", c.Intn(256), c.Intn(256), c.Intn(256), c.Intn(256), c.Intn(65536)) obj.MetricsBindAddress = fmt.Sprintf("%d.%d.%d.%d:%d", c.Intn(256), c.Intn(256), c.Intn(256), c.Intn(256), c.Intn(65536))
obj.Linux.OOMScoreAdj = ptr.To(c.Int31()) obj.Linux.OOMScoreAdj = ptr.To(c.Int31())

View File

@ -26,7 +26,7 @@ import (
kapi "k8s.io/kubernetes/pkg/apis/core" kapi "k8s.io/kubernetes/pkg/apis/core"
kapihelper "k8s.io/kubernetes/pkg/apis/core/helper" kapihelper "k8s.io/kubernetes/pkg/apis/core/helper"
fuzz "github.com/google/gofuzz" "sigs.k8s.io/randfill"
) )
func newPod() *kapi.Pod { func newPod() *kapi.Pod {
@ -172,10 +172,10 @@ func TestIsOnlyMutatingGCFields(t *testing.T) {
} }
func TestNewMetadataFields(t *testing.T) { func TestNewMetadataFields(t *testing.T) {
f := fuzz.New().NilChance(0.0).NumElements(1, 1) f := randfill.New().NilChance(0.0).NumElements(1, 1)
for i := 0; i < 100; i++ { for i := 0; i < 100; i++ {
objMeta := metav1.ObjectMeta{} objMeta := metav1.ObjectMeta{}
f.Fuzz(&objMeta) f.Fill(&objMeta)
objMeta.Name = "" objMeta.Name = ""
objMeta.GenerateName = "" objMeta.GenerateName = ""
objMeta.Namespace = "" objMeta.Namespace = ""

View File

@ -20,7 +20,7 @@ import (
"reflect" "reflect"
"strings" "strings"
fuzz "github.com/google/gofuzz" "sigs.k8s.io/randfill"
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions" "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -33,8 +33,8 @@ var swaggerMetadataDescriptions = metav1.ObjectMeta{}.SwaggerDoc()
// Funcs returns the fuzzer functions for the apiextensions apis. // Funcs returns the fuzzer functions for the apiextensions apis.
func Funcs(codecs runtimeserializer.CodecFactory) []interface{} { func Funcs(codecs runtimeserializer.CodecFactory) []interface{} {
return []interface{}{ return []interface{}{
func(obj *apiextensions.CustomResourceDefinitionSpec, c fuzz.Continue) { func(obj *apiextensions.CustomResourceDefinitionSpec, c randfill.Continue) {
c.FuzzNoCustom(obj) c.FillNoCustom(obj)
// match our defaulter // match our defaulter
if len(obj.Scope) == 0 { if len(obj.Scope) == 0 {
@ -66,7 +66,7 @@ func Funcs(codecs runtimeserializer.CodecFactory) []interface{} {
{Name: "Age", Type: "date", Description: swaggerMetadataDescriptions["creationTimestamp"], JSONPath: ".metadata.creationTimestamp"}, {Name: "Age", Type: "date", Description: swaggerMetadataDescriptions["creationTimestamp"], JSONPath: ".metadata.creationTimestamp"},
} }
} }
c.Fuzz(&obj.SelectableFields) c.Fill(&obj.SelectableFields)
if obj.Conversion == nil { if obj.Conversion == nil {
obj.Conversion = &apiextensions.CustomResourceConversion{ obj.Conversion = &apiextensions.CustomResourceConversion{
Strategy: apiextensions.NoneConverter, Strategy: apiextensions.NoneConverter,
@ -100,8 +100,8 @@ func Funcs(codecs runtimeserializer.CodecFactory) []interface{} {
} }
} }
}, },
func(obj *apiextensions.CustomResourceDefinition, c fuzz.Continue) { func(obj *apiextensions.CustomResourceDefinition, c randfill.Continue) {
c.FuzzNoCustom(obj) c.FillNoCustom(obj)
if len(obj.Status.StoredVersions) == 0 { if len(obj.Status.StoredVersions) == 0 {
for _, v := range obj.Spec.Versions { for _, v := range obj.Spec.Versions {
@ -111,7 +111,7 @@ func Funcs(codecs runtimeserializer.CodecFactory) []interface{} {
} }
} }
}, },
func(obj *apiextensions.JSONSchemaProps, c fuzz.Continue) { func(obj *apiextensions.JSONSchemaProps, c randfill.Continue) {
// we cannot use c.FuzzNoCustom because of the interface{} fields. So let's loop with reflection. // we cannot use c.FuzzNoCustom because of the interface{} fields. So let's loop with reflection.
vobj := reflect.ValueOf(obj).Elem() vobj := reflect.ValueOf(obj).Elem()
tobj := reflect.TypeOf(obj).Elem() tobj := reflect.TypeOf(obj).Elem()
@ -127,22 +127,22 @@ func Funcs(codecs runtimeserializer.CodecFactory) []interface{} {
isValue = false isValue = false
} }
if isValue || c.Intn(10) == 0 { if isValue || c.Intn(10) == 0 {
c.Fuzz(vobj.Field(i).Addr().Interface()) c.Fill(vobj.Field(i).Addr().Interface())
} }
} }
} }
if c.RandBool() { if c.Bool() {
validJSON := apiextensions.JSON(`{"some": {"json": "test"}, "string": 42}`) validJSON := apiextensions.JSON(`{"some": {"json": "test"}, "string": 42}`)
obj.Default = &validJSON obj.Default = &validJSON
} }
if c.RandBool() { if c.Bool() {
obj.Enum = []apiextensions.JSON{c.Float64(), c.RandString(), c.RandBool()} obj.Enum = []apiextensions.JSON{c.Float64(), c.String(0), c.Bool()}
} }
if c.RandBool() { if c.Bool() {
validJSON := apiextensions.JSON(`"foobarbaz"`) validJSON := apiextensions.JSON(`"foobarbaz"`)
obj.Example = &validJSON obj.Example = &validJSON
} }
if c.RandBool() { if c.Bool() {
validRef := "validRef" validRef := "validRef"
obj.Ref = &validRef obj.Ref = &validRef
} }
@ -153,41 +153,41 @@ func Funcs(codecs runtimeserializer.CodecFactory) []interface{} {
obj.Type = "" obj.Type = ""
} }
}, },
func(obj *apiextensions.JSONSchemaPropsOrBool, c fuzz.Continue) { func(obj *apiextensions.JSONSchemaPropsOrBool, c randfill.Continue) {
if c.RandBool() { if c.Bool() {
obj.Allows = true obj.Allows = true
obj.Schema = &apiextensions.JSONSchemaProps{} obj.Schema = &apiextensions.JSONSchemaProps{}
c.Fuzz(obj.Schema) c.Fill(obj.Schema)
} else { } else {
obj.Allows = c.RandBool() obj.Allows = c.Bool()
} }
}, },
func(obj *apiextensions.JSONSchemaPropsOrArray, c fuzz.Continue) { func(obj *apiextensions.JSONSchemaPropsOrArray, c randfill.Continue) {
// disallow both Schema and JSONSchemas to be nil. // disallow both Schema and JSONSchemas to be nil.
if c.RandBool() { if c.Bool() {
obj.Schema = &apiextensions.JSONSchemaProps{} obj.Schema = &apiextensions.JSONSchemaProps{}
c.Fuzz(obj.Schema) c.Fill(obj.Schema)
} else { } else {
obj.JSONSchemas = make([]apiextensions.JSONSchemaProps, c.Intn(3)+1) obj.JSONSchemas = make([]apiextensions.JSONSchemaProps, c.Intn(3)+1)
for i := range obj.JSONSchemas { for i := range obj.JSONSchemas {
c.Fuzz(&obj.JSONSchemas[i]) c.Fill(&obj.JSONSchemas[i])
} }
} }
}, },
func(obj *apiextensions.JSONSchemaPropsOrStringArray, c fuzz.Continue) { func(obj *apiextensions.JSONSchemaPropsOrStringArray, c randfill.Continue) {
if c.RandBool() { if c.Bool() {
obj.Schema = &apiextensions.JSONSchemaProps{} obj.Schema = &apiextensions.JSONSchemaProps{}
c.Fuzz(obj.Schema) c.Fill(obj.Schema)
} else { } else {
c.Fuzz(&obj.Property) c.Fill(&obj.Property)
} }
}, },
func(obj *int64, c fuzz.Continue) { func(obj *int64, c randfill.Continue) {
// JSON only supports 53 bits because everything is a float // JSON only supports 53 bits because everything is a float
*obj = int64(c.Uint64()) & ((int64(1) << 53) - 1) *obj = int64(c.Uint64()) & ((int64(1) << 53) - 1)
}, },
func(obj *apiextensions.ValidationRule, c fuzz.Continue) { func(obj *apiextensions.ValidationRule, c randfill.Continue) {
c.FuzzNoCustom(obj) c.FillNoCustom(obj)
if obj.Reason != nil && *(obj.Reason) == "" { if obj.Reason != nil && *(obj.Reason) == "" {
obj.Reason = nil obj.Reason = nil
} }

View File

@ -10948,7 +10948,7 @@ func TestSchemaHasDefaults(t *testing.T) {
for i := 0; i < 10000; i++ { for i := 0; i < 10000; i++ {
// fuzz internal types // fuzz internal types
schema := &apiextensions.JSONSchemaProps{} schema := &apiextensions.JSONSchemaProps{}
f.Fuzz(schema) f.Fill(schema)
v1beta1Schema := &apiextensionsv1beta1.JSONSchemaProps{} v1beta1Schema := &apiextensionsv1beta1.JSONSchemaProps{}
if err := apiextensionsv1beta1.Convert_apiextensions_JSONSchemaProps_To_v1beta1_JSONSchemaProps(schema, v1beta1Schema, nil); err != nil { if err := apiextensionsv1beta1.Convert_apiextensions_JSONSchemaProps_To_v1beta1_JSONSchemaProps(schema, v1beta1Schema, nil); err != nil {
@ -11072,7 +11072,7 @@ func BenchmarkSchemaHas(b *testing.B) {
f := fuzzer.FuzzerFor(fuzzerFuncs, rand.NewSource(seed), codecs) f := fuzzer.FuzzerFor(fuzzerFuncs, rand.NewSource(seed), codecs)
// fuzz internal types // fuzz internal types
schema := &apiextensions.JSONSchemaProps{} schema := &apiextensions.JSONSchemaProps{}
f.NilChance(0).NumElements(10, 10).MaxDepth(10).Fuzz(schema) f.NilChance(0).NumElements(10, 10).MaxDepth(10).Fill(schema)
b.ReportAllocs() b.ReportAllocs()
b.ResetTimer() b.ResetTimer()

View File

@ -21,8 +21,8 @@ import (
"strconv" "strconv"
"testing" "testing"
fuzz "github.com/google/gofuzz"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"sigs.k8s.io/randfill"
apiextensionsfuzzer "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/fuzzer" apiextensionsfuzzer "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/fuzzer"
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/install" "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/install"
@ -81,8 +81,8 @@ func TestRoundtripToUnstructured(t *testing.T) {
apiextensionsfuzzer.Funcs, apiextensionsfuzzer.Funcs,
func(_ serializer.CodecFactory) []any { func(_ serializer.CodecFactory) []any {
return []any{ return []any{
func(obj *apiextensionsv1.ConversionReview, c fuzz.Continue) { func(obj *apiextensionsv1.ConversionReview, c randfill.Continue) {
c.FuzzNoCustom(obj) c.FillNoCustom(obj)
if obj.Request != nil { if obj.Request != nil {
for i := range obj.Request.Objects { for i := range obj.Request.Objects {
fuzzer.NormalizeJSONRawExtension(&obj.Request.Objects[i]) fuzzer.NormalizeJSONRawExtension(&obj.Request.Objects[i])
@ -94,8 +94,8 @@ func TestRoundtripToUnstructured(t *testing.T) {
} }
} }
}, },
func(obj *apiextensionsv1beta1.ConversionReview, c fuzz.Continue) { func(obj *apiextensionsv1beta1.ConversionReview, c randfill.Continue) {
c.FuzzNoCustom(obj) c.FillNoCustom(obj)
if obj.Request != nil { if obj.Request != nil {
for i := range obj.Request.Objects { for i := range obj.Request.Objects {
fuzzer.NormalizeJSONRawExtension(&obj.Request.Objects[i]) fuzzer.NormalizeJSONRawExtension(&obj.Request.Objects[i])

View File

@ -23,7 +23,7 @@ import (
"time" "time"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
fuzz "github.com/google/gofuzz" "sigs.k8s.io/randfill"
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions" "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
@ -31,31 +31,31 @@ import (
) )
func TestStructuralRoundtripOrError(t *testing.T) { func TestStructuralRoundtripOrError(t *testing.T) {
f := fuzz.New() f := randfill.New()
seed := time.Now().UnixNano() seed := time.Now().UnixNano()
t.Logf("seed = %v", seed) t.Logf("seed = %v", seed)
//seed = int64(1549012506261785182) //seed = int64(1549012506261785182)
f.RandSource(rand.New(rand.NewSource(seed))) f.RandSource(rand.New(rand.NewSource(seed)))
f.Funcs( f.Funcs(
func(s *apiextensions.JSON, c fuzz.Continue) { func(s *apiextensions.JSON, c randfill.Continue) {
*s = apiextensions.JSON(map[string]interface{}{"foo": float64(42.2)}) *s = apiextensions.JSON(map[string]interface{}{"foo": float64(42.2)})
}, },
func(s *apiextensions.JSONSchemaPropsOrArray, c fuzz.Continue) { func(s *apiextensions.JSONSchemaPropsOrArray, c randfill.Continue) {
c.FuzzNoCustom(s) c.FillNoCustom(s)
if s.Schema != nil { if s.Schema != nil {
s.JSONSchemas = nil s.JSONSchemas = nil
} else if s.JSONSchemas == nil { } else if s.JSONSchemas == nil {
s.Schema = &apiextensions.JSONSchemaProps{} s.Schema = &apiextensions.JSONSchemaProps{}
} }
}, },
func(s *apiextensions.JSONSchemaPropsOrBool, c fuzz.Continue) { func(s *apiextensions.JSONSchemaPropsOrBool, c randfill.Continue) {
c.FuzzNoCustom(s) c.FillNoCustom(s)
if s.Schema != nil { if s.Schema != nil {
s.Allows = false s.Allows = false
} }
}, },
func(s **string, c fuzz.Continue) { func(s **string, c randfill.Continue) {
c.FuzzNoCustom(s) c.FillNoCustom(s)
if *s != nil && **s == "" { if *s != nil && **s == "" {
*s = nil *s = nil
} }
@ -74,7 +74,7 @@ func TestStructuralRoundtripOrError(t *testing.T) {
// we drop these intentionally // we drop these intentionally
continue continue
} }
f.Fuzz(x.Field(n).Addr().Interface()) f.Fill(x.Field(n).Addr().Interface())
// it roundtrips or NewStructural errors out. We should never drop anything // it roundtrips or NewStructural errors out. We should never drop anything
orig, err := NewStructural(origSchema) orig, err := NewStructural(origSchema)

View File

@ -23,7 +23,7 @@ import (
"time" "time"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
fuzz "github.com/google/gofuzz" "sigs.k8s.io/randfill"
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions" "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
@ -31,13 +31,13 @@ import (
) )
func TestStructuralKubeOpenAPIRoundtrip(t *testing.T) { func TestStructuralKubeOpenAPIRoundtrip(t *testing.T) {
f := fuzz.New() f := randfill.New()
seed := time.Now().UnixNano() seed := time.Now().UnixNano()
t.Logf("seed = %v", seed) t.Logf("seed = %v", seed)
//seed = int64(1549012506261785182) //seed = int64(1549012506261785182)
f.RandSource(rand.New(rand.NewSource(seed))) f.RandSource(rand.New(rand.NewSource(seed)))
f.Funcs( f.Funcs(
func(s *JSON, c fuzz.Continue) { func(s *JSON, c randfill.Continue) {
switch c.Intn(7) { switch c.Intn(7) {
case 0: case 0:
s.Object = float64(42.2) s.Object = float64(42.2)
@ -61,7 +61,7 @@ func TestStructuralKubeOpenAPIRoundtrip(t *testing.T) {
for i := 0; i < 10000; i++ { for i := 0; i < 10000; i++ {
orig := &Structural{} orig := &Structural{}
f.Fuzz(orig) f.Fill(orig)
// normalize Structural.ValueValidation to zero values if it was nil before // normalize Structural.ValueValidation to zero values if it was nil before
normalizer := Visitor{ normalizer := Visitor{

View File

@ -46,7 +46,7 @@ func TestRoundtripObjectMeta(t *testing.T) {
for i := 0; i < N; i++ { for i := 0; i < N; i++ {
u := &unstructured.Unstructured{Object: map[string]interface{}{}} u := &unstructured.Unstructured{Object: map[string]interface{}{}}
original := &metav1.ObjectMeta{} original := &metav1.ObjectMeta{}
fuzzer.Fuzz(original) fuzzer.Fill(original)
if err := SetObjectMeta(u.Object, original); err != nil { if err := SetObjectMeta(u.Object, original); err != nil {
t.Fatalf("unexpected error setting ObjectMeta: %v", err) t.Fatalf("unexpected error setting ObjectMeta: %v", err)
} }
@ -89,7 +89,7 @@ func TestMalformedObjectMetaFields(t *testing.T) {
N := 100 N := 100
for i := 0; i < N; i++ { for i := 0; i < N; i++ {
fuzzedObjectMeta := &metav1.ObjectMeta{} fuzzedObjectMeta := &metav1.ObjectMeta{}
fuzzer.Fuzz(fuzzedObjectMeta) fuzzer.Fill(fuzzedObjectMeta)
goodMetaMap, err := runtime.DefaultUnstructuredConverter.ToUnstructured(fuzzedObjectMeta.DeepCopy()) goodMetaMap, err := runtime.DefaultUnstructuredConverter.ToUnstructured(fuzzedObjectMeta.DeepCopy())
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)

View File

@ -24,39 +24,39 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/utils/ptr" "k8s.io/utils/ptr"
fuzz "github.com/google/gofuzz" "sigs.k8s.io/randfill"
) )
func TestValidateStructuralMetadataInvariants(t *testing.T) { func TestValidateStructuralMetadataInvariants(t *testing.T) {
fuzzer := fuzz.New() fuzzer := randfill.New()
fuzzer.Funcs( fuzzer.Funcs(
func(s *JSON, c fuzz.Continue) { func(s *JSON, c randfill.Continue) {
if c.RandBool() { if c.Bool() {
s.Object = float64(42.0) s.Object = float64(42.0)
} }
}, },
func(s **StructuralOrBool, c fuzz.Continue) { func(s **StructuralOrBool, c randfill.Continue) {
if c.RandBool() { if c.Bool() {
*s = &StructuralOrBool{} *s = &StructuralOrBool{}
} }
}, },
func(s **Structural, c fuzz.Continue) { func(s **Structural, c randfill.Continue) {
if c.RandBool() { if c.Bool() {
*s = &Structural{} *s = &Structural{}
} }
}, },
func(s *Structural, c fuzz.Continue) { func(s *Structural, c randfill.Continue) {
if c.RandBool() { if c.Bool() {
*s = Structural{} *s = Structural{}
} }
}, },
func(vv **NestedValueValidation, c fuzz.Continue) { func(vv **NestedValueValidation, c randfill.Continue) {
if c.RandBool() { if c.Bool() {
*vv = &NestedValueValidation{} *vv = &NestedValueValidation{}
} }
}, },
func(vv *NestedValueValidation, c fuzz.Continue) { func(vv *NestedValueValidation, c randfill.Continue) {
if c.RandBool() { if c.Bool() {
*vv = NestedValueValidation{} *vv = NestedValueValidation{}
} }
}, },
@ -114,7 +114,7 @@ func TestValidateStructuralMetadataInvariants(t *testing.T) {
for i := 0; i < tt.NumField(); i++ { for i := 0; i < tt.NumField(); i++ {
s := Structural{} s := Structural{}
x := reflect.ValueOf(&s).Elem() x := reflect.ValueOf(&s).Elem()
fuzzer.Fuzz(x.Field(i).Addr().Interface()) fuzzer.Fill(x.Field(i).Addr().Interface())
s.Type = "object" s.Type = "object"
s.Properties = map[string]Structural{ s.Properties = map[string]Structural{
"name": {}, "name": {},
@ -384,15 +384,15 @@ func TestValidateStructuralCompleteness(t *testing.T) {
} }
func TestValidateNestedValueValidationComplete(t *testing.T) { func TestValidateNestedValueValidationComplete(t *testing.T) {
fuzzer := fuzz.New() fuzzer := randfill.New()
fuzzer.Funcs( fuzzer.Funcs(
func(s *JSON, c fuzz.Continue) { func(s *JSON, c randfill.Continue) {
if c.RandBool() { if c.Bool() {
s.Object = float64(42.0) s.Object = float64(42.0)
} }
}, },
func(s **NestedValueValidation, c fuzz.Continue) { func(s **NestedValueValidation, c randfill.Continue) {
if c.RandBool() { if c.Bool() {
*s = &NestedValueValidation{} *s = &NestedValueValidation{}
} }
}, },
@ -404,7 +404,7 @@ func TestValidateNestedValueValidationComplete(t *testing.T) {
for i := 0; i < tt.NumField(); i++ { for i := 0; i < tt.NumField(); i++ {
vv := &NestedValueValidation{} vv := &NestedValueValidation{}
x := reflect.ValueOf(&vv.ForbiddenGenerics).Elem() x := reflect.ValueOf(&vv.ForbiddenGenerics).Elem()
fuzzer.Fuzz(x.Field(i).Addr().Interface()) fuzzer.Fill(x.Field(i).Addr().Interface())
errs := validateNestedValueValidation(vv, false, false, fieldLevel, nil, ValidationOptions{}) errs := validateNestedValueValidation(vv, false, false, fieldLevel, nil, ValidationOptions{})
if len(errs) == 0 && !reflect.DeepEqual(vv.ForbiddenGenerics, Generic{}) { if len(errs) == 0 && !reflect.DeepEqual(vv.ForbiddenGenerics, Generic{}) {
@ -417,7 +417,7 @@ func TestValidateNestedValueValidationComplete(t *testing.T) {
for i := 0; i < tt.NumField(); i++ { for i := 0; i < tt.NumField(); i++ {
vv := &NestedValueValidation{} vv := &NestedValueValidation{}
x := reflect.ValueOf(&vv.ForbiddenExtensions).Elem() x := reflect.ValueOf(&vv.ForbiddenExtensions).Elem()
fuzzer.Fuzz(x.Field(i).Addr().Interface()) fuzzer.Fill(x.Field(i).Addr().Interface())
errs := validateNestedValueValidation(vv, false, false, fieldLevel, nil, ValidationOptions{}) errs := validateNestedValueValidation(vv, false, false, fieldLevel, nil, ValidationOptions{})
if len(errs) == 0 && !reflect.DeepEqual(vv.ForbiddenExtensions, Extensions{}) { if len(errs) == 0 && !reflect.DeepEqual(vv.ForbiddenExtensions, Extensions{}) {
@ -433,7 +433,7 @@ func TestValidateNestedValueValidationComplete(t *testing.T) {
} }
vv := NestedValueValidation{} vv := NestedValueValidation{}
fuzzer.Fuzz(&vv.ValidationExtensions.XValidations) fuzzer.Fill(&vv.ValidationExtensions.XValidations)
errs := validateNestedValueValidation(&vv, false, false, fieldLevel, nil, opts) errs := validateNestedValueValidation(&vv, false, false, fieldLevel, nil, opts)
if allowedNestedXValidations { if allowedNestedXValidations {
if len(errs) != 0 { if len(errs) != 0 {
@ -444,7 +444,7 @@ func TestValidateNestedValueValidationComplete(t *testing.T) {
} }
vv = NestedValueValidation{} vv = NestedValueValidation{}
fuzzer.Fuzz(&vv.AdditionalProperties) fuzzer.Fill(&vv.AdditionalProperties)
errs = validateNestedValueValidation(&vv, false, false, fieldLevel, nil, opts) errs = validateNestedValueValidation(&vv, false, false, fieldLevel, nil, opts)
if allowedNestedAdditionalProperties { if allowedNestedAdditionalProperties {
if len(errs) != 0 { if len(errs) != 0 {

View File

@ -76,7 +76,7 @@ func TestRoundTrip(t *testing.T) {
for i := 0; i < 50; i++ { for i := 0; i < 50; i++ {
// fuzz internal types // fuzz internal types
internal := &apiextensions.JSONSchemaProps{} internal := &apiextensions.JSONSchemaProps{}
f.Fuzz(internal) f.Fill(internal)
// internal -> go-openapi // internal -> go-openapi
openAPITypes := &kubeopenapispec.Schema{} openAPITypes := &kubeopenapispec.Schema{}

View File

@ -27,7 +27,7 @@ import (
openapi_v2 "github.com/google/gnostic-models/openapiv2" openapi_v2 "github.com/google/gnostic-models/openapiv2"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
fuzz "github.com/google/gofuzz" "sigs.k8s.io/randfill"
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions" "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
@ -704,15 +704,15 @@ func refEqual(x spec.Ref, y spec.Ref) bool {
func TestKubeOpenapiRejectionFiltering(t *testing.T) { func TestKubeOpenapiRejectionFiltering(t *testing.T) {
// 1000 iterations runs for ~2 seconds with race detection enabled // 1000 iterations runs for ~2 seconds with race detection enabled
for i := 0; i < 1000; i++ { for i := 0; i < 1000; i++ {
f := fuzz.New() f := randfill.New()
seed := time.Now().UnixNano() seed := time.Now().UnixNano()
randSource := rand.New(rand.NewSource(seed)) randSource := rand.New(rand.NewSource(seed))
f.RandSource(randSource) f.RandSource(randSource)
t.Logf("iteration %d with seed %d", i, seed) t.Logf("iteration %d with seed %d", i, seed)
fuzzFuncs(f, func(ref *spec.Ref, c fuzz.Continue, visible bool) { fuzzFuncs(f, func(ref *spec.Ref, c randfill.Continue, visible bool) {
var url string var url string
if c.RandBool() { if c.Bool() {
url = fmt.Sprintf("http://%d", c.Intn(100000)) url = fmt.Sprintf("http://%d", c.Intn(100000))
} else { } else {
url = "#/definitions/test" url = "#/definitions/test"
@ -726,7 +726,7 @@ func TestKubeOpenapiRejectionFiltering(t *testing.T) {
// create go-openapi object and fuzz it (we start here because we have the powerful fuzzer already // create go-openapi object and fuzz it (we start here because we have the powerful fuzzer already
s := &spec.Schema{} s := &spec.Schema{}
f.Fuzz(s) f.Fill(s)
// convert to apiextensions v1beta1 // convert to apiextensions v1beta1
bs, err := json.Marshal(s) bs, err := json.Marshal(s)
@ -790,7 +790,7 @@ func TestKubeOpenapiRejectionFiltering(t *testing.T) {
} }
// fuzzFuncs is copied from kube-openapi/pkg/aggregator. It fuzzes go-openapi/spec schemata. // fuzzFuncs is copied from kube-openapi/pkg/aggregator. It fuzzes go-openapi/spec schemata.
func fuzzFuncs(f *fuzz.Fuzzer, refFunc func(ref *spec.Ref, c fuzz.Continue, visible bool)) { func fuzzFuncs(f *randfill.Filler, refFunc func(ref *spec.Ref, c randfill.Continue, visible bool)) {
invisible := 0 // == 0 means visible, > 0 means invisible invisible := 0 // == 0 means visible, > 0 means invisible
depth := 0 depth := 0
maxDepth := 3 maxDepth := 3
@ -802,14 +802,14 @@ func fuzzFuncs(f *fuzz.Fuzzer, refFunc func(ref *spec.Ref, c fuzz.Continue, visi
f.NumElements(0, max(0, maxDepth-depth)) f.NumElements(0, max(0, maxDepth-depth))
} }
updateFuzzer(depth) updateFuzzer(depth)
enter := func(o interface{}, recursive bool, c fuzz.Continue) { enter := func(o interface{}, recursive bool, c randfill.Continue) {
if recursive { if recursive {
depth++ depth++
updateFuzzer(depth) updateFuzzer(depth)
} }
invisible++ invisible++
c.FuzzNoCustom(o) c.FillNoCustom(o)
invisible-- invisible--
} }
leave := func(recursive bool) { leave := func(recursive bool) {
@ -819,31 +819,31 @@ func fuzzFuncs(f *fuzz.Fuzzer, refFunc func(ref *spec.Ref, c fuzz.Continue, visi
} }
} }
f.Funcs( f.Funcs(
func(ref *spec.Ref, c fuzz.Continue) { func(ref *spec.Ref, c randfill.Continue) {
refFunc(ref, c, invisible == 0) refFunc(ref, c, invisible == 0)
}, },
func(sa *spec.SchemaOrStringArray, c fuzz.Continue) { func(sa *spec.SchemaOrStringArray, c randfill.Continue) {
*sa = spec.SchemaOrStringArray{} *sa = spec.SchemaOrStringArray{}
if c.RandBool() { if c.Bool() {
c.Fuzz(&sa.Schema) c.Fill(&sa.Schema)
} else { } else {
c.Fuzz(&sa.Property) c.Fill(&sa.Property)
} }
if sa.Schema == nil && len(sa.Property) == 0 { if sa.Schema == nil && len(sa.Property) == 0 {
*sa = spec.SchemaOrStringArray{Schema: &spec.Schema{}} *sa = spec.SchemaOrStringArray{Schema: &spec.Schema{}}
} }
}, },
func(url *spec.SchemaURL, c fuzz.Continue) { func(url *spec.SchemaURL, c randfill.Continue) {
*url = spec.SchemaURL("http://url") *url = spec.SchemaURL("http://url")
}, },
func(s *spec.Dependencies, c fuzz.Continue) { func(s *spec.Dependencies, c randfill.Continue) {
enter(s, false, c) enter(s, false, c)
defer leave(false) defer leave(false)
// and nothing with invisible==false // and nothing with invisible==false
}, },
func(p *spec.SimpleSchema, c fuzz.Continue) { func(p *spec.SimpleSchema, c randfill.Continue) {
// gofuzz is broken and calls this even for *SimpleSchema fields, ignoring NilChance, leading to infinite recursion // randfill is broken and calls this even for *SimpleSchema fields, ignoring NilChance, leading to infinite recursion
if c.Float64() > nilChance(depth) { if c.Float64() > nilChance(depth) {
return return
} }
@ -851,7 +851,7 @@ func fuzzFuncs(f *fuzz.Fuzzer, refFunc func(ref *spec.Ref, c fuzz.Continue, visi
enter(p, true, c) enter(p, true, c)
defer leave(true) defer leave(true)
c.FuzzNoCustom(p) c.FillNoCustom(p)
// reset JSON fields to some correct JSON // reset JSON fields to some correct JSON
if p.Default != nil { if p.Default != nil {
@ -859,12 +859,12 @@ func fuzzFuncs(f *fuzz.Fuzzer, refFunc func(ref *spec.Ref, c fuzz.Continue, visi
} }
p.Example = nil p.Example = nil
}, },
func(s *spec.SwaggerSchemaProps, c fuzz.Continue) { func(s *spec.SwaggerSchemaProps, c randfill.Continue) {
// nothing allowed // nothing allowed
*s = spec.SwaggerSchemaProps{} *s = spec.SwaggerSchemaProps{}
}, },
func(s *spec.SchemaProps, c fuzz.Continue) { func(s *spec.SchemaProps, c randfill.Continue) {
// gofuzz is broken and calls this even for *SchemaProps fields, ignoring NilChance, leading to infinite recursion // randfill is broken and calls this even for *SchemaProps fields, ignoring NilChance, leading to infinite recursion
if c.Float64() > nilChance(depth) { if c.Float64() > nilChance(depth) {
return return
} }
@ -872,9 +872,9 @@ func fuzzFuncs(f *fuzz.Fuzzer, refFunc func(ref *spec.Ref, c fuzz.Continue, visi
enter(s, true, c) enter(s, true, c)
defer leave(true) defer leave(true)
c.FuzzNoCustom(s) c.FillNoCustom(s)
if c.RandBool() { if c.Bool() {
types := []string{"object", "array", "boolean", "string", "integer", "number"} types := []string{"object", "array", "boolean", "string", "integer", "number"}
s.Type = []string{types[c.Intn(len(types))]} s.Type = []string{types[c.Intn(len(types))]}
} else { } else {
@ -891,7 +891,7 @@ func fuzzFuncs(f *fuzz.Fuzzer, refFunc func(ref *spec.Ref, c fuzz.Continue, visi
if len(s.Type) == 1 && s.Type[0] == "array" { if len(s.Type) == 1 && s.Type[0] == "array" {
s.Items = &spec.SchemaOrArray{Schema: &spec.Schema{}} s.Items = &spec.SchemaOrArray{Schema: &spec.Schema{}}
c.Fuzz(s.Items.Schema) c.Fill(s.Items.Schema)
} else { } else {
s.Items = nil s.Items = nil
} }
@ -904,7 +904,7 @@ func fuzzFuncs(f *fuzz.Fuzzer, refFunc func(ref *spec.Ref, c fuzz.Continue, visi
s.Enum[i] = "42" s.Enum[i] = "42"
} }
}, },
func(i *interface{}, c fuzz.Continue) { func(i *interface{}, c randfill.Continue) {
// do nothing for examples and defaults. These are free form JSON fields. // do nothing for examples and defaults. These are free form JSON fields.
}, },
) )

View File

@ -21,19 +21,19 @@ import (
"fmt" "fmt"
"math/rand" "math/rand"
"github.com/google/gofuzz" "sigs.k8s.io/randfill"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer"
kjson "k8s.io/apimachinery/pkg/util/json" kjson "k8s.io/apimachinery/pkg/util/json"
) )
// FuzzerFuncs returns a list of func(*SomeType, c fuzz.Continue) functions. // FuzzerFuncs returns a list of func(*SomeType, c randfill.Continue) functions.
type FuzzerFuncs func(codecs runtimeserializer.CodecFactory) []interface{} type FuzzerFuncs func(codecs runtimeserializer.CodecFactory) []interface{}
// FuzzerFor can randomly populate api objects that are destined for version. // FuzzerFor can randomly populate api objects that are destined for version.
func FuzzerFor(funcs FuzzerFuncs, src rand.Source, codecs runtimeserializer.CodecFactory) *fuzz.Fuzzer { func FuzzerFor(funcs FuzzerFuncs, src rand.Source, codecs runtimeserializer.CodecFactory) *randfill.Filler {
f := fuzz.New().NilChance(.5).NumElements(0, 1) f := randfill.New().NilChance(.5).NumElements(0, 1)
if src != nil { if src != nil {
f.RandSource(src) f.RandSource(src)
} }

View File

@ -25,8 +25,8 @@ import (
"testing" "testing"
"github.com/google/go-cmp/cmp" //nolint:depguard "github.com/google/go-cmp/cmp" //nolint:depguard
fuzz "github.com/google/gofuzz"
flag "github.com/spf13/pflag" flag "github.com/spf13/pflag"
"sigs.k8s.io/randfill"
apitesting "k8s.io/apimachinery/pkg/api/apitesting" apitesting "k8s.io/apimachinery/pkg/api/apitesting"
"k8s.io/apimachinery/pkg/api/apitesting/fuzzer" "k8s.io/apimachinery/pkg/api/apitesting/fuzzer"
@ -120,15 +120,15 @@ func GlobalNonRoundTrippableTypes() sets.String {
// RoundTripTypesWithoutProtobuf applies the round-trip test to all round-trippable Kinds // RoundTripTypesWithoutProtobuf applies the round-trip test to all round-trippable Kinds
// in the scheme. It will skip all the GroupVersionKinds in the skip list. // in the scheme. It will skip all the GroupVersionKinds in the skip list.
func RoundTripTypesWithoutProtobuf(t *testing.T, scheme *runtime.Scheme, codecFactory runtimeserializer.CodecFactory, fuzzer *fuzz.Fuzzer, nonRoundTrippableTypes map[schema.GroupVersionKind]bool) { func RoundTripTypesWithoutProtobuf(t *testing.T, scheme *runtime.Scheme, codecFactory runtimeserializer.CodecFactory, fuzzer *randfill.Filler, nonRoundTrippableTypes map[schema.GroupVersionKind]bool) {
roundTripTypes(t, scheme, codecFactory, fuzzer, nonRoundTrippableTypes, true) roundTripTypes(t, scheme, codecFactory, fuzzer, nonRoundTrippableTypes, true)
} }
func RoundTripTypes(t *testing.T, scheme *runtime.Scheme, codecFactory runtimeserializer.CodecFactory, fuzzer *fuzz.Fuzzer, nonRoundTrippableTypes map[schema.GroupVersionKind]bool) { func RoundTripTypes(t *testing.T, scheme *runtime.Scheme, codecFactory runtimeserializer.CodecFactory, fuzzer *randfill.Filler, nonRoundTrippableTypes map[schema.GroupVersionKind]bool) {
roundTripTypes(t, scheme, codecFactory, fuzzer, nonRoundTrippableTypes, false) roundTripTypes(t, scheme, codecFactory, fuzzer, nonRoundTrippableTypes, false)
} }
func roundTripTypes(t *testing.T, scheme *runtime.Scheme, codecFactory runtimeserializer.CodecFactory, fuzzer *fuzz.Fuzzer, nonRoundTrippableTypes map[schema.GroupVersionKind]bool, skipProtobuf bool) { func roundTripTypes(t *testing.T, scheme *runtime.Scheme, codecFactory runtimeserializer.CodecFactory, fuzzer *randfill.Filler, nonRoundTrippableTypes map[schema.GroupVersionKind]bool, skipProtobuf bool) {
for _, group := range groupsFromScheme(scheme) { for _, group := range groupsFromScheme(scheme) {
t.Logf("starting group %q", group) t.Logf("starting group %q", group)
internalVersion := schema.GroupVersion{Group: group, Version: runtime.APIVersionInternal} internalVersion := schema.GroupVersion{Group: group, Version: runtime.APIVersionInternal}
@ -149,7 +149,7 @@ func roundTripTypes(t *testing.T, scheme *runtime.Scheme, codecFactory runtimese
// RoundTripExternalTypes applies the round-trip test to all external round-trippable Kinds // RoundTripExternalTypes applies the round-trip test to all external round-trippable Kinds
// in the scheme. It will skip all the GroupVersionKinds in the nonRoundTripExternalTypes list . // in the scheme. It will skip all the GroupVersionKinds in the nonRoundTripExternalTypes list .
func RoundTripExternalTypes(t *testing.T, scheme *runtime.Scheme, codecFactory runtimeserializer.CodecFactory, fuzzer *fuzz.Fuzzer, nonRoundTrippableTypes map[schema.GroupVersionKind]bool) { func RoundTripExternalTypes(t *testing.T, scheme *runtime.Scheme, codecFactory runtimeserializer.CodecFactory, fuzzer *randfill.Filler, nonRoundTrippableTypes map[schema.GroupVersionKind]bool) {
kinds := scheme.AllKnownTypes() kinds := scheme.AllKnownTypes()
for gvk := range kinds { for gvk := range kinds {
if gvk.Version == runtime.APIVersionInternal || globalNonRoundTrippableTypes.Has(gvk.Kind) { if gvk.Version == runtime.APIVersionInternal || globalNonRoundTrippableTypes.Has(gvk.Kind) {
@ -163,7 +163,7 @@ func RoundTripExternalTypes(t *testing.T, scheme *runtime.Scheme, codecFactory r
// RoundTripExternalTypesWithoutProtobuf applies the round-trip test to all external round-trippable Kinds // RoundTripExternalTypesWithoutProtobuf applies the round-trip test to all external round-trippable Kinds
// in the scheme. It will skip all the GroupVersionKinds in the nonRoundTripExternalTypes list. // in the scheme. It will skip all the GroupVersionKinds in the nonRoundTripExternalTypes list.
func RoundTripExternalTypesWithoutProtobuf(t *testing.T, scheme *runtime.Scheme, codecFactory runtimeserializer.CodecFactory, fuzzer *fuzz.Fuzzer, nonRoundTrippableTypes map[schema.GroupVersionKind]bool) { func RoundTripExternalTypesWithoutProtobuf(t *testing.T, scheme *runtime.Scheme, codecFactory runtimeserializer.CodecFactory, fuzzer *randfill.Filler, nonRoundTrippableTypes map[schema.GroupVersionKind]bool) {
kinds := scheme.AllKnownTypes() kinds := scheme.AllKnownTypes()
for gvk := range kinds { for gvk := range kinds {
if gvk.Version == runtime.APIVersionInternal || globalNonRoundTrippableTypes.Has(gvk.Kind) { if gvk.Version == runtime.APIVersionInternal || globalNonRoundTrippableTypes.Has(gvk.Kind) {
@ -175,15 +175,15 @@ func RoundTripExternalTypesWithoutProtobuf(t *testing.T, scheme *runtime.Scheme,
} }
} }
func RoundTripSpecificKindWithoutProtobuf(t *testing.T, gvk schema.GroupVersionKind, scheme *runtime.Scheme, codecFactory runtimeserializer.CodecFactory, fuzzer *fuzz.Fuzzer, nonRoundTrippableTypes map[schema.GroupVersionKind]bool) { func RoundTripSpecificKindWithoutProtobuf(t *testing.T, gvk schema.GroupVersionKind, scheme *runtime.Scheme, codecFactory runtimeserializer.CodecFactory, fuzzer *randfill.Filler, nonRoundTrippableTypes map[schema.GroupVersionKind]bool) {
roundTripSpecificKind(t, gvk, scheme, codecFactory, fuzzer, nonRoundTrippableTypes, true) roundTripSpecificKind(t, gvk, scheme, codecFactory, fuzzer, nonRoundTrippableTypes, true)
} }
func RoundTripSpecificKind(t *testing.T, gvk schema.GroupVersionKind, scheme *runtime.Scheme, codecFactory runtimeserializer.CodecFactory, fuzzer *fuzz.Fuzzer, nonRoundTrippableTypes map[schema.GroupVersionKind]bool) { func RoundTripSpecificKind(t *testing.T, gvk schema.GroupVersionKind, scheme *runtime.Scheme, codecFactory runtimeserializer.CodecFactory, fuzzer *randfill.Filler, nonRoundTrippableTypes map[schema.GroupVersionKind]bool) {
roundTripSpecificKind(t, gvk, scheme, codecFactory, fuzzer, nonRoundTrippableTypes, false) roundTripSpecificKind(t, gvk, scheme, codecFactory, fuzzer, nonRoundTrippableTypes, false)
} }
func roundTripSpecificKind(t *testing.T, gvk schema.GroupVersionKind, scheme *runtime.Scheme, codecFactory runtimeserializer.CodecFactory, fuzzer *fuzz.Fuzzer, nonRoundTrippableTypes map[schema.GroupVersionKind]bool, skipProtobuf bool) { func roundTripSpecificKind(t *testing.T, gvk schema.GroupVersionKind, scheme *runtime.Scheme, codecFactory runtimeserializer.CodecFactory, fuzzer *randfill.Filler, nonRoundTrippableTypes map[schema.GroupVersionKind]bool, skipProtobuf bool) {
if nonRoundTrippableTypes[gvk] { if nonRoundTrippableTypes[gvk] {
t.Logf("skipping %v", gvk) t.Logf("skipping %v", gvk)
return return
@ -204,8 +204,8 @@ func roundTripSpecificKind(t *testing.T, gvk schema.GroupVersionKind, scheme *ru
// fuzzInternalObject fuzzes an arbitrary runtime object using the appropriate // fuzzInternalObject fuzzes an arbitrary runtime object using the appropriate
// fuzzer registered with the apitesting package. // fuzzer registered with the apitesting package.
func fuzzInternalObject(t *testing.T, fuzzer *fuzz.Fuzzer, object runtime.Object) runtime.Object { func fuzzInternalObject(t *testing.T, fuzzer *randfill.Filler, object runtime.Object) runtime.Object {
fuzzer.Fuzz(object) fuzzer.Fill(object)
j, err := apimeta.TypeAccessor(object) j, err := apimeta.TypeAccessor(object)
if err != nil { if err != nil {
@ -225,7 +225,7 @@ func groupsFromScheme(scheme *runtime.Scheme) []string {
return ret.List() return ret.List()
} }
func roundTripToAllExternalVersions(t *testing.T, scheme *runtime.Scheme, codecFactory runtimeserializer.CodecFactory, fuzzer *fuzz.Fuzzer, internalGVK schema.GroupVersionKind, nonRoundTrippableTypes map[schema.GroupVersionKind]bool, skipProtobuf bool) { func roundTripToAllExternalVersions(t *testing.T, scheme *runtime.Scheme, codecFactory runtimeserializer.CodecFactory, fuzzer *randfill.Filler, internalGVK schema.GroupVersionKind, nonRoundTrippableTypes map[schema.GroupVersionKind]bool, skipProtobuf bool) {
object, err := scheme.New(internalGVK) object, err := scheme.New(internalGVK)
if err != nil { if err != nil {
t.Fatalf("Couldn't make a %v? %v", internalGVK, err) t.Fatalf("Couldn't make a %v? %v", internalGVK, err)
@ -262,7 +262,7 @@ func roundTripToAllExternalVersions(t *testing.T, scheme *runtime.Scheme, codecF
} }
} }
func roundTripOfExternalType(t *testing.T, scheme *runtime.Scheme, codecFactory runtimeserializer.CodecFactory, fuzzer *fuzz.Fuzzer, externalGVK schema.GroupVersionKind, skipProtobuf bool) { func roundTripOfExternalType(t *testing.T, scheme *runtime.Scheme, codecFactory runtimeserializer.CodecFactory, fuzzer *randfill.Filler, externalGVK schema.GroupVersionKind, skipProtobuf bool) {
object, err := scheme.New(externalGVK) object, err := scheme.New(externalGVK)
if err != nil { if err != nil {
t.Fatalf("Couldn't make a %v? %v", externalGVK, err) t.Fatalf("Couldn't make a %v? %v", externalGVK, err)

View File

@ -92,13 +92,13 @@ func RoundtripToUnstructured(t *testing.T, scheme *runtime.Scheme, funcs fuzzer.
} }
if nointernal.Has(gvk) { if nointernal.Has(gvk) {
fuzzer.Fuzz(item) fuzzer.Fill(item)
} else { } else {
internalObj, err := scheme.New(gvk.GroupKind().WithVersion(runtime.APIVersionInternal)) internalObj, err := scheme.New(gvk.GroupKind().WithVersion(runtime.APIVersionInternal))
if err != nil { if err != nil {
t.Fatalf("couldn't create internal object %v: %v", gvk.Kind, err) t.Fatalf("couldn't create internal object %v: %v", gvk.Kind, err)
} }
fuzzer.Fuzz(internalObj) fuzzer.Fill(internalObj)
if err := scheme.Convert(internalObj, item, nil); err != nil { if err := scheme.Convert(internalObj, item, nil); err != nil {
t.Fatalf("conversion for %v failed: %v", gvk.Kind, err) t.Fatalf("conversion for %v failed: %v", gvk.Kind, err)

View File

@ -25,15 +25,15 @@ import (
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1" metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
fuzz "github.com/google/gofuzz" "sigs.k8s.io/randfill"
) )
func TestAsPartialObjectMetadata(t *testing.T) { func TestAsPartialObjectMetadata(t *testing.T) {
f := fuzz.New().NilChance(.5).NumElements(0, 1).RandSource(rand.NewSource(1)) f := randfill.New().NilChance(.5).NumElements(0, 1).RandSource(rand.NewSource(1))
for i := 0; i < 100; i++ { for i := 0; i < 100; i++ {
m := &metav1.ObjectMeta{} m := &metav1.ObjectMeta{}
f.Fuzz(m) f.Fill(m)
partial := AsPartialObjectMetadata(m) partial := AsPartialObjectMetadata(m)
if !reflect.DeepEqual(&partial.ObjectMeta, m) { if !reflect.DeepEqual(&partial.ObjectMeta, m) {
t.Fatalf("incomplete partial object metadata: %s", cmp.Diff(&partial.ObjectMeta, m)) t.Fatalf("incomplete partial object metadata: %s", cmp.Diff(&partial.ObjectMeta, m))
@ -42,7 +42,7 @@ func TestAsPartialObjectMetadata(t *testing.T) {
for i := 0; i < 100; i++ { for i := 0; i < 100; i++ {
m := &metav1beta1.PartialObjectMetadata{} m := &metav1beta1.PartialObjectMetadata{}
f.Fuzz(&m.ObjectMeta) f.Fill(&m.ObjectMeta)
partial := AsPartialObjectMetadata(m) partial := AsPartialObjectMetadata(m)
if !reflect.DeepEqual(&partial.ObjectMeta, &m.ObjectMeta) { if !reflect.DeepEqual(&partial.ObjectMeta, &m.ObjectMeta) {
t.Fatalf("incomplete partial object metadata: %s", cmp.Diff(&partial.ObjectMeta, &m.ObjectMeta)) t.Fatalf("incomplete partial object metadata: %s", cmp.Diff(&partial.ObjectMeta, &m.ObjectMeta))

View File

@ -28,9 +28,9 @@ import (
"unicode" "unicode"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
fuzz "github.com/google/gofuzz"
"github.com/spf13/pflag" "github.com/spf13/pflag"
inf "gopkg.in/inf.v0" inf "gopkg.in/inf.v0"
"sigs.k8s.io/randfill"
cbor "k8s.io/apimachinery/pkg/runtime/serializer/cbor/direct" cbor "k8s.io/apimachinery/pkg/runtime/serializer/cbor/direct"
) )
@ -827,12 +827,12 @@ func TestQuantityParseEmit(t *testing.T) {
} }
} }
var fuzzer = fuzz.New().Funcs( var fuzzer = randfill.New().Funcs(
func(q *Quantity, c fuzz.Continue) { func(q *Quantity, c randfill.Continue) {
q.i = Zero q.i = Zero
if c.RandBool() { if c.Bool() {
q.Format = BinarySI q.Format = BinarySI
if c.RandBool() { if c.Bool() {
dec := &inf.Dec{} dec := &inf.Dec{}
q.d = infDecAmount{Dec: dec} q.d = infDecAmount{Dec: dec}
dec.SetScale(0) dec.SetScale(0)
@ -846,12 +846,12 @@ var fuzzer = fuzz.New().Funcs(
dec.SetUnscaled(c.Int63n(1024) << uint(10*c.Intn(5))) dec.SetUnscaled(c.Int63n(1024) << uint(10*c.Intn(5)))
return return
} }
if c.RandBool() { if c.Bool() {
q.Format = DecimalSI q.Format = DecimalSI
} else { } else {
q.Format = DecimalExponent q.Format = DecimalExponent
} }
if c.RandBool() { if c.Bool() {
dec := &inf.Dec{} dec := &inf.Dec{}
q.d = infDecAmount{Dec: dec} q.d = infDecAmount{Dec: dec}
dec.SetScale(inf.Scale(c.Intn(4))) dec.SetScale(inf.Scale(c.Intn(4)))
@ -897,7 +897,7 @@ func TestQuantityDeepCopy(t *testing.T) {
func TestJSON(t *testing.T) { func TestJSON(t *testing.T) {
for i := 0; i < 500; i++ { for i := 0; i < 500; i++ {
q := &Quantity{} q := &Quantity{}
fuzzer.Fuzz(q) fuzzer.Fill(q)
b, err := json.Marshal(q) b, err := json.Marshal(q)
if err != nil { if err != nil {
t.Errorf("error encoding %v: %v", q, err) t.Errorf("error encoding %v: %v", q, err)
@ -1801,7 +1801,7 @@ func TestQuantityUnmarshalCBOR(t *testing.T) {
func TestQuantityRoundtripCBOR(t *testing.T) { func TestQuantityRoundtripCBOR(t *testing.T) {
for i := 0; i < 500; i++ { for i := 0; i < 500; i++ {
var initial, final Quantity var initial, final Quantity
fuzzer.Fuzz(&initial) fuzzer.Fill(&initial)
b, err := cbor.Marshal(initial) b, err := cbor.Marshal(initial)
if err != nil { if err != nil {
t.Errorf("error encoding %v: %v", initial, err) t.Errorf("error encoding %v: %v", initial, err)

View File

@ -23,7 +23,7 @@ import (
"strconv" "strconv"
"strings" "strings"
fuzz "github.com/google/gofuzz" "sigs.k8s.io/randfill"
apitesting "k8s.io/apimachinery/pkg/api/apitesting" apitesting "k8s.io/apimachinery/pkg/api/apitesting"
"k8s.io/apimachinery/pkg/api/apitesting/fuzzer" "k8s.io/apimachinery/pkg/api/apitesting/fuzzer"
@ -38,29 +38,29 @@ import (
func genericFuzzerFuncs(codecs runtimeserializer.CodecFactory) []interface{} { func genericFuzzerFuncs(codecs runtimeserializer.CodecFactory) []interface{} {
return []interface{}{ return []interface{}{
func(q *resource.Quantity, c fuzz.Continue) { func(q *resource.Quantity, c randfill.Continue) {
*q = *resource.NewQuantity(c.Int63n(1000), resource.DecimalExponent) *q = *resource.NewQuantity(c.Int63n(1000), resource.DecimalExponent)
}, },
func(j *int, c fuzz.Continue) { func(j *int, c randfill.Continue) {
*j = int(c.Int31()) *j = int(c.Int31())
}, },
func(j **int, c fuzz.Continue) { func(j **int, c randfill.Continue) {
if c.RandBool() { if c.Bool() {
i := int(c.Int31()) i := int(c.Int31())
*j = &i *j = &i
} else { } else {
*j = nil *j = nil
} }
}, },
func(j *runtime.TypeMeta, c fuzz.Continue) { func(j *runtime.TypeMeta, c randfill.Continue) {
// We have to customize the randomization of TypeMetas because their // We have to customize the randomization of TypeMetas because their
// APIVersion and Kind must remain blank in memory. // APIVersion and Kind must remain blank in memory.
j.APIVersion = "" j.APIVersion = ""
j.Kind = "" j.Kind = ""
}, },
func(j *runtime.Object, c fuzz.Continue) { func(j *runtime.Object, c randfill.Continue) {
// TODO: uncomment when round trip starts from a versioned object // TODO: uncomment when round trip starts from a versioned object
if true { //c.RandBool() { if true { // c.Bool() {
*j = &runtime.Unknown{ *j = &runtime.Unknown{
// We do not set TypeMeta here because it is not carried through a round trip // We do not set TypeMeta here because it is not carried through a round trip
Raw: []byte(`{"apiVersion":"unknown.group/unknown","kind":"Something","someKey":"someValue"}`), Raw: []byte(`{"apiVersion":"unknown.group/unknown","kind":"Something","someKey":"someValue"}`),
@ -69,15 +69,15 @@ func genericFuzzerFuncs(codecs runtimeserializer.CodecFactory) []interface{} {
} else { } else {
types := []runtime.Object{&metav1.Status{}, &metav1.APIGroup{}} types := []runtime.Object{&metav1.Status{}, &metav1.APIGroup{}}
t := types[c.Rand.Intn(len(types))] t := types[c.Rand.Intn(len(types))]
c.Fuzz(t) c.Fill(t)
*j = t *j = t
} }
}, },
func(r *runtime.RawExtension, c fuzz.Continue) { func(r *runtime.RawExtension, c randfill.Continue) {
// Pick an arbitrary type and fuzz it // Pick an arbitrary type and fuzz it
types := []runtime.Object{&metav1.Status{}, &metav1.APIGroup{}} types := []runtime.Object{&metav1.Status{}, &metav1.APIGroup{}}
obj := types[c.Rand.Intn(len(types))] obj := types[c.Rand.Intn(len(types))]
c.Fuzz(obj) c.Fill(obj)
// Find a codec for converting the object to raw bytes. This is necessary for the // 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. // api version and kind to be correctly set be serialization.
@ -100,7 +100,7 @@ func genericFuzzerFuncs(codecs runtimeserializer.CodecFactory) []interface{} {
} }
} }
// taken from gofuzz internals for RandString // taken from randfill (nee gofuzz) internals for RandString
type charRange struct { type charRange struct {
first, last rune first, last rune
} }
@ -114,7 +114,7 @@ func (c *charRange) choose(r *rand.Rand) rune {
// randomLabelPart produces a valid random label value or name-part // randomLabelPart produces a valid random label value or name-part
// of a label key. // of a label key.
func randomLabelPart(c fuzz.Continue, canBeEmpty bool) string { func randomLabelPart(c randfill.Continue, canBeEmpty bool) string {
validStartEnd := []charRange{{'0', '9'}, {'a', 'z'}, {'A', 'Z'}} validStartEnd := []charRange{{'0', '9'}, {'a', 'z'}, {'A', 'Z'}}
validMiddle := []charRange{{'0', '9'}, {'a', 'z'}, {'A', 'Z'}, validMiddle := []charRange{{'0', '9'}, {'a', 'z'}, {'A', 'Z'},
{'.', '.'}, {'-', '-'}, {'_', '_'}} {'.', '.'}, {'-', '-'}, {'_', '_'}}
@ -138,7 +138,7 @@ func randomLabelPart(c fuzz.Continue, canBeEmpty bool) string {
return string(runes) return string(runes)
} }
func randomDNSLabel(c fuzz.Continue) string { func randomDNSLabel(c randfill.Continue) string {
validStartEnd := []charRange{{'0', '9'}, {'a', 'z'}} validStartEnd := []charRange{{'0', '9'}, {'a', 'z'}}
validMiddle := []charRange{{'0', '9'}, {'a', 'z'}, {'-', '-'}} validMiddle := []charRange{{'0', '9'}, {'a', 'z'}, {'-', '-'}}
@ -154,11 +154,11 @@ func randomDNSLabel(c fuzz.Continue) string {
return string(runes) return string(runes)
} }
func randomLabelKey(c fuzz.Continue) string { func randomLabelKey(c randfill.Continue) string {
namePart := randomLabelPart(c, false) namePart := randomLabelPart(c, false)
prefixPart := "" prefixPart := ""
usePrefix := c.RandBool() usePrefix := c.Bool()
if usePrefix { if usePrefix {
// we can fit, with dots, at most 3 labels in the 253 allotted characters // we can fit, with dots, at most 3 labels in the 253 allotted characters
prefixPartsLen := c.Rand.Intn(2) + 1 prefixPartsLen := c.Rand.Intn(2) + 1
@ -175,28 +175,28 @@ func randomLabelKey(c fuzz.Continue) string {
func v1FuzzerFuncs(codecs runtimeserializer.CodecFactory) []interface{} { func v1FuzzerFuncs(codecs runtimeserializer.CodecFactory) []interface{} {
return []interface{}{ return []interface{}{
func(j *metav1.TypeMeta, c fuzz.Continue) { func(j *metav1.TypeMeta, c randfill.Continue) {
// We have to customize the randomization of TypeMetas because their // We have to customize the randomization of TypeMetas because their
// APIVersion and Kind must remain blank in memory. // APIVersion and Kind must remain blank in memory.
j.APIVersion = "" j.APIVersion = ""
j.Kind = "" j.Kind = ""
}, },
func(j *metav1.ObjectMeta, c fuzz.Continue) { func(j *metav1.ObjectMeta, c randfill.Continue) {
c.FuzzNoCustom(j) c.FillNoCustom(j)
j.ResourceVersion = strconv.FormatUint(c.RandUint64(), 10) j.ResourceVersion = strconv.FormatUint(c.Uint64(), 10)
j.UID = types.UID(c.RandString()) j.UID = types.UID(c.String(0))
// Fuzzing sec and nsec in a smaller range (uint32 instead of int64), // Fuzzing sec and nsec in a smaller range (uint32 instead of int64),
// so that the result Unix time is a valid date and can be parsed into RFC3339 format. // so that the result Unix time is a valid date and can be parsed into RFC3339 format.
var sec, nsec uint32 var sec, nsec uint32
c.Fuzz(&sec) c.Fill(&sec)
c.Fuzz(&nsec) c.Fill(&nsec)
j.CreationTimestamp = metav1.Unix(int64(sec), int64(nsec)).Rfc3339Copy() j.CreationTimestamp = metav1.Unix(int64(sec), int64(nsec)).Rfc3339Copy()
if j.DeletionTimestamp != nil { if j.DeletionTimestamp != nil {
c.Fuzz(&sec) c.Fill(&sec)
c.Fuzz(&nsec) c.Fill(&nsec)
t := metav1.Unix(int64(sec), int64(nsec)).Rfc3339Copy() t := metav1.Unix(int64(sec), int64(nsec)).Rfc3339Copy()
j.DeletionTimestamp = &t j.DeletionTimestamp = &t
} }
@ -218,16 +218,16 @@ func v1FuzzerFuncs(codecs runtimeserializer.CodecFactory) []interface{} {
j.Finalizers = nil j.Finalizers = nil
} }
}, },
func(j *metav1.ResourceVersionMatch, c fuzz.Continue) { func(j *metav1.ResourceVersionMatch, c randfill.Continue) {
matches := []metav1.ResourceVersionMatch{"", metav1.ResourceVersionMatchExact, metav1.ResourceVersionMatchNotOlderThan} matches := []metav1.ResourceVersionMatch{"", metav1.ResourceVersionMatchExact, metav1.ResourceVersionMatchNotOlderThan}
*j = matches[c.Rand.Intn(len(matches))] *j = matches[c.Rand.Intn(len(matches))]
}, },
func(j *metav1.ListMeta, c fuzz.Continue) { func(j *metav1.ListMeta, c randfill.Continue) {
j.ResourceVersion = strconv.FormatUint(c.RandUint64(), 10) j.ResourceVersion = strconv.FormatUint(c.Uint64(), 10)
j.SelfLink = c.RandString() j.SelfLink = c.String(0) //nolint:staticcheck // SA1019 backwards compatibility
}, },
func(j *metav1.LabelSelector, c fuzz.Continue) { func(j *metav1.LabelSelector, c randfill.Continue) {
c.FuzzNoCustom(j) c.FillNoCustom(j)
// we can't have an entirely empty selector, so force // we can't have an entirely empty selector, so force
// use of MatchExpression if necessary // use of MatchExpression if necessary
if len(j.MatchLabels) == 0 && len(j.MatchExpressions) == 0 { if len(j.MatchLabels) == 0 && len(j.MatchExpressions) == 0 {
@ -257,7 +257,7 @@ func v1FuzzerFuncs(codecs runtimeserializer.CodecFactory) []interface{} {
for i := range j.MatchExpressions { for i := range j.MatchExpressions {
req := metav1.LabelSelectorRequirement{} req := metav1.LabelSelectorRequirement{}
c.Fuzz(&req) c.Fill(&req)
req.Key = randomLabelKey(c) req.Key = randomLabelKey(c)
req.Operator = validOperators[c.Rand.Intn(len(validOperators))] req.Operator = validOperators[c.Rand.Intn(len(validOperators))]
if req.Operator == metav1.LabelSelectorOpIn || req.Operator == metav1.LabelSelectorOpNotIn { if req.Operator == metav1.LabelSelectorOpIn || req.Operator == metav1.LabelSelectorOpNotIn {
@ -278,8 +278,8 @@ func v1FuzzerFuncs(codecs runtimeserializer.CodecFactory) []interface{} {
sort.Slice(j.MatchExpressions, func(a, b int) bool { return j.MatchExpressions[a].Key < j.MatchExpressions[b].Key }) sort.Slice(j.MatchExpressions, func(a, b int) bool { return j.MatchExpressions[a].Key < j.MatchExpressions[b].Key })
} }
}, },
func(j *metav1.ManagedFieldsEntry, c fuzz.Continue) { func(j *metav1.ManagedFieldsEntry, c randfill.Continue) {
c.FuzzNoCustom(j) c.FillNoCustom(j)
j.FieldsV1 = nil j.FieldsV1 = nil
}, },
} }
@ -287,15 +287,15 @@ func v1FuzzerFuncs(codecs runtimeserializer.CodecFactory) []interface{} {
func v1beta1FuzzerFuncs(codecs runtimeserializer.CodecFactory) []interface{} { func v1beta1FuzzerFuncs(codecs runtimeserializer.CodecFactory) []interface{} {
return []interface{}{ return []interface{}{
func(r *metav1beta1.TableOptions, c fuzz.Continue) { func(r *metav1beta1.TableOptions, c randfill.Continue) {
c.FuzzNoCustom(r) c.FillNoCustom(r)
// NoHeaders is not serialized to the wire but is allowed within the versioned // NoHeaders is not serialized to the wire but is allowed within the versioned
// type because we don't use meta internal types in the client and API server. // type because we don't use meta internal types in the client and API server.
r.NoHeaders = false r.NoHeaders = false
}, },
func(r *metav1beta1.TableRow, c fuzz.Continue) { func(r *metav1beta1.TableRow, c randfill.Continue) {
c.Fuzz(&r.Object) c.Fill(&r.Object)
c.Fuzz(&r.Conditions) c.Fill(&r.Conditions)
if len(r.Conditions) == 0 { if len(r.Conditions) == 0 {
r.Conditions = nil r.Conditions = nil
} }
@ -307,15 +307,15 @@ func v1beta1FuzzerFuncs(codecs runtimeserializer.CodecFactory) []interface{} {
t := c.Intn(6) t := c.Intn(6)
switch t { switch t {
case 0: case 0:
r.Cells[i] = c.RandString() r.Cells[i] = c.String(0)
case 1: case 1:
r.Cells[i] = c.Int63() r.Cells[i] = c.Int63()
case 2: case 2:
r.Cells[i] = c.RandBool() r.Cells[i] = c.Bool()
case 3: case 3:
x := map[string]interface{}{} x := map[string]interface{}{}
for j := c.Intn(10) + 1; j >= 0; j-- { for j := c.Intn(10) + 1; j >= 0; j-- {
x[c.RandString()] = c.RandString() x[c.String(0)] = c.String(0)
} }
r.Cells[i] = x r.Cells[i] = x
case 4: case 4:

View File

@ -23,9 +23,9 @@ import (
"testing" "testing"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
fuzz "github.com/google/gofuzz"
"k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/randfill"
) )
func TestLabelSelectorAsSelector(t *testing.T) { func TestLabelSelectorAsSelector(t *testing.T) {
@ -188,8 +188,8 @@ func TestResetObjectMetaForStatus(t *testing.T) {
existingMeta := &ObjectMeta{} existingMeta := &ObjectMeta{}
// fuzz the existingMeta to set every field, no nils // fuzz the existingMeta to set every field, no nils
f := fuzz.New().NilChance(0).NumElements(1, 1).MaxDepth(10) f := randfill.New().NilChance(0).NumElements(1, 1).MaxDepth(10)
f.Fuzz(existingMeta) f.Fill(existingMeta)
ResetObjectMetaForStatus(meta, existingMeta) ResetObjectMetaForStatus(meta, existingMeta)
// not all fields are stomped during the reset. These fields should not have been set. False // not all fields are stomped during the reset. These fields should not have been set. False

View File

@ -20,21 +20,22 @@ limitations under the License.
package v1 package v1
import ( import (
"math/rand"
"time" "time"
fuzz "github.com/google/gofuzz" "sigs.k8s.io/randfill"
) )
// Fuzz satisfies fuzz.Interface. // Fuzz satisfies randfill.SimpleSelfFiller.
func (t *MicroTime) Fuzz(c fuzz.Continue) { func (t *MicroTime) RandFill(r *rand.Rand) {
if t == nil { if t == nil {
return return
} }
// Allow for about 1000 years of randomness. Accurate to a tenth of // Allow for about 1000 years of randomness. Accurate to a tenth of
// micro second. Leave off nanoseconds because JSON doesn't // micro second. Leave off nanoseconds because JSON doesn't
// represent them so they can't round-trip properly. // represent them so they can't round-trip properly.
t.Time = time.Unix(c.Rand.Int63n(1000*365*24*60*60), 1000*c.Rand.Int63n(1000000)) t.Time = time.Unix(r.Int63n(1000*365*24*60*60), 1000*r.Int63n(1000000))
} }
// ensure MicroTime implements fuzz.Interface // ensure MicroTime implements randfill.Interface
var _ fuzz.Interface = &MicroTime{} var _ randfill.SimpleSelfFiller = &MicroTime{}

View File

@ -27,7 +27,7 @@ import (
"sigs.k8s.io/yaml" "sigs.k8s.io/yaml"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
fuzz "github.com/google/gofuzz" "sigs.k8s.io/randfill"
) )
type MicroTimeHolder struct { type MicroTimeHolder struct {
@ -378,10 +378,10 @@ func TestMicroTimeProtoUnmarshalRaw(t *testing.T) {
} }
func TestMicroTimeRoundtripCBOR(t *testing.T) { func TestMicroTimeRoundtripCBOR(t *testing.T) {
fuzzer := fuzz.New() fuzzer := randfill.New()
for i := 0; i < 500; i++ { for i := 0; i < 500; i++ {
var initial, final MicroTime var initial, final MicroTime
fuzzer.Fuzz(&initial) fuzzer.Fill(&initial)
b, err := cbor.Marshal(initial) b, err := cbor.Marshal(initial)
if err != nil { if err != nil {
t.Errorf("error encoding %v: %v", initial, err) t.Errorf("error encoding %v: %v", initial, err)

View File

@ -22,15 +22,15 @@ import (
"reflect" "reflect"
"testing" "testing"
fuzz "github.com/google/gofuzz" "sigs.k8s.io/randfill"
) )
func TestPatchOptionsIsSuperSetOfUpdateOptions(t *testing.T) { func TestPatchOptionsIsSuperSetOfUpdateOptions(t *testing.T) {
f := fuzz.New() f := randfill.New()
for i := 0; i < 1000; i++ { for i := 0; i < 1000; i++ {
t.Run(fmt.Sprintf("Run %d/1000", i), func(t *testing.T) { t.Run(fmt.Sprintf("Run %d/1000", i), func(t *testing.T) {
update := UpdateOptions{} update := UpdateOptions{}
f.Fuzz(&update) f.Fill(&update)
b, err := json.Marshal(update) b, err := json.Marshal(update)
if err != nil { if err != nil {

View File

@ -20,21 +20,22 @@ limitations under the License.
package v1 package v1
import ( import (
"math/rand"
"time" "time"
fuzz "github.com/google/gofuzz" "sigs.k8s.io/randfill"
) )
// Fuzz satisfies fuzz.Interface. // Fuzz satisfies randfill.SimpleSelfFiller.
func (t *Time) Fuzz(c fuzz.Continue) { func (t *Time) RandFill(r *rand.Rand) {
if t == nil { if t == nil {
return return
} }
// Allow for about 1000 years of randomness. Leave off nanoseconds // Allow for about 1000 years of randomness. Leave off nanoseconds
// because JSON doesn't represent them so they can't round-trip // because JSON doesn't represent them so they can't round-trip
// properly. // properly.
t.Time = time.Unix(c.Rand.Int63n(1000*365*24*60*60), 0) t.Time = time.Unix(r.Int63n(1000*365*24*60*60), 0)
} }
// ensure Time implements fuzz.Interface // ensure Time implements randfill.SimpleSelfFiller
var _ fuzz.Interface = &Time{} var _ randfill.SimpleSelfFiller = &Time{}

View File

@ -27,7 +27,7 @@ import (
"sigs.k8s.io/yaml" "sigs.k8s.io/yaml"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
fuzz "github.com/google/gofuzz" "sigs.k8s.io/randfill"
) )
type TimeHolder struct { type TimeHolder struct {
@ -303,10 +303,10 @@ func TestTimeIsZero(t *testing.T) {
} }
func TestTimeRoundtripCBOR(t *testing.T) { func TestTimeRoundtripCBOR(t *testing.T) {
fuzzer := fuzz.New() fuzzer := randfill.New()
for i := 0; i < 500; i++ { for i := 0; i < 500; i++ {
var initial, final Time var initial, final Time
fuzzer.Fuzz(&initial) fuzzer.Fill(&initial)
b, err := cbor.Marshal(initial) b, err := cbor.Marshal(initial)
if err != nil { if err != nil {
t.Errorf("error encoding %v: %v", initial, err) t.Errorf("error encoding %v: %v", initial, err)

View File

@ -28,8 +28,8 @@ import (
"time" "time"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
fuzz "github.com/google/gofuzz"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"sigs.k8s.io/randfill"
"k8s.io/apimachinery/pkg/api/apitesting/fuzzer" "k8s.io/apimachinery/pkg/api/apitesting/fuzzer"
"k8s.io/apimachinery/pkg/api/equality" "k8s.io/apimachinery/pkg/api/equality"
@ -67,7 +67,7 @@ func TestUnstructuredMetadataRoundTrip(t *testing.T) {
u := &unstructured.Unstructured{Object: map[string]interface{}{}} u := &unstructured.Unstructured{Object: map[string]interface{}{}}
uCopy := u.DeepCopy() uCopy := u.DeepCopy()
metadata := &metav1.ObjectMeta{} metadata := &metav1.ObjectMeta{}
fuzzer.Fuzz(metadata) fuzzer.Fill(metadata)
if err := setObjectMeta(u, metadata); err != nil { if err := setObjectMeta(u, metadata); err != nil {
t.Fatalf("unexpected error setting fuzzed ObjectMeta: %v", err) t.Fatalf("unexpected error setting fuzzed ObjectMeta: %v", err)
@ -94,7 +94,7 @@ func TestUnstructuredMetadataOmitempty(t *testing.T) {
// fuzz to make sure we don't miss any function calls below // fuzz to make sure we don't miss any function calls below
u := &unstructured.Unstructured{Object: map[string]interface{}{}} u := &unstructured.Unstructured{Object: map[string]interface{}{}}
metadata := &metav1.ObjectMeta{} metadata := &metav1.ObjectMeta{}
fuzzer.Fuzz(metadata) fuzzer.Fill(metadata)
if err := setObjectMeta(u, metadata); err != nil { if err := setObjectMeta(u, metadata); err != nil {
t.Fatalf("unexpected error setting fuzzed ObjectMeta: %v", err) t.Fatalf("unexpected error setting fuzzed ObjectMeta: %v", err)
} }
@ -184,7 +184,7 @@ func roundtripType[U runtime.Unstructured](t *testing.T) {
for i := 0; i < 50; i++ { for i := 0; i < 50; i++ {
original := reflect.New(reflect.TypeFor[U]().Elem()).Interface().(runtime.Unstructured) original := reflect.New(reflect.TypeFor[U]().Elem()).Interface().(runtime.Unstructured)
fuzzer.Fuzz(original) fuzzer.Fill(original)
// unstructured -> JSON > unstructured > CBOR -> unstructured -> JSON -> unstructured // unstructured -> JSON > unstructured > CBOR -> unstructured -> JSON -> unstructured
roundtrip(t, original, jS, cS) roundtrip(t, original, jS, cS)
// unstructured -> CBOR > unstructured > JSON -> unstructured -> CBOR -> unstructured // unstructured -> CBOR > unstructured > JSON -> unstructured -> CBOR -> unstructured
@ -285,25 +285,25 @@ const (
func unstructuredFuzzerFuncs(codecs serializer.CodecFactory) []interface{} { func unstructuredFuzzerFuncs(codecs serializer.CodecFactory) []interface{} {
return []interface{}{ return []interface{}{
func(u *unstructured.Unstructured, c fuzz.Continue) { func(u *unstructured.Unstructured, c randfill.Continue) {
obj := make(map[string]interface{}) obj := make(map[string]interface{})
obj["apiVersion"] = generateValidAPIVersionString(c) obj["apiVersion"] = generateValidAPIVersionString(c)
obj["kind"] = generateNonEmptyString(c) obj["kind"] = generateNonEmptyString(c)
for j := c.Intn(maxUnstructuredFanOut); j >= 0; j-- { for j := c.Intn(maxUnstructuredFanOut); j >= 0; j-- {
obj[c.RandString()] = generateRandomTypeValue(maxUnstructuredDepth, c) obj[c.String(0)] = generateRandomTypeValue(maxUnstructuredDepth, c)
} }
u.Object = obj u.Object = obj
}, },
func(ul *unstructured.UnstructuredList, c fuzz.Continue) { func(ul *unstructured.UnstructuredList, c randfill.Continue) {
obj := make(map[string]interface{}) obj := make(map[string]interface{})
obj["apiVersion"] = generateValidAPIVersionString(c) obj["apiVersion"] = generateValidAPIVersionString(c)
obj["kind"] = generateNonEmptyString(c) obj["kind"] = generateNonEmptyString(c)
for j := c.Intn(maxUnstructuredFanOut); j >= 0; j-- { for j := c.Intn(maxUnstructuredFanOut); j >= 0; j-- {
obj[c.RandString()] = generateRandomTypeValue(maxUnstructuredDepth, c) obj[c.String(0)] = generateRandomTypeValue(maxUnstructuredDepth, c)
} }
for j := c.Intn(maxUnstructuredFanOut); j >= 0; j-- { for j := c.Intn(maxUnstructuredFanOut); j >= 0; j-- {
var item = unstructured.Unstructured{} var item = unstructured.Unstructured{}
c.Fuzz(&item) c.Fill(&item)
ul.Items = append(ul.Items, item) ul.Items = append(ul.Items, item)
} }
ul.Object = obj ul.Object = obj
@ -311,16 +311,16 @@ func unstructuredFuzzerFuncs(codecs serializer.CodecFactory) []interface{} {
} }
} }
func generateNonEmptyString(c fuzz.Continue) string { func generateNonEmptyString(c randfill.Continue) string {
temp := c.RandString() temp := c.String(0)
for len(temp) == 0 { for len(temp) == 0 {
temp = c.RandString() temp = c.String(0)
} }
return temp return temp
} }
// generateNonEmptyNoSlashString generates a non-empty string without any slashes // generateNonEmptyNoSlashString generates a non-empty string without any slashes
func generateNonEmptyNoSlashString(c fuzz.Continue) string { func generateNonEmptyNoSlashString(c randfill.Continue) string {
temp := strings.ReplaceAll(generateNonEmptyString(c), "/", "") temp := strings.ReplaceAll(generateNonEmptyString(c), "/", "")
for len(temp) == 0 { for len(temp) == 0 {
temp = strings.ReplaceAll(generateNonEmptyString(c), "/", "") temp = strings.ReplaceAll(generateNonEmptyString(c), "/", "")
@ -330,8 +330,8 @@ func generateNonEmptyNoSlashString(c fuzz.Continue) string {
// generateValidAPIVersionString generates valid apiVersion string with formats: // generateValidAPIVersionString generates valid apiVersion string with formats:
// <string>/<string> or <string> // <string>/<string> or <string>
func generateValidAPIVersionString(c fuzz.Continue) string { func generateValidAPIVersionString(c randfill.Continue) string {
if c.RandBool() { if c.Bool() {
return generateNonEmptyNoSlashString(c) + "/" + generateNonEmptyNoSlashString(c) return generateNonEmptyNoSlashString(c) + "/" + generateNonEmptyNoSlashString(c)
} else { } else {
return generateNonEmptyNoSlashString(c) return generateNonEmptyNoSlashString(c)
@ -355,7 +355,7 @@ func generateValidAPIVersionString(c fuzz.Continue) string {
// All external-versioned builtin types are exercised through RoundtripToUnstructured // All external-versioned builtin types are exercised through RoundtripToUnstructured
// in apitesting package. Types like metav1.Time are implicitly being exercised // in apitesting package. Types like metav1.Time are implicitly being exercised
// because they appear as fields in those types. // because they appear as fields in those types.
func generateRandomTypeValue(depth int, c fuzz.Continue) interface{} { func generateRandomTypeValue(depth int, c randfill.Continue) interface{} {
t := c.Rand.Intn(120) t := c.Rand.Intn(120)
// If the max depth for unstructured is reached, only add non-recursive types // If the max depth for unstructured is reached, only add non-recursive types
// which is 20+ in range // which is 20+ in range
@ -373,21 +373,21 @@ func generateRandomTypeValue(depth int, c fuzz.Continue) interface{} {
case t < 20: case t < 20:
item := map[string]interface{}{} item := map[string]interface{}{}
for j := c.Intn(maxUnstructuredFanOut); j >= 0; j-- { for j := c.Intn(maxUnstructuredFanOut); j >= 0; j-- {
item[c.RandString()] = generateRandomTypeValue(depth-1, c) item[c.String(0)] = generateRandomTypeValue(depth-1, c)
} }
return item return item
case t < 40: case t < 40:
// Only valid UTF-8 encodings // Only valid UTF-8 encodings
var item string var item string
c.Fuzz(&item) c.Fill(&item)
return item return item
case t < 60: case t < 60:
var item int64 var item int64
c.Fuzz(&item) c.Fill(&item)
return item return item
case t < 80: case t < 80:
var item bool var item bool
c.Fuzz(&item) c.Fill(&item)
return item return item
case t < 100: case t < 100:
return c.Rand.NormFloat64() return c.Rand.NormFloat64()

View File

@ -19,12 +19,12 @@ package fuzzer
import ( import (
"fmt" "fmt"
"github.com/google/gofuzz" "sigs.k8s.io/randfill"
apitesting "k8s.io/apimachinery/pkg/api/apitesting" apitesting "k8s.io/apimachinery/pkg/api/apitesting"
"k8s.io/apimachinery/pkg/api/apitesting/fuzzer" "k8s.io/apimachinery/pkg/api/apitesting/fuzzer"
"k8s.io/apimachinery/pkg/apis/testapigroup" "k8s.io/apimachinery/pkg/apis/testapigroup"
"k8s.io/apimachinery/pkg/apis/testapigroup/v1" v1 "k8s.io/apimachinery/pkg/apis/testapigroup/v1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer"
) )
@ -33,9 +33,9 @@ import (
// values in a Kubernetes context. // values in a Kubernetes context.
func overrideMetaFuncs(codecs runtimeserializer.CodecFactory) []interface{} { func overrideMetaFuncs(codecs runtimeserializer.CodecFactory) []interface{} {
return []interface{}{ return []interface{}{
func(j *runtime.Object, c fuzz.Continue) { func(j *runtime.Object, c randfill.Continue) {
// TODO: uncomment when round trip starts from a versioned object // TODO: uncomment when round trip starts from a versioned object
if true { //c.RandBool() { if true { // c.Bool() {
*j = &runtime.Unknown{ *j = &runtime.Unknown{
// We do not set TypeMeta here because it is not carried through a round trip // We do not set TypeMeta here because it is not carried through a round trip
Raw: []byte(`{"apiVersion":"unknown.group/unknown","kind":"Something","someKey":"someValue"}`), Raw: []byte(`{"apiVersion":"unknown.group/unknown","kind":"Something","someKey":"someValue"}`),
@ -44,15 +44,15 @@ func overrideMetaFuncs(codecs runtimeserializer.CodecFactory) []interface{} {
} else { } else {
types := []runtime.Object{&testapigroup.Carp{}} types := []runtime.Object{&testapigroup.Carp{}}
t := types[c.Rand.Intn(len(types))] t := types[c.Rand.Intn(len(types))]
c.Fuzz(t) c.Fill(t)
*j = t *j = t
} }
}, },
func(r *runtime.RawExtension, c fuzz.Continue) { func(r *runtime.RawExtension, c randfill.Continue) {
// Pick an arbitrary type and fuzz it // Pick an arbitrary type and fuzz it
types := []runtime.Object{&testapigroup.Carp{}} types := []runtime.Object{&testapigroup.Carp{}}
obj := types[c.Rand.Intn(len(types))] obj := types[c.Rand.Intn(len(types))]
c.Fuzz(obj) c.Fill(obj)
// Convert the object to raw bytes // Convert the object to raw bytes
bytes, err := runtime.Encode(apitesting.TestCodec(codecs, v1.SchemeGroupVersion), obj) bytes, err := runtime.Encode(apitesting.TestCodec(codecs, v1.SchemeGroupVersion), obj)
@ -68,11 +68,11 @@ func overrideMetaFuncs(codecs runtimeserializer.CodecFactory) []interface{} {
func testapigroupFuncs(codecs runtimeserializer.CodecFactory) []interface{} { func testapigroupFuncs(codecs runtimeserializer.CodecFactory) []interface{} {
return []interface{}{ return []interface{}{
func(s *testapigroup.CarpSpec, c fuzz.Continue) { func(s *testapigroup.CarpSpec, c randfill.Continue) {
c.FuzzNoCustom(s) c.FillNoCustom(s)
// has a default value // has a default value
ttl := int64(30) ttl := int64(30)
if c.RandBool() { if c.Bool() {
ttl = int64(c.Uint32()) ttl = int64(c.Uint32())
} }
s.TerminationGracePeriodSeconds = &ttl s.TerminationGracePeriodSeconds = &ttl
@ -81,11 +81,11 @@ func testapigroupFuncs(codecs runtimeserializer.CodecFactory) []interface{} {
s.SchedulerName = "default-scheduler" s.SchedulerName = "default-scheduler"
} }
}, },
func(j *testapigroup.CarpPhase, c fuzz.Continue) { func(j *testapigroup.CarpPhase, c randfill.Continue) {
statuses := []testapigroup.CarpPhase{"Pending", "Running", "Succeeded", "Failed", "Unknown"} statuses := []testapigroup.CarpPhase{"Pending", "Running", "Succeeded", "Failed", "Unknown"}
*j = statuses[c.Rand.Intn(len(statuses))] *j = statuses[c.Rand.Intn(len(statuses))]
}, },
func(rp *testapigroup.RestartPolicy, c fuzz.Continue) { func(rp *testapigroup.RestartPolicy, c randfill.Continue) {
policies := []testapigroup.RestartPolicy{"Always", "Never", "OnFailure"} policies := []testapigroup.RestartPolicy{"Always", "Never", "OnFailure"}
*rp = policies[c.Rand.Intn(len(policies))] *rp = policies[c.Rand.Intn(len(policies))]
}, },

View File

@ -36,9 +36,9 @@ import (
"k8s.io/apimachinery/pkg/util/json" "k8s.io/apimachinery/pkg/util/json"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
fuzz "github.com/google/gofuzz"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"sigs.k8s.io/randfill"
) )
var simpleEquality = conversion.EqualitiesOrDie( var simpleEquality = conversion.EqualitiesOrDie(
@ -640,9 +640,9 @@ func TestUnknownFields(t *testing.T) {
// with the various validation directives (Ignore, Warn, Strict) // with the various validation directives (Ignore, Warn, Strict)
func BenchmarkFromUnstructuredWithValidation(b *testing.B) { func BenchmarkFromUnstructuredWithValidation(b *testing.B) {
re := regexp.MustCompile("^I$") re := regexp.MustCompile("^I$")
f := fuzz.NewWithSeed(1).NilChance(0.1).SkipFieldsWithPattern(re) f := randfill.NewWithSeed(1).NilChance(0.1).SkipFieldsWithPattern(re)
iObj := &I{} iObj := &I{}
f.Fuzz(&iObj) f.Fill(&iObj)
unstr, err := runtime.DefaultUnstructuredConverter.ToUnstructured(iObj) unstr, err := runtime.DefaultUnstructuredConverter.ToUnstructured(iObj)
if err != nil { if err != nil {

View File

@ -34,8 +34,8 @@ import (
utilruntime "k8s.io/apimachinery/pkg/util/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
fuzz "github.com/google/gofuzz"
flag "github.com/spf13/pflag" flag "github.com/spf13/pflag"
"sigs.k8s.io/randfill"
"sigs.k8s.io/yaml" "sigs.k8s.io/yaml"
) )
@ -61,9 +61,9 @@ func (testMetaFactory) Interpret(data []byte) (*schema.GroupVersionKind, error)
} }
// TestObjectFuzzer can randomly populate all the above objects. // TestObjectFuzzer can randomly populate all the above objects.
var TestObjectFuzzer = fuzz.New().NilChance(.5).NumElements(1, 100).Funcs( var TestObjectFuzzer = randfill.New().NilChance(.5).NumElements(1, 100).Funcs(
func(j *runtimetesting.MyWeirdCustomEmbeddedVersionKindField, c fuzz.Continue) { func(j *runtimetesting.MyWeirdCustomEmbeddedVersionKindField, c randfill.Continue) {
c.FuzzNoCustom(j) c.FillNoCustom(j)
j.APIVersion = "" j.APIVersion = ""
j.ObjectKind = "" j.ObjectKind = ""
}, },
@ -106,7 +106,7 @@ var semantic = conversion.EqualitiesOrDie(
func runTest(t *testing.T, source interface{}) { func runTest(t *testing.T, source interface{}) {
name := reflect.TypeOf(source).Elem().Name() name := reflect.TypeOf(source).Elem().Name()
TestObjectFuzzer.Fuzz(source) TestObjectFuzzer.Fill(source)
_, codec := GetTestScheme() _, codec := GetTestScheme()
data, err := runtime.Encode(codec, source.(runtime.Object)) data, err := runtime.Encode(codec, source.(runtime.Object))

View File

@ -22,12 +22,12 @@ import (
"testing" "testing"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
fuzz "github.com/google/gofuzz"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
testapigroupv1 "k8s.io/apimachinery/pkg/apis/testapigroup/v1" testapigroupv1 "k8s.io/apimachinery/pkg/apis/testapigroup/v1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"sigs.k8s.io/randfill"
) )
func TestCollectionsEncoding(t *testing.T) { func TestCollectionsEncoding(t *testing.T) {
@ -720,35 +720,35 @@ func (b *writeCountingBuffer) Reset() {
} }
func TestFuzzCollectionsEncoding(t *testing.T) { func TestFuzzCollectionsEncoding(t *testing.T) {
disableFuzzFieldsV1 := func(field *metav1.FieldsV1, c fuzz.Continue) {} disableFuzzFieldsV1 := func(field *metav1.FieldsV1, c randfill.Continue) {}
fuzzUnstructuredList := func(list *unstructured.UnstructuredList, c fuzz.Continue) { fuzzUnstructuredList := func(list *unstructured.UnstructuredList, c randfill.Continue) {
list.Object = map[string]interface{}{ list.Object = map[string]interface{}{
"kind": "List", "kind": "List",
"apiVersion": "v1", "apiVersion": "v1",
c.RandString(): c.RandString(), c.String(0): c.String(0),
c.RandString(): c.RandUint64(), c.String(0): c.Uint64(),
c.RandString(): c.RandBool(), c.String(0): c.Bool(),
"metadata": map[string]interface{}{ "metadata": map[string]interface{}{
"resourceVersion": fmt.Sprintf("%d", c.RandUint64()), "resourceVersion": fmt.Sprintf("%d", c.Uint64()),
"continue": c.RandString(), "continue": c.String(0),
"remainingItemCount": fmt.Sprintf("%d", c.RandUint64()), "remainingItemCount": fmt.Sprintf("%d", c.Uint64()),
c.RandString(): c.RandString(), c.String(0): c.String(0),
}} }}
c.Fuzz(&list.Items) c.Fill(&list.Items)
} }
fuzzMap := func(kvs map[string]interface{}, c fuzz.Continue) { fuzzMap := func(kvs map[string]interface{}, c randfill.Continue) {
kvs[c.RandString()] = c.RandBool() kvs[c.String(0)] = c.Bool()
kvs[c.RandString()] = c.RandUint64() kvs[c.String(0)] = c.Uint64()
kvs[c.RandString()] = c.RandString() kvs[c.String(0)] = c.String(0)
} }
f := fuzz.New().Funcs(disableFuzzFieldsV1, fuzzUnstructuredList, fuzzMap) f := randfill.New().Funcs(disableFuzzFieldsV1, fuzzUnstructuredList, fuzzMap)
streamingBuffer := &bytes.Buffer{} streamingBuffer := &bytes.Buffer{}
normalSerializer := NewSerializerWithOptions(DefaultMetaFactory, nil, nil, SerializerOptions{StreamingCollectionsEncoding: false}) normalSerializer := NewSerializerWithOptions(DefaultMetaFactory, nil, nil, SerializerOptions{StreamingCollectionsEncoding: false})
normalBuffer := &bytes.Buffer{} normalBuffer := &bytes.Buffer{}
t.Run("CarpList", func(t *testing.T) { t.Run("CarpList", func(t *testing.T) {
for i := 0; i < 1000; i++ { for i := 0; i < 1000; i++ {
list := &testapigroupv1.CarpList{} list := &testapigroupv1.CarpList{}
f.Fuzz(list) f.Fill(list)
streamingBuffer.Reset() streamingBuffer.Reset()
normalBuffer.Reset() normalBuffer.Reset()
ok, err := streamEncodeCollections(list, streamingBuffer) ok, err := streamEncodeCollections(list, streamingBuffer)
@ -771,7 +771,7 @@ func TestFuzzCollectionsEncoding(t *testing.T) {
t.Run("UnstructuredList", func(t *testing.T) { t.Run("UnstructuredList", func(t *testing.T) {
for i := 0; i < 1000; i++ { for i := 0; i < 1000; i++ {
list := &unstructured.UnstructuredList{} list := &unstructured.UnstructuredList{}
f.Fuzz(list) f.Fill(list)
streamingBuffer.Reset() streamingBuffer.Reset()
normalBuffer.Reset() normalBuffer.Reset()
ok, err := streamEncodeCollections(list, streamingBuffer) ok, err := streamEncodeCollections(list, streamingBuffer)

View File

@ -21,7 +21,7 @@ import (
"testing" "testing"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
fuzz "github.com/google/gofuzz" "sigs.k8s.io/randfill"
"k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/api/meta"
metafuzzer "k8s.io/apimachinery/pkg/apis/meta/fuzzer" metafuzzer "k8s.io/apimachinery/pkg/apis/meta/fuzzer"
@ -312,10 +312,10 @@ func TestSetListToMatchingType(t *testing.T) {
func TestSetExtractListRoundTrip(t *testing.T) { func TestSetExtractListRoundTrip(t *testing.T) {
scheme := runtime.NewScheme() scheme := runtime.NewScheme()
codecs := serializer.NewCodecFactory(scheme) codecs := serializer.NewCodecFactory(scheme)
fuzzer := fuzz.New().NilChance(0).NumElements(1, 5).Funcs(metafuzzer.Funcs(codecs)...).MaxDepth(10) fuzzer := randfill.New().NilChance(0).NumElements(1, 5).Funcs(metafuzzer.Funcs(codecs)...).MaxDepth(10)
for i := 0; i < 5; i++ { for i := 0; i < 5; i++ {
start := &testapigroup.CarpList{} start := &testapigroup.CarpList{}
fuzzer.Fuzz(&start.Items) fuzzer.Fill(&start.Items)
list, err := meta.ExtractList(start) list, err := meta.ExtractList(start)
if err != nil { if err != nil {

View File

@ -20,7 +20,6 @@ import (
"reflect" "reflect"
"testing" "testing"
fuzz "github.com/google/gofuzz"
"k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/api/meta"
metafuzzer "k8s.io/apimachinery/pkg/apis/meta/fuzzer" metafuzzer "k8s.io/apimachinery/pkg/apis/meta/fuzzer"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -29,6 +28,7 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer" "k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/randfill"
) )
func TestAPIObjectMeta(t *testing.T) { func TestAPIObjectMeta(t *testing.T) {
@ -306,7 +306,7 @@ type MyAPIObject2 struct {
func getObjectMetaAndOwnerReferences() (myAPIObject2 MyAPIObject2, metaOwnerReferences []metav1.OwnerReference) { func getObjectMetaAndOwnerReferences() (myAPIObject2 MyAPIObject2, metaOwnerReferences []metav1.OwnerReference) {
scheme := runtime.NewScheme() scheme := runtime.NewScheme()
codecs := serializer.NewCodecFactory(scheme) codecs := serializer.NewCodecFactory(scheme)
fuzz.New().NilChance(.5).NumElements(1, 5).Funcs(metafuzzer.Funcs(codecs)...).MaxDepth(10).Fuzz(&myAPIObject2) randfill.New().NilChance(.5).NumElements(1, 5).Funcs(metafuzzer.Funcs(codecs)...).MaxDepth(10).Fill(&myAPIObject2)
references := myAPIObject2.ObjectMeta.OwnerReferences references := myAPIObject2.ObjectMeta.OwnerReferences
// This is necessary for the test to pass because the getter will return a // This is necessary for the test to pass because the getter will return a
// non-nil slice. // non-nil slice.

View File

@ -20,24 +20,24 @@ limitations under the License.
package intstr package intstr
import ( import (
fuzz "github.com/google/gofuzz" "sigs.k8s.io/randfill"
) )
// Fuzz satisfies fuzz.Interface // RandFill satisfies randfill.NativeSelfFiller
func (intstr *IntOrString) Fuzz(c fuzz.Continue) { func (intstr *IntOrString) RandFill(c randfill.Continue) {
if intstr == nil { if intstr == nil {
return return
} }
if c.RandBool() { if c.Bool() {
intstr.Type = Int intstr.Type = Int
c.Fuzz(&intstr.IntVal) c.Fill(&intstr.IntVal)
intstr.StrVal = "" intstr.StrVal = ""
} else { } else {
intstr.Type = String intstr.Type = String
intstr.IntVal = 0 intstr.IntVal = 0
c.Fuzz(&intstr.StrVal) c.Fill(&intstr.StrVal)
} }
} }
// ensure IntOrString implements fuzz.Interface // ensure IntOrString implements fuzz.Interface
var _ fuzz.Interface = &IntOrString{} var _ randfill.NativeSelfFiller = &IntOrString{}

View File

@ -27,7 +27,7 @@ import (
"sigs.k8s.io/yaml" "sigs.k8s.io/yaml"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
fuzz "github.com/google/gofuzz" "sigs.k8s.io/randfill"
) )
func TestFromInt(t *testing.T) { func TestFromInt(t *testing.T) {
@ -544,10 +544,10 @@ func TestUnmarshalCBOR(t *testing.T) {
} }
func TestIntOrStringRoundtripCBOR(t *testing.T) { func TestIntOrStringRoundtripCBOR(t *testing.T) {
fuzzer := fuzz.New() fuzzer := randfill.New()
for i := 0; i < 500; i++ { for i := 0; i < 500; i++ {
var initial, final IntOrString var initial, final IntOrString
fuzzer.Fuzz(&initial) fuzzer.Fill(&initial)
b, err := cbor.Marshal(initial) b, err := cbor.Marshal(initial)
if err != nil { if err != nil {
t.Errorf("error encoding %v: %v", initial, err) t.Errorf("error encoding %v: %v", initial, err)

View File

@ -22,16 +22,16 @@ import (
"testing" "testing"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
fuzz "github.com/google/gofuzz"
v1 "k8s.io/api/admissionregistration/v1" v1 "k8s.io/api/admissionregistration/v1"
"sigs.k8s.io/randfill"
) )
func TestMutatingWebhookAccessor(t *testing.T) { func TestMutatingWebhookAccessor(t *testing.T) {
f := fuzz.New() f := randfill.New()
for i := 0; i < 100; i++ { for i := 0; i < 100; i++ {
t.Run(fmt.Sprintf("Run %d/100", i), func(t *testing.T) { t.Run(fmt.Sprintf("Run %d/100", i), func(t *testing.T) {
orig := &v1.MutatingWebhook{} orig := &v1.MutatingWebhook{}
f.Fuzz(orig) f.Fill(orig)
// zero out any accessor type specific fields not included in the accessor // zero out any accessor type specific fields not included in the accessor
orig.ReinvocationPolicy = nil orig.ReinvocationPolicy = nil
@ -72,11 +72,11 @@ func TestMutatingWebhookAccessor(t *testing.T) {
} }
func TestValidatingWebhookAccessor(t *testing.T) { func TestValidatingWebhookAccessor(t *testing.T) {
f := fuzz.New() f := randfill.New()
for i := 0; i < 100; i++ { for i := 0; i < 100; i++ {
t.Run(fmt.Sprintf("Run %d/100", i), func(t *testing.T) { t.Run(fmt.Sprintf("Run %d/100", i), func(t *testing.T) {
orig := &v1.ValidatingWebhook{} orig := &v1.ValidatingWebhook{}
f.Fuzz(orig) f.Fill(orig)
uid := fmt.Sprintf("test.configuration.admission/%s/0", orig.Name) uid := fmt.Sprintf("test.configuration.admission/%s/0", orig.Name)
accessor := NewValidatingWebhookAccessor(uid, "test.configuration.admission", orig) accessor := NewValidatingWebhookAccessor(uid, "test.configuration.admission", orig)
if uid != accessor.GetUID() { if uid != accessor.GetUID() {

View File

@ -29,8 +29,8 @@ import (
runtime "k8s.io/apimachinery/pkg/runtime" runtime "k8s.io/apimachinery/pkg/runtime"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
fuzz "github.com/google/gofuzz"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"sigs.k8s.io/randfill"
) )
func TestConversionRoundTrip(t *testing.T) { func TestConversionRoundTrip(t *testing.T) {
@ -42,12 +42,12 @@ func TestConversionRoundTrip(t *testing.T) {
err = v2scheme.RegisterConversions(scheme) err = v2scheme.RegisterConversions(scheme)
require.NoError(t, err) require.NoError(t, err)
fuzzer := fuzz.NewWithSeed(2374375) fuzzer := randfill.NewWithSeed(2374375)
// v2 -> v2beta1 -> v2 // v2 -> v2beta1 -> v2
for i := 0; i < 100; i++ { for i := 0; i < 100; i++ {
expected := &v2.APIGroupDiscoveryList{} expected := &v2.APIGroupDiscoveryList{}
fuzzer.Fuzz(expected) fuzzer.Fill(expected)
expected.TypeMeta = metav1.TypeMeta{ expected.TypeMeta = metav1.TypeMeta{
Kind: "APIGroupDiscoveryList", Kind: "APIGroupDiscoveryList",
APIVersion: "apidiscovery.k8s.io/v2", APIVersion: "apidiscovery.k8s.io/v2",
@ -68,7 +68,7 @@ func TestConversionRoundTrip(t *testing.T) {
// v2beta1 -> v2 -> v2beta1 // v2beta1 -> v2 -> v2beta1
for i := 0; i < 100; i++ { for i := 0; i < 100; i++ {
expected := &v2beta1.APIGroupDiscoveryList{} expected := &v2beta1.APIGroupDiscoveryList{}
fuzzer.Fuzz(expected) fuzzer.Fill(expected)
expected.TypeMeta = metav1.TypeMeta{ expected.TypeMeta = metav1.TypeMeta{
Kind: "APIGroupDiscoveryList", Kind: "APIGroupDiscoveryList",
APIVersion: "apidiscovery.k8s.io/v2beta1", APIVersion: "apidiscovery.k8s.io/v2beta1",

View File

@ -19,7 +19,7 @@ package fuzzer
import ( import (
"strings" "strings"
fuzz "github.com/google/gofuzz" "sigs.k8s.io/randfill"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer"
@ -29,9 +29,9 @@ import (
// Funcs returns the fuzzer functions for the audit api group. // Funcs returns the fuzzer functions for the audit api group.
func Funcs(codecs runtimeserializer.CodecFactory) []interface{} { func Funcs(codecs runtimeserializer.CodecFactory) []interface{} {
return []interface{}{ return []interface{}{
func(e *audit.Event, c fuzz.Continue) { func(e *audit.Event, c randfill.Continue) {
c.FuzzNoCustom(e) c.FillNoCustom(e)
switch c.RandBool() { switch c.Bool() {
case true: case true:
e.RequestObject = nil e.RequestObject = nil
case false: case false:
@ -41,7 +41,7 @@ func Funcs(codecs runtimeserializer.CodecFactory) []interface{} {
ContentType: runtime.ContentTypeJSON, ContentType: runtime.ContentTypeJSON,
} }
} }
switch c.RandBool() { switch c.Bool() {
case true: case true:
e.ResponseObject = nil e.ResponseObject = nil
case false: case false:
@ -52,8 +52,8 @@ func Funcs(codecs runtimeserializer.CodecFactory) []interface{} {
} }
} }
}, },
func(o *audit.ObjectReference, c fuzz.Continue) { func(o *audit.ObjectReference, c randfill.Continue) {
c.FuzzNoCustom(o) c.FillNoCustom(o)
switch c.Intn(3) { switch c.Intn(3) {
case 0: case 0:
// core api group // core api group

View File

@ -19,7 +19,7 @@ package fuzzer
import ( import (
"fmt" "fmt"
"github.com/google/gofuzz" "sigs.k8s.io/randfill"
apitesting "k8s.io/apimachinery/pkg/api/apitesting" apitesting "k8s.io/apimachinery/pkg/api/apitesting"
"k8s.io/apimachinery/pkg/api/apitesting/fuzzer" "k8s.io/apimachinery/pkg/api/apitesting/fuzzer"
@ -33,9 +33,9 @@ import (
// values in a Kubernetes context. // values in a Kubernetes context.
func overrideMetaFuncs(codecs runtimeserializer.CodecFactory) []interface{} { func overrideMetaFuncs(codecs runtimeserializer.CodecFactory) []interface{} {
return []interface{}{ return []interface{}{
func(j *runtime.Object, c fuzz.Continue) { func(j *runtime.Object, c randfill.Continue) {
// TODO: uncomment when round trip starts from a versioned object // TODO: uncomment when round trip starts from a versioned object
if true { //c.RandBool() { if true { // c.Bool() {
*j = &runtime.Unknown{ *j = &runtime.Unknown{
// We do not set TypeMeta here because it is not carried through a round trip // We do not set TypeMeta here because it is not carried through a round trip
Raw: []byte(`{"apiVersion":"unknown.group/unknown","kind":"Something","someKey":"someValue"}`), Raw: []byte(`{"apiVersion":"unknown.group/unknown","kind":"Something","someKey":"someValue"}`),
@ -44,15 +44,15 @@ func overrideMetaFuncs(codecs runtimeserializer.CodecFactory) []interface{} {
} else { } else {
types := []runtime.Object{&example.Pod{}} types := []runtime.Object{&example.Pod{}}
t := types[c.Rand.Intn(len(types))] t := types[c.Rand.Intn(len(types))]
c.Fuzz(t) c.Fill(t)
*j = t *j = t
} }
}, },
func(r *runtime.RawExtension, c fuzz.Continue) { func(r *runtime.RawExtension, c randfill.Continue) {
// Pick an arbitrary type and fuzz it // Pick an arbitrary type and fuzz it
types := []runtime.Object{&example.Pod{}} types := []runtime.Object{&example.Pod{}}
obj := types[c.Rand.Intn(len(types))] obj := types[c.Rand.Intn(len(types))]
c.Fuzz(obj) c.Fill(obj)
// Convert the object to raw bytes // Convert the object to raw bytes
bytes, err := runtime.Encode(apitesting.TestCodec(codecs, examplev1.SchemeGroupVersion), obj) bytes, err := runtime.Encode(apitesting.TestCodec(codecs, examplev1.SchemeGroupVersion), obj)
@ -68,11 +68,11 @@ func overrideMetaFuncs(codecs runtimeserializer.CodecFactory) []interface{} {
func exampleFuncs(codecs runtimeserializer.CodecFactory) []interface{} { func exampleFuncs(codecs runtimeserializer.CodecFactory) []interface{} {
return []interface{}{ return []interface{}{
func(s *example.PodSpec, c fuzz.Continue) { func(s *example.PodSpec, c randfill.Continue) {
c.FuzzNoCustom(s) c.FillNoCustom(s)
// has a default value // has a default value
ttl := int64(30) ttl := int64(30)
if c.RandBool() { if c.Bool() {
ttl = int64(c.Uint32()) ttl = int64(c.Uint32())
} }
s.TerminationGracePeriodSeconds = &ttl s.TerminationGracePeriodSeconds = &ttl
@ -81,11 +81,11 @@ func exampleFuncs(codecs runtimeserializer.CodecFactory) []interface{} {
s.SchedulerName = "default-scheduler" s.SchedulerName = "default-scheduler"
} }
}, },
func(j *example.PodPhase, c fuzz.Continue) { func(j *example.PodPhase, c randfill.Continue) {
statuses := []example.PodPhase{"Pending", "Running", "Succeeded", "Failed", "Unknown"} statuses := []example.PodPhase{"Pending", "Running", "Succeeded", "Failed", "Unknown"}
*j = statuses[c.Rand.Intn(len(statuses))] *j = statuses[c.Rand.Intn(len(statuses))]
}, },
func(rp *example.RestartPolicy, c fuzz.Continue) { func(rp *example.RestartPolicy, c randfill.Continue) {
policies := []example.RestartPolicy{"Always", "Never", "OnFailure"} policies := []example.RestartPolicy{"Always", "Never", "OnFailure"}
*rp = policies[c.Rand.Intn(len(policies))] *rp = policies[c.Rand.Intn(len(policies))]
}, },

View File

@ -22,7 +22,7 @@ import (
"strings" "strings"
"testing" "testing"
fuzz "github.com/google/gofuzz" "sigs.k8s.io/randfill"
) )
// TestEscaping tests that property names are escaped as expected. // TestEscaping tests that property names are escaped as expected.
@ -143,10 +143,10 @@ func TestUnescapeMalformed(t *testing.T) {
} }
func TestEscapingFuzz(t *testing.T) { func TestEscapingFuzz(t *testing.T) {
fuzzer := fuzz.New() fuzzer := randfill.New()
for i := 0; i < 1000; i++ { for i := 0; i < 1000; i++ {
var unescaped string var unescaped string
fuzzer.Fuzz(&unescaped) fuzzer.Fill(&unescaped)
t.Run(fmt.Sprintf("%d - '%s'", i, unescaped), func(t *testing.T) { t.Run(fmt.Sprintf("%d - '%s'", i, unescaped), func(t *testing.T) {
if len(unescaped) == 0 { if len(unescaped) == 0 {
return return

View File

@ -4463,7 +4463,7 @@ func benchmarkItems(b *testing.B) []example.Pod {
clientapiObjectFuzzer := fuzzer.FuzzerFor(examplefuzzer.Funcs, rand.NewSource(benchmarkSeed), codecs) clientapiObjectFuzzer := fuzzer.FuzzerFor(examplefuzzer.Funcs, rand.NewSource(benchmarkSeed), codecs)
items := make([]example.Pod, 3) items := make([]example.Pod, 3)
for i := range items { for i := range items {
clientapiObjectFuzzer.Fuzz(&items[i]) clientapiObjectFuzzer.Fill(&items[i])
} }
return items return items
} }

View File

@ -29,9 +29,9 @@ import (
"sync" "sync"
"testing" "testing"
fuzz "github.com/google/gofuzz"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"sigs.k8s.io/randfill"
apidiscoveryv2 "k8s.io/api/apidiscovery/v2" apidiscoveryv2 "k8s.io/api/apidiscovery/v2"
apidiscoveryv2beta1 "k8s.io/api/apidiscovery/v2beta1" apidiscoveryv2beta1 "k8s.io/api/apidiscovery/v2beta1"
@ -59,16 +59,16 @@ func init() {
} }
func fuzzAPIGroups(atLeastNumGroups, maxNumGroups int, seed int64) apidiscoveryv2.APIGroupDiscoveryList { func fuzzAPIGroups(atLeastNumGroups, maxNumGroups int, seed int64) apidiscoveryv2.APIGroupDiscoveryList {
fuzzer := fuzz.NewWithSeed(seed) fuzzer := randfill.NewWithSeed(seed)
fuzzer.NumElements(atLeastNumGroups, maxNumGroups) fuzzer.NumElements(atLeastNumGroups, maxNumGroups)
fuzzer.NilChance(0) fuzzer.NilChance(0)
fuzzer.Funcs(func(o *apidiscoveryv2.APIGroupDiscovery, c fuzz.Continue) { fuzzer.Funcs(func(o *apidiscoveryv2.APIGroupDiscovery, c randfill.Continue) {
c.FuzzNoCustom(o) c.FillNoCustom(o)
// The ResourceManager will just not serve the group if its versions // The ResourceManager will just not serve the group if its versions
// list is empty // list is empty
atLeastOne := apidiscoveryv2.APIVersionDiscovery{} atLeastOne := apidiscoveryv2.APIVersionDiscovery{}
c.Fuzz(&atLeastOne) c.Fill(&atLeastOne)
o.Versions = append(o.Versions, atLeastOne) o.Versions = append(o.Versions, atLeastOne)
sort.Slice(o.Versions[:], func(i, j int) bool { sort.Slice(o.Versions[:], func(i, j int) bool {
return version.CompareKubeAwareVersionStrings(o.Versions[i].Version, o.Versions[j].Version) > 0 return version.CompareKubeAwareVersionStrings(o.Versions[i].Version, o.Versions[j].Version) > 0
@ -76,14 +76,14 @@ func fuzzAPIGroups(atLeastNumGroups, maxNumGroups int, seed int64) apidiscoveryv
o.TypeMeta = metav1.TypeMeta{} o.TypeMeta = metav1.TypeMeta{}
var name string var name string
c.Fuzz(&name) c.Fill(&name)
o.ObjectMeta = metav1.ObjectMeta{ o.ObjectMeta = metav1.ObjectMeta{
Name: name, Name: name,
} }
}) })
var apis []apidiscoveryv2.APIGroupDiscovery var apis []apidiscoveryv2.APIGroupDiscovery
fuzzer.Fuzz(&apis) fuzzer.Fill(&apis)
sort.Slice(apis[:], func(i, j int) bool { sort.Slice(apis[:], func(i, j int) bool {
return apis[i].Name < apis[j].Name return apis[i].Name < apis[j].Name
}) })

View File

@ -28,7 +28,6 @@ import (
"time" "time"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
fuzz "github.com/google/gofuzz"
jsonpatch "gopkg.in/evanphx/json-patch.v4" jsonpatch "gopkg.in/evanphx/json-patch.v4"
apiequality "k8s.io/apimachinery/pkg/api/equality" apiequality "k8s.io/apimachinery/pkg/api/equality"
apierrors "k8s.io/apimachinery/pkg/api/errors" apierrors "k8s.io/apimachinery/pkg/api/errors"
@ -53,6 +52,7 @@ import (
clientgoscheme "k8s.io/client-go/kubernetes/scheme" clientgoscheme "k8s.io/client-go/kubernetes/scheme"
"k8s.io/component-base/metrics/legacyregistry" "k8s.io/component-base/metrics/legacyregistry"
"k8s.io/component-base/metrics/testutil" "k8s.io/component-base/metrics/testutil"
"sigs.k8s.io/randfill"
) )
var ( var (
@ -991,11 +991,11 @@ func (alwaysErrorTyper) Recognizes(gvk schema.GroupVersionKind) bool {
} }
func TestUpdateToCreateOptions(t *testing.T) { func TestUpdateToCreateOptions(t *testing.T) {
f := fuzz.New() f := randfill.New()
for i := 0; i < 100; i++ { for i := 0; i < 100; i++ {
t.Run(fmt.Sprintf("Run %d/100", i), func(t *testing.T) { t.Run(fmt.Sprintf("Run %d/100", i), func(t *testing.T) {
update := &metav1.UpdateOptions{} update := &metav1.UpdateOptions{}
f.Fuzz(update) f.Fill(update)
create := updateToCreateOptions(update) create := updateToCreateOptions(update)
b, err := json.Marshal(create) b, err := json.Marshal(create)
@ -1038,13 +1038,13 @@ func TestPatchToUpdateOptions(t *testing.T) {
}, },
} }
f := fuzz.New() f := randfill.New()
for _, test := range tests { for _, test := range tests {
t.Run(test.name, func(t *testing.T) { t.Run(test.name, func(t *testing.T) {
for i := 0; i < 100; i++ { for i := 0; i < 100; i++ {
t.Run(fmt.Sprintf("Run %d/100", i), func(t *testing.T) { t.Run(fmt.Sprintf("Run %d/100", i), func(t *testing.T) {
patch := &metav1.PatchOptions{} patch := &metav1.PatchOptions{}
f.Fuzz(patch) f.Fill(patch)
converted := test.converterFn(patch) converted := test.converterFn(patch)
b, err := json.Marshal(converted) b, err := json.Marshal(converted)

View File

@ -29,7 +29,7 @@ import (
"testing" "testing"
"time" "time"
fuzz "github.com/google/gofuzz" "sigs.k8s.io/randfill"
"k8s.io/apimachinery/pkg/api/apitesting" "k8s.io/apimachinery/pkg/api/apitesting"
apiequality "k8s.io/apimachinery/pkg/api/equality" apiequality "k8s.io/apimachinery/pkg/api/equality"
@ -480,13 +480,13 @@ func TestStoreCreateWithRetryNameGenerateFeatureDisabled(t *testing.T) {
} }
func TestNewCreateOptionsFromUpdateOptions(t *testing.T) { func TestNewCreateOptionsFromUpdateOptions(t *testing.T) {
f := fuzz.New().NilChance(0.0).NumElements(1, 1) f := randfill.New().NilChance(0.0).NumElements(1, 1)
// The goal here is to trigger when any changes are made to either // The goal here is to trigger when any changes are made to either
// CreateOptions or UpdateOptions types, so we can update the converter. // CreateOptions or UpdateOptions types, so we can update the converter.
for i := 0; i < 20; i++ { for i := 0; i < 20; i++ {
in := &metav1.UpdateOptions{} in := &metav1.UpdateOptions{}
f.Fuzz(in) f.Fill(in)
in.TypeMeta.SetGroupVersionKind(metav1.SchemeGroupVersion.WithKind("CreateOptions")) in.TypeMeta.SetGroupVersionKind(metav1.SchemeGroupVersion.WithKind("CreateOptions"))
out := newCreateOptionsFromUpdateOptions(in) out := newCreateOptionsFromUpdateOptions(in)
@ -532,13 +532,13 @@ func TestNewCreateOptionsFromUpdateOptions(t *testing.T) {
} }
func TestNewDeleteOptionsFromUpdateOptions(t *testing.T) { func TestNewDeleteOptionsFromUpdateOptions(t *testing.T) {
f := fuzz.New().NilChance(0.0).NumElements(1, 1) f := randfill.New().NilChance(0.0).NumElements(1, 1)
// The goal here is to trigger when any changes are made to either // The goal here is to trigger when any changes are made to either
// DeleteOptions or UpdateOptions types, so we can update the converter. // DeleteOptions or UpdateOptions types, so we can update the converter.
for i := 0; i < 20; i++ { for i := 0; i < 20; i++ {
in := &metav1.UpdateOptions{} in := &metav1.UpdateOptions{}
f.Fuzz(in) f.Fill(in)
in.TypeMeta.SetGroupVersionKind(metav1.SchemeGroupVersion.WithKind("DeleteOptions")) in.TypeMeta.SetGroupVersionKind(metav1.SchemeGroupVersion.WithKind("DeleteOptions"))
out := newDeleteOptionsFromUpdateOptions(in) out := newDeleteOptionsFromUpdateOptions(in)

View File

@ -24,22 +24,22 @@ import (
"time" "time"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
fuzz "github.com/google/gofuzz" "sigs.k8s.io/randfill"
authenticationv1 "k8s.io/api/authentication/v1" authenticationv1 "k8s.io/api/authentication/v1"
authenticationv1beta1 "k8s.io/api/authentication/v1beta1" authenticationv1beta1 "k8s.io/api/authentication/v1beta1"
) )
func TestRoundTrip(t *testing.T) { func TestRoundTrip(t *testing.T) {
f := fuzz.New() f := randfill.New()
seed := time.Now().UnixNano() seed := time.Now().UnixNano()
t.Logf("seed = %v", seed) t.Logf("seed = %v", seed)
f.RandSource(rand.New(rand.NewSource(seed))) f.RandSource(rand.New(rand.NewSource(seed)))
for i := 0; i < 1000; i++ { for i := 0; i < 1000; i++ {
original := &authenticationv1.TokenReview{} original := &authenticationv1.TokenReview{}
f.Fuzz(&original.Spec) f.Fill(&original.Spec)
f.Fuzz(&original.Status) f.Fill(&original.Status)
converted := &authenticationv1beta1.TokenReview{ converted := &authenticationv1beta1.TokenReview{
Spec: v1SpecToV1beta1Spec(&original.Spec), Spec: v1SpecToV1beta1Spec(&original.Spec),
Status: v1StatusToV1beta1Status(original.Status), Status: v1StatusToV1beta1Status(original.Status),

View File

@ -24,22 +24,22 @@ import (
"time" "time"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
fuzz "github.com/google/gofuzz" "sigs.k8s.io/randfill"
authorizationv1 "k8s.io/api/authorization/v1" authorizationv1 "k8s.io/api/authorization/v1"
authorizationv1beta1 "k8s.io/api/authorization/v1beta1" authorizationv1beta1 "k8s.io/api/authorization/v1beta1"
) )
func TestRoundTrip(t *testing.T) { func TestRoundTrip(t *testing.T) {
f := fuzz.New() f := randfill.New()
seed := time.Now().UnixNano() seed := time.Now().UnixNano()
t.Logf("seed = %v", seed) t.Logf("seed = %v", seed)
f.RandSource(rand.New(rand.NewSource(seed))) f.RandSource(rand.New(rand.NewSource(seed)))
for i := 0; i < 1000; i++ { for i := 0; i < 1000; i++ {
original := &authorizationv1.SubjectAccessReview{} original := &authorizationv1.SubjectAccessReview{}
f.Fuzz(&original.Spec) f.Fill(&original.Spec)
f.Fuzz(&original.Status) f.Fill(&original.Status)
converted := &authorizationv1beta1.SubjectAccessReview{ converted := &authorizationv1beta1.SubjectAccessReview{
Spec: v1SpecToV1beta1Spec(&original.Spec), Spec: v1SpecToV1beta1Spec(&original.Spec),
Status: v1StatusToV1beta1Status(original.Status), Status: v1StatusToV1beta1Status(original.Status),

View File

@ -39,9 +39,9 @@ import (
"k8s.io/client-go/util/flowcontrol" "k8s.io/client-go/util/flowcontrol"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
fuzz "github.com/google/gofuzz"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"sigs.k8s.io/randfill"
) )
func TestIsConfigTransportTLS(t *testing.T) { func TestIsConfigTransportTLS(t *testing.T) {
@ -313,60 +313,60 @@ func (fakeAuthProviderConfigPersister) Persist(map[string]string) error {
var fakeAuthProviderConfigPersisterError = errors.New("fakeAuthProviderConfigPersisterError") var fakeAuthProviderConfigPersisterError = errors.New("fakeAuthProviderConfigPersisterError")
func TestAnonymousAuthConfig(t *testing.T) { func TestAnonymousAuthConfig(t *testing.T) {
f := fuzz.New().NilChance(0.0).NumElements(1, 1) f := randfill.New().NilChance(0.0).NumElements(1, 1)
f.Funcs( f.Funcs(
func(r *runtime.Codec, f fuzz.Continue) { func(r *runtime.Codec, f randfill.Continue) {
codec := &fakeCodec{} codec := &fakeCodec{}
f.Fuzz(codec) f.Fill(codec)
*r = codec *r = codec
}, },
func(r *http.RoundTripper, f fuzz.Continue) { func(r *http.RoundTripper, f randfill.Continue) {
roundTripper := &fakeRoundTripper{} roundTripper := &fakeRoundTripper{}
f.Fuzz(roundTripper) f.Fill(roundTripper)
*r = roundTripper *r = roundTripper
}, },
func(fn *func(http.RoundTripper) http.RoundTripper, f fuzz.Continue) { func(fn *func(http.RoundTripper) http.RoundTripper, f randfill.Continue) {
*fn = fakeWrapperFunc *fn = fakeWrapperFunc
}, },
func(fn *transport.WrapperFunc, f fuzz.Continue) { func(fn *transport.WrapperFunc, f randfill.Continue) {
*fn = fakeWrapperFunc *fn = fakeWrapperFunc
}, },
func(r *runtime.NegotiatedSerializer, f fuzz.Continue) { func(r *runtime.NegotiatedSerializer, f randfill.Continue) {
serializer := &fakeNegotiatedSerializer{} serializer := &fakeNegotiatedSerializer{}
f.Fuzz(serializer) f.Fill(serializer)
*r = serializer *r = serializer
}, },
func(r *flowcontrol.RateLimiter, f fuzz.Continue) { func(r *flowcontrol.RateLimiter, f randfill.Continue) {
limiter := &fakeLimiter{} limiter := &fakeLimiter{}
f.Fuzz(limiter) f.Fill(limiter)
*r = limiter *r = limiter
}, },
func(h *WarningHandler, f fuzz.Continue) { func(h *WarningHandler, f randfill.Continue) {
*h = &fakeWarningHandler{} *h = &fakeWarningHandler{}
}, },
func(h *WarningHandlerWithContext, f fuzz.Continue) { func(h *WarningHandlerWithContext, f randfill.Continue) {
*h = &fakeWarningHandlerWithContext{} *h = &fakeWarningHandlerWithContext{}
}, },
// Authentication does not require fuzzer // Authentication does not require fuzzer
func(r *AuthProviderConfigPersister, f fuzz.Continue) {}, func(r *AuthProviderConfigPersister, f randfill.Continue) {},
func(r *clientcmdapi.AuthProviderConfig, f fuzz.Continue) { func(r *clientcmdapi.AuthProviderConfig, f randfill.Continue) {
r.Config = map[string]string{} r.Config = map[string]string{}
}, },
func(r *func(ctx context.Context, network, addr string) (net.Conn, error), f fuzz.Continue) { func(r *func(ctx context.Context, network, addr string) (net.Conn, error), f randfill.Continue) {
*r = fakeDialFunc *r = fakeDialFunc
}, },
func(r *func(*http.Request) (*url.URL, error), f fuzz.Continue) { func(r *func(*http.Request) (*url.URL, error), f randfill.Continue) {
*r = fakeProxyFunc *r = fakeProxyFunc
}, },
func(r *runtime.Object, f fuzz.Continue) { func(r *runtime.Object, f randfill.Continue) {
unknown := &runtime.Unknown{} unknown := &runtime.Unknown{}
f.Fuzz(unknown) f.Fill(unknown)
*r = unknown *r = unknown
}, },
) )
for i := 0; i < 20; i++ { for i := 0; i < 20; i++ {
original := &Config{} original := &Config{}
f.Fuzz(original) f.Fill(original)
actual := AnonymousClientConfig(original) actual := AnonymousClientConfig(original)
expected := *original expected := *original
@ -414,58 +414,58 @@ func TestAnonymousAuthConfig(t *testing.T) {
} }
func TestCopyConfig(t *testing.T) { func TestCopyConfig(t *testing.T) {
f := fuzz.New().NilChance(0.0).NumElements(1, 1) f := randfill.New().NilChance(0.0).NumElements(1, 1)
f.Funcs( f.Funcs(
func(r *runtime.Codec, f fuzz.Continue) { func(r *runtime.Codec, f randfill.Continue) {
codec := &fakeCodec{} codec := &fakeCodec{}
f.Fuzz(codec) f.Fill(codec)
*r = codec *r = codec
}, },
func(r *http.RoundTripper, f fuzz.Continue) { func(r *http.RoundTripper, f randfill.Continue) {
roundTripper := &fakeRoundTripper{} roundTripper := &fakeRoundTripper{}
f.Fuzz(roundTripper) f.Fill(roundTripper)
*r = roundTripper *r = roundTripper
}, },
func(fn *func(http.RoundTripper) http.RoundTripper, f fuzz.Continue) { func(fn *func(http.RoundTripper) http.RoundTripper, f randfill.Continue) {
*fn = fakeWrapperFunc *fn = fakeWrapperFunc
}, },
func(fn *transport.WrapperFunc, f fuzz.Continue) { func(fn *transport.WrapperFunc, f randfill.Continue) {
*fn = fakeWrapperFunc *fn = fakeWrapperFunc
}, },
func(r *runtime.NegotiatedSerializer, f fuzz.Continue) { func(r *runtime.NegotiatedSerializer, f randfill.Continue) {
serializer := &fakeNegotiatedSerializer{} serializer := &fakeNegotiatedSerializer{}
f.Fuzz(serializer) f.Fill(serializer)
*r = serializer *r = serializer
}, },
func(r *flowcontrol.RateLimiter, f fuzz.Continue) { func(r *flowcontrol.RateLimiter, f randfill.Continue) {
limiter := &fakeLimiter{} limiter := &fakeLimiter{}
f.Fuzz(limiter) f.Fill(limiter)
*r = limiter *r = limiter
}, },
func(h *WarningHandler, f fuzz.Continue) { func(h *WarningHandler, f randfill.Continue) {
*h = &fakeWarningHandler{} *h = &fakeWarningHandler{}
}, },
func(h *WarningHandlerWithContext, f fuzz.Continue) { func(h *WarningHandlerWithContext, f randfill.Continue) {
*h = &fakeWarningHandlerWithContext{} *h = &fakeWarningHandlerWithContext{}
}, },
func(r *AuthProviderConfigPersister, f fuzz.Continue) { func(r *AuthProviderConfigPersister, f randfill.Continue) {
*r = fakeAuthProviderConfigPersister{} *r = fakeAuthProviderConfigPersister{}
}, },
func(r *func(ctx context.Context, network, addr string) (net.Conn, error), f fuzz.Continue) { func(r *func(ctx context.Context, network, addr string) (net.Conn, error), f randfill.Continue) {
*r = fakeDialFunc *r = fakeDialFunc
}, },
func(r *func(*http.Request) (*url.URL, error), f fuzz.Continue) { func(r *func(*http.Request) (*url.URL, error), f randfill.Continue) {
*r = fakeProxyFunc *r = fakeProxyFunc
}, },
func(r *runtime.Object, f fuzz.Continue) { func(r *runtime.Object, f randfill.Continue) {
unknown := &runtime.Unknown{} unknown := &runtime.Unknown{}
f.Fuzz(unknown) f.Fill(unknown)
*r = unknown *r = unknown
}, },
) )
for i := 0; i < 20; i++ { for i := 0; i < 20; i++ {
original := &Config{} original := &Config{}
f.Fuzz(original) f.Fill(original)
actual := CopyConfig(original) actual := CopyConfig(original)
expected := *original expected := *original

View File

@ -26,12 +26,12 @@ import (
"testing" "testing"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
fuzz "github.com/google/gofuzz"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
clientauthenticationapi "k8s.io/client-go/pkg/apis/clientauthentication" clientauthenticationapi "k8s.io/client-go/pkg/apis/clientauthentication"
clientcmdapi "k8s.io/client-go/tools/clientcmd/api" clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
"k8s.io/client-go/transport" "k8s.io/client-go/transport"
"k8s.io/client-go/util/flowcontrol" "k8s.io/client-go/util/flowcontrol"
"sigs.k8s.io/randfill"
) )
func TestConfigToExecCluster(t *testing.T) { func TestConfigToExecCluster(t *testing.T) {
@ -211,60 +211,60 @@ func TestConfigToExecCluster(t *testing.T) {
func TestConfigToExecClusterRoundtrip(t *testing.T) { func TestConfigToExecClusterRoundtrip(t *testing.T) {
t.Parallel() t.Parallel()
f := fuzz.New().NilChance(0.5).NumElements(1, 1) f := randfill.New().NilChance(0.5).NumElements(1, 1)
f.Funcs( f.Funcs(
func(r *runtime.Codec, f fuzz.Continue) { func(r *runtime.Codec, f randfill.Continue) {
codec := &fakeCodec{} codec := &fakeCodec{}
f.Fuzz(codec) f.Fill(codec)
*r = codec *r = codec
}, },
func(r *http.RoundTripper, f fuzz.Continue) { func(r *http.RoundTripper, f randfill.Continue) {
roundTripper := &fakeRoundTripper{} roundTripper := &fakeRoundTripper{}
f.Fuzz(roundTripper) f.Fill(roundTripper)
*r = roundTripper *r = roundTripper
}, },
func(fn *func(http.RoundTripper) http.RoundTripper, f fuzz.Continue) { func(fn *func(http.RoundTripper) http.RoundTripper, f randfill.Continue) {
*fn = fakeWrapperFunc *fn = fakeWrapperFunc
}, },
func(fn *transport.WrapperFunc, f fuzz.Continue) { func(fn *transport.WrapperFunc, f randfill.Continue) {
*fn = fakeWrapperFunc *fn = fakeWrapperFunc
}, },
func(r *runtime.NegotiatedSerializer, f fuzz.Continue) { func(r *runtime.NegotiatedSerializer, f randfill.Continue) {
serializer := &fakeNegotiatedSerializer{} serializer := &fakeNegotiatedSerializer{}
f.Fuzz(serializer) f.Fill(serializer)
*r = serializer *r = serializer
}, },
func(r *flowcontrol.RateLimiter, f fuzz.Continue) { func(r *flowcontrol.RateLimiter, f randfill.Continue) {
limiter := &fakeLimiter{} limiter := &fakeLimiter{}
f.Fuzz(limiter) f.Fill(limiter)
*r = limiter *r = limiter
}, },
func(h *WarningHandler, f fuzz.Continue) { func(h *WarningHandler, f randfill.Continue) {
*h = &fakeWarningHandler{} *h = &fakeWarningHandler{}
}, },
func(h *WarningHandlerWithContext, f fuzz.Continue) { func(h *WarningHandlerWithContext, f randfill.Continue) {
*h = &fakeWarningHandlerWithContext{} *h = &fakeWarningHandlerWithContext{}
}, },
// Authentication does not require fuzzer // Authentication does not require fuzzer
func(r *AuthProviderConfigPersister, f fuzz.Continue) {}, func(r *AuthProviderConfigPersister, f randfill.Continue) {},
func(r *clientcmdapi.AuthProviderConfig, f fuzz.Continue) { func(r *clientcmdapi.AuthProviderConfig, f randfill.Continue) {
r.Config = map[string]string{} r.Config = map[string]string{}
}, },
func(r *func(ctx context.Context, network, addr string) (net.Conn, error), f fuzz.Continue) { func(r *func(ctx context.Context, network, addr string) (net.Conn, error), f randfill.Continue) {
*r = fakeDialFunc *r = fakeDialFunc
}, },
func(r *func(*http.Request) (*url.URL, error), f fuzz.Continue) { func(r *func(*http.Request) (*url.URL, error), f randfill.Continue) {
*r = fakeProxyFunc *r = fakeProxyFunc
}, },
func(r *runtime.Object, f fuzz.Continue) { func(r *runtime.Object, f randfill.Continue) {
unknown := &runtime.Unknown{} unknown := &runtime.Unknown{}
f.Fuzz(unknown) f.Fill(unknown)
*r = unknown *r = unknown
}, },
) )
for i := 0; i < 100; i++ { for i := 0; i < 100; i++ {
expected := &Config{} expected := &Config{}
f.Fuzz(expected) f.Fill(expected)
// This is the list of known fields that this roundtrip doesn't care about. We should add new // This is the list of known fields that this roundtrip doesn't care about. We should add new
// fields to this list if we don't want to roundtrip them on exec cluster conversion. // fields to this list if we don't want to roundtrip them on exec cluster conversion.
@ -347,9 +347,9 @@ func TestConfigToExecClusterRoundtrip(t *testing.T) {
func TestExecClusterToConfigRoundtrip(t *testing.T) { func TestExecClusterToConfigRoundtrip(t *testing.T) {
t.Parallel() t.Parallel()
f := fuzz.New().NilChance(0.5).NumElements(1, 1) f := randfill.New().NilChance(0.5).NumElements(1, 1)
f.Funcs( f.Funcs(
func(r *runtime.Object, f fuzz.Continue) { func(r *runtime.Object, f randfill.Continue) {
// We don't expect the clientauthentication.Cluster.Config to show up in the Config that // We don't expect the clientauthentication.Cluster.Config to show up in the Config that
// comes back from the roundtrip, so just set it to nil. // comes back from the roundtrip, so just set it to nil.
*r = nil *r = nil
@ -357,7 +357,7 @@ func TestExecClusterToConfigRoundtrip(t *testing.T) {
) )
for i := 0; i < 100; i++ { for i := 0; i < 100; i++ {
expected := &clientauthenticationapi.Cluster{} expected := &clientauthenticationapi.Cluster{}
f.Fuzz(expected) f.Fill(expected)
// Manually set URLs so we don't get an error when parsing these during the roundtrip. // Manually set URLs so we don't get an error when parsing these during the roundtrip.
if expected.Server != "" { if expected.Server != "" {

View File

@ -35,7 +35,7 @@ import (
fcache "k8s.io/client-go/tools/cache/testing" fcache "k8s.io/client-go/tools/cache/testing"
"k8s.io/klog/v2/ktesting" "k8s.io/klog/v2/ktesting"
fuzz "github.com/google/gofuzz" "sigs.k8s.io/randfill"
) )
func Example() { func Example() {
@ -252,12 +252,12 @@ func TestHammerController(t *testing.T) {
// Let's add a few objects to the source. // Let's add a few objects to the source.
currentNames := sets.String{} currentNames := sets.String{}
rs := rand.NewSource(rand.Int63()) rs := rand.NewSource(rand.Int63())
f := fuzz.New().NilChance(.5).NumElements(0, 2).RandSource(rs) f := randfill.New().NilChance(.5).NumElements(0, 2).RandSource(rs)
for i := 0; i < 100; i++ { for i := 0; i < 100; i++ {
var name string var name string
var isNew bool var isNew bool
if currentNames.Len() == 0 || rand.Intn(3) == 1 { if currentNames.Len() == 0 || rand.Intn(3) == 1 {
f.Fuzz(&name) f.Fill(&name)
isNew = true isNew = true
} else { } else {
l := currentNames.List() l := currentNames.List()
@ -265,7 +265,7 @@ func TestHammerController(t *testing.T) {
} }
pod := &v1.Pod{} pod := &v1.Pod{}
f.Fuzz(pod) f.Fill(pod)
pod.ObjectMeta.Name = name pod.ObjectMeta.Name = name
pod.ObjectMeta.Namespace = "default" pod.ObjectMeta.Namespace = "default"
// Add, update, or delete randomly. // Add, update, or delete randomly.

View File

@ -17,7 +17,7 @@ limitations under the License.
package outputtests package outputtests
import ( import (
"github.com/google/gofuzz" "sigs.k8s.io/randfill"
"k8s.io/code-generator/cmd/deepcopy-gen/output_tests/aliases" "k8s.io/code-generator/cmd/deepcopy-gen/output_tests/aliases"
"k8s.io/code-generator/cmd/deepcopy-gen/output_tests/interfaces" "k8s.io/code-generator/cmd/deepcopy-gen/output_tests/interfaces"
@ -27,49 +27,49 @@ import (
// JSON deepcopy does not work with it. // JSON deepcopy does not work with it.
// TODO: test also interface deepcopy // TODO: test also interface deepcopy
var interfaceFuzzers = []interface{}{ var interfaceFuzzers = []interface{}{
func(s *aliases.AliasAliasInterface, c fuzz.Continue) { func(s *aliases.AliasAliasInterface, c randfill.Continue) {
if c.RandBool() { if c.Bool() {
*s = nil *s = nil
} else { } else {
*s = &aliasAliasInterfaceInstance{X: c.Int()} *s = &aliasAliasInterfaceInstance{X: c.Int()}
} }
}, },
func(s *aliases.AliasInterface, c fuzz.Continue) { func(s *aliases.AliasInterface, c randfill.Continue) {
if c.RandBool() { if c.Bool() {
*s = nil *s = nil
} else { } else {
*s = &aliasAliasInterfaceInstance{X: c.Int()} *s = &aliasAliasInterfaceInstance{X: c.Int()}
} }
}, },
func(s *aliases.Interface, c fuzz.Continue) { func(s *aliases.Interface, c randfill.Continue) {
if c.RandBool() { if c.Bool() {
*s = nil *s = nil
} else { } else {
*s = &aliasAliasInterfaceInstance{X: c.Int()} *s = &aliasAliasInterfaceInstance{X: c.Int()}
} }
}, },
func(s *aliases.AliasInterfaceMap, c fuzz.Continue) { func(s *aliases.AliasInterfaceMap, c randfill.Continue) {
if c.RandBool() { if c.Bool() {
*s = nil *s = nil
} else { } else {
*s = make(aliases.AliasInterfaceMap) *s = make(aliases.AliasInterfaceMap)
for i := 0; i < c.Intn(3); i++ { for i := 0; i < c.Intn(3); i++ {
if c.RandBool() { if c.Bool() {
(*s)[c.RandString()] = nil (*s)[c.String(0)] = nil
} else { } else {
(*s)[c.RandString()] = &aliasAliasInterfaceInstance{X: c.Int()} (*s)[c.String(0)] = &aliasAliasInterfaceInstance{X: c.Int()}
} }
} }
} }
}, },
func(s *aliases.AliasInterfaceSlice, c fuzz.Continue) { func(s *aliases.AliasInterfaceSlice, c randfill.Continue) {
if c.RandBool() { if c.Bool() {
*s = nil *s = nil
} else { } else {
*s = make(aliases.AliasInterfaceSlice, 0) *s = make(aliases.AliasInterfaceSlice, 0)
for i := 0; i < c.Intn(3); i++ { for i := 0; i < c.Intn(3); i++ {
if c.RandBool() { if c.Bool() {
*s = append(*s, nil) *s = append(*s, nil)
} else { } else {
*s = append(*s, &aliasAliasInterfaceInstance{X: c.Int()}) *s = append(*s, &aliasAliasInterfaceInstance{X: c.Int()})
@ -77,8 +77,8 @@ var interfaceFuzzers = []interface{}{
} }
} }
}, },
func(s *interfaces.Inner, c fuzz.Continue) { func(s *interfaces.Inner, c randfill.Continue) {
if c.RandBool() { if c.Bool() {
*s = nil *s = nil
} else { } else {
*s = &interfacesInnerInstance{X: c.Float64()} *s = &interfacesInnerInstance{X: c.Float64()}

View File

@ -21,7 +21,7 @@ import (
"reflect" "reflect"
"testing" "testing"
fuzz "github.com/google/gofuzz" "sigs.k8s.io/randfill"
"k8s.io/apimachinery/pkg/util/dump" "k8s.io/apimachinery/pkg/util/dump"
"k8s.io/code-generator/cmd/deepcopy-gen/output_tests/aliases" "k8s.io/code-generator/cmd/deepcopy-gen/output_tests/aliases"
@ -44,7 +44,7 @@ func TestWithValueFuzzer(t *testing.T) {
structs.Ttest{}, structs.Ttest{},
} }
fuzzer := fuzz.New() fuzzer := randfill.New()
fuzzer.NilChance(0.5) fuzzer.NilChance(0.5)
fuzzer.NumElements(0, 2) fuzzer.NumElements(0, 2)
fuzzer.Funcs(interfaceFuzzers...) fuzzer.Funcs(interfaceFuzzers...)
@ -55,7 +55,7 @@ func TestWithValueFuzzer(t *testing.T) {
for i := 0; i < N; i++ { for i := 0; i < N; i++ {
original := reflect.New(reflect.TypeOf(test)).Interface() original := reflect.New(reflect.TypeOf(test)).Interface()
fuzzer.Fuzz(original) fuzzer.Fill(original)
reflectCopy := ReflectDeepCopy(original) reflectCopy := ReflectDeepCopy(original)
@ -149,7 +149,7 @@ func BenchmarkReflectDeepCopy(b *testing.B) {
}, },
} }
fuzzer := fuzz.New() fuzzer := randfill.New()
fuzzer.NilChance(0.5) fuzzer.NilChance(0.5)
fuzzer.NumElements(0, 2) fuzzer.NumElements(0, 2)
fuzzer.Funcs(interfaceFuzzers...) fuzzer.Funcs(interfaceFuzzers...)

View File

@ -20,7 +20,7 @@ import (
"reflect" "reflect"
"testing" "testing"
fuzz "github.com/google/gofuzz" "sigs.k8s.io/randfill"
) )
func TestDeepCopyPrimitives(t *testing.T) { func TestDeepCopyPrimitives(t *testing.T) {
@ -31,9 +31,9 @@ func TestDeepCopyPrimitives(t *testing.T) {
t.Errorf("objects should be equal to start, but are not") t.Errorf("objects should be equal to start, but are not")
} }
fuzzer := fuzz.New() fuzzer := randfill.New()
fuzzer.Fuzz(&x) fuzzer.Fill(&x)
fuzzer.Fuzz(&y) fuzzer.Fill(&y)
if reflect.DeepEqual(&x, &y) { if reflect.DeepEqual(&x, &y) {
t.Errorf("objects should not be equal, but are") t.Errorf("objects should not be equal, but are")
@ -53,14 +53,14 @@ func TestDeepCopyInterfaceFields(t *testing.T) {
t.Errorf("objects should be equal to start, but are not") t.Errorf("objects should be equal to start, but are not")
} }
fuzzer := fuzz.New() fuzzer := randfill.New()
obj := StructExplicitObject{} obj := StructExplicitObject{}
fuzzer.Fuzz(&obj) fuzzer.Fill(&obj)
x.ObjectField = &obj x.ObjectField = &obj
sel := StructExplicitSelectorExplicitObject{} sel := StructExplicitSelectorExplicitObject{}
fuzzer.Fuzz(&sel) fuzzer.Fill(&sel)
x.SelectorField = &sel x.SelectorField = &sel
if reflect.DeepEqual(&x, &y) { if reflect.DeepEqual(&x, &y) {
@ -115,8 +115,8 @@ func TestInterfaceTypes(t *testing.T) {
func TestInterfaceDeepCopy(t *testing.T) { func TestInterfaceDeepCopy(t *testing.T) {
x := StructExplicitObject{} x := StructExplicitObject{}
fuzzer := fuzz.New() fuzzer := randfill.New()
fuzzer.Fuzz(&x) fuzzer.Fill(&x)
yObj := x.DeepCopyObject() yObj := x.DeepCopyObject()
y, ok := yObj.(*StructExplicitObject) y, ok := yObj.(*StructExplicitObject)
@ -131,8 +131,8 @@ func TestInterfaceDeepCopy(t *testing.T) {
func TestInterfaceNonPointerDeepCopy(t *testing.T) { func TestInterfaceNonPointerDeepCopy(t *testing.T) {
x := StructNonPointerExplicitObject{} x := StructNonPointerExplicitObject{}
fuzzer := fuzz.New() fuzzer := randfill.New()
fuzzer.Fuzz(&x) fuzzer.Fill(&x)
yObj := x.DeepCopyObject() yObj := x.DeepCopyObject()
y, ok := yObj.(StructNonPointerExplicitObject) y, ok := yObj.(StructNonPointerExplicitObject)

View File

@ -123,7 +123,7 @@ type T1 struct {
} }
// TODO: the validateFalse test fixture doesn't handle map and slice types, and // TODO: the validateFalse test fixture doesn't handle map and slice types, and
// fixing it requires fixing gofuzz. That is a tomorrow problem. For now, the // fixing it requires fixing randfill. That is a tomorrow problem. For now, the
// following types have been tested to fail without +k8s:opaqueType. // following types have been tested to fail without +k8s:opaqueType.
/* /*

View File

@ -124,7 +124,7 @@ type OtherStruct struct {
type OtherString string type OtherString string
// TODO: the validateFalse test fixture doesn't handle map and slice types, and // TODO: the validateFalse test fixture doesn't handle map and slice types, and
// fixing it requires fixing gofuzz. That is a tomorrow problem. For now, the // fixing it requires fixing randfill. That is a tomorrow problem. For now, the
// following types have been tested to generate correct code with // following types have been tested to generate correct code with
// +k8s:opaqueType. // +k8s:opaqueType.

View File

@ -35,11 +35,11 @@ import (
"github.com/google/go-cmp/cmp" // nolint:depguard // this package provides test utilities "github.com/google/go-cmp/cmp" // nolint:depguard // this package provides test utilities
"github.com/google/go-cmp/cmp/cmpopts" // nolint:depguard // this package provides test utilities "github.com/google/go-cmp/cmp/cmpopts" // nolint:depguard // this package provides test utilities
fuzz "github.com/google/gofuzz"
"k8s.io/apimachinery/pkg/api/operation" "k8s.io/apimachinery/pkg/api/operation"
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/apimachinery/pkg/util/validation/field"
"sigs.k8s.io/randfill"
) )
// Scheme is similar to runtime.Scheme, but for validation testing purposes. Scheme only supports validation, // Scheme is similar to runtime.Scheme, but for validation testing purposes. Scheme only supports validation,
@ -221,15 +221,15 @@ func (s *ValidationTestBuilder) ValidateFixtures() {
} }
} }
func fuzzer() *fuzz.Fuzzer { func randfiller() *randfill.Filler {
// Ensure that lists and maps are not empty and use a deterministic seed. // Ensure that lists and maps are not empty and use a deterministic seed.
return fuzz.New().NilChance(0.0).NumElements(2, 2).RandSource(rand.NewSource(0)) return randfill.New().NilChance(0.0).NumElements(2, 2).RandSource(rand.NewSource(0))
} }
// ValueFuzzed automatically populates the given value using a deterministic fuzzer. // ValueFuzzed automatically populates the given value using a deterministic filler.
// The fuzzer sets pointers to values and always includes a two map keys and slice elements. // The filler sets pointers to values and always includes a two map keys and slice elements.
func (s *ValidationTestBuilder) ValueFuzzed(value any) *ValidationTester { func (s *ValidationTestBuilder) ValueFuzzed(value any) *ValidationTester {
fuzzer().Fuzz(value) randfiller().Fill(value)
return &ValidationTester{ValidationTestBuilder: s, value: value} return &ValidationTester{ValidationTestBuilder: s, value: value}
} }
@ -257,10 +257,10 @@ func (v *ValidationTester) OldValue(oldValue any) *ValidationTester {
return v return v
} }
// OldValueFuzzed automatically populates the given value using a deterministic fuzzer. // OldValueFuzzed automatically populates the given value using a deterministic filler.
// The fuzzer sets pointers to values and always includes a two map keys and slice elements. // The filler sets pointers to values and always includes a two map keys and slice elements.
func (v *ValidationTester) OldValueFuzzed(oldValue any) *ValidationTester { func (v *ValidationTester) OldValueFuzzed(oldValue any) *ValidationTester {
fuzzer().Fuzz(oldValue) randfiller().Fill(oldValue)
v.oldValue = oldValue v.oldValue = oldValue
return v return v
} }

View File

@ -30,8 +30,8 @@ import (
"time" "time"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
fuzz "github.com/google/gofuzz"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"sigs.k8s.io/randfill"
apidiscoveryv2 "k8s.io/api/apidiscovery/v2" apidiscoveryv2 "k8s.io/api/apidiscovery/v2"
apidiscoveryv2beta1 "k8s.io/api/apidiscovery/v2beta1" apidiscoveryv2beta1 "k8s.io/api/apidiscovery/v2beta1"
@ -1008,16 +1008,16 @@ func TestNotModified(t *testing.T) {
// copied from staging/src/k8s.io/apiserver/pkg/endpoints/discovery/v2/handler_test.go // copied from staging/src/k8s.io/apiserver/pkg/endpoints/discovery/v2/handler_test.go
func fuzzAPIGroups(atLeastNumGroups, maxNumGroups int, seed int64) apidiscoveryv2.APIGroupDiscoveryList { func fuzzAPIGroups(atLeastNumGroups, maxNumGroups int, seed int64) apidiscoveryv2.APIGroupDiscoveryList {
fuzzer := fuzz.NewWithSeed(seed) fuzzer := randfill.NewWithSeed(seed)
fuzzer.NumElements(atLeastNumGroups, maxNumGroups) fuzzer.NumElements(atLeastNumGroups, maxNumGroups)
fuzzer.NilChance(0) fuzzer.NilChance(0)
fuzzer.Funcs(func(o *apidiscoveryv2.APIGroupDiscovery, c fuzz.Continue) { fuzzer.Funcs(func(o *apidiscoveryv2.APIGroupDiscovery, c randfill.Continue) {
c.FuzzNoCustom(o) c.FillNoCustom(o)
// The ResourceManager will just not serve the group if its versions // The ResourceManager will just not serve the group if its versions
// list is empty // list is empty
atLeastOne := apidiscoveryv2.APIVersionDiscovery{} atLeastOne := apidiscoveryv2.APIVersionDiscovery{}
c.Fuzz(&atLeastOne) c.Fill(&atLeastOne)
o.Versions = append(o.Versions, atLeastOne) o.Versions = append(o.Versions, atLeastOne)
// clear invalid fuzzed values // clear invalid fuzzed values
@ -1032,7 +1032,7 @@ func fuzzAPIGroups(atLeastNumGroups, maxNumGroups int, seed int64) apidiscoveryv
}) })
var apis []apidiscoveryv2.APIGroupDiscovery var apis []apidiscoveryv2.APIGroupDiscovery
fuzzer.Fuzz(&apis) fuzzer.Fill(&apis)
return apidiscoveryv2.APIGroupDiscoveryList{ return apidiscoveryv2.APIGroupDiscoveryList{
TypeMeta: metav1.TypeMeta{ TypeMeta: metav1.TypeMeta{

View File

@ -17,8 +17,8 @@ limitations under the License.
package fuzzer package fuzzer
import ( import (
fuzz "github.com/google/gofuzz"
"k8s.io/sample-apiserver/pkg/apis/wardle" "k8s.io/sample-apiserver/pkg/apis/wardle"
"sigs.k8s.io/randfill"
runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer"
) )
@ -26,8 +26,8 @@ import (
// Funcs returns the fuzzer functions for the apps api group. // Funcs returns the fuzzer functions for the apps api group.
var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} { var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
return []interface{}{ return []interface{}{
func(s *wardle.FlunderSpec, c fuzz.Continue) { func(s *wardle.FlunderSpec, c randfill.Continue) {
c.FuzzNoCustom(s) // fuzz self without calling this function again c.FillNoCustom(s) // fuzz self without calling this function again
if len(s.FlunderReference) != 0 && len(s.FischerReference) != 0 { if len(s.FlunderReference) != 0 && len(s.FischerReference) != 0 {
s.FischerReference = "" s.FischerReference = ""

View File

@ -23,7 +23,7 @@ import (
"testing" "testing"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
fuzz "github.com/google/gofuzz" "sigs.k8s.io/randfill"
v1 "k8s.io/api/admission/v1" v1 "k8s.io/api/admission/v1"
"k8s.io/api/admission/v1beta1" "k8s.io/api/admission/v1beta1"
@ -38,7 +38,7 @@ func TestConvertAdmissionRequestToV1(t *testing.T) {
for i := 0; i < 100; i++ { for i := 0; i < 100; i++ {
t.Run(fmt.Sprintf("Run %d/100", i), func(t *testing.T) { t.Run(fmt.Sprintf("Run %d/100", i), func(t *testing.T) {
orig := &v1beta1.AdmissionRequest{} orig := &v1beta1.AdmissionRequest{}
f.Fuzz(orig) f.Fill(orig)
converted := convertAdmissionRequestToV1(orig) converted := convertAdmissionRequestToV1(orig)
rt := convertAdmissionRequestToV1beta1(converted) rt := convertAdmissionRequestToV1beta1(converted)
if !reflect.DeepEqual(orig, rt) { if !reflect.DeepEqual(orig, rt) {
@ -49,11 +49,11 @@ func TestConvertAdmissionRequestToV1(t *testing.T) {
} }
func TestConvertAdmissionResponseToV1beta1(t *testing.T) { func TestConvertAdmissionResponseToV1beta1(t *testing.T) {
f := fuzz.New() f := randfill.New()
for i := 0; i < 100; i++ { for i := 0; i < 100; i++ {
t.Run(fmt.Sprintf("Run %d/100", i), func(t *testing.T) { t.Run(fmt.Sprintf("Run %d/100", i), func(t *testing.T) {
orig := &v1.AdmissionResponse{} orig := &v1.AdmissionResponse{}
f.Fuzz(orig) f.Fill(orig)
converted := convertAdmissionResponseToV1beta1(orig) converted := convertAdmissionResponseToV1beta1(orig)
rt := convertAdmissionResponseToV1(converted) rt := convertAdmissionResponseToV1(converted)
if !reflect.DeepEqual(orig, rt) { if !reflect.DeepEqual(orig, rt) {

View File

@ -59,11 +59,11 @@ func doBench(b *testing.B, useUnstructured bool, shortCircuit bool) {
fuzzer.MaxDepth(1000).NilChance(0.2).NumElements(2, 15) fuzzer.MaxDepth(1000).NilChance(0.2).NumElements(2, 15)
pod := &v1.Pod{} pod := &v1.Pod{}
fuzzer.Fuzz(pod) fuzzer.Fill(pod)
fuzzer.NilChance(0.2).NumElements(10, 100).MaxDepth(10) fuzzer.NilChance(0.2).NumElements(10, 100).MaxDepth(10)
deployment := &v1.Endpoints{} deployment := &v1.Endpoints{}
fuzzer.Fuzz(deployment) fuzzer.Fill(deployment)
bts, err := json.Marshal(deployment) bts, err := json.Marshal(deployment)
require.NoError(b, err) require.NoError(b, err)