Commit 723a200c authored by Kubernetes Submit Queue's avatar Kubernetes Submit Queue Committed by GitHub

Merge pull request #37823 from danwinship/better-fuzzing

Automatic merge from submit-queue (batch tested with PRs 38049, 37823, 38000, 36646) Test 0-length-arrays in fuzzing tests While hacking on #37289 I noticed that our fuzzing tests test nil slices and slices of length 1, but not slices of length 0, meaning we aren't testing that 0-length slices get treated the same as nil in all the places we expect them to (and in particular, we aren't ensuring that comparisons always use api.Semantic.DeepEqual rather than reflect.DeepEqual). (Though in fact, changing the fuzzer didn't turn up any bugs, so maybe this effectively gets tested somewhere else...) `fuzz.New().NilChance(.5).NumElements(0, 1)` means we end up generating `nil` 50% of the time, a length 0 array 25% of the time, and a length 1 array 25% of the time... maybe it should be `fuzz.New().NilChance(.33).NumElements(0, 1)` instead? The gofuzz rebase is to pull in https://github.com/google/gofuzz/pull/20, and the other fix is just a drive-by.
parents 07dd740a b684f73e
...@@ -1348,7 +1348,7 @@ ...@@ -1348,7 +1348,7 @@
}, },
{ {
"ImportPath": "github.com/google/gofuzz", "ImportPath": "github.com/google/gofuzz",
"Rev": "bbcb9da2d746f8bdbd6a936686a0a6067ada0ec5" "Rev": "44d81051d367757e1c7c6a5a86423ece9afcf63c"
}, },
{ {
"ImportPath": "github.com/gorilla/context", "ImportPath": "github.com/gorilla/context",
......
...@@ -45,7 +45,7 @@ import ( ...@@ -45,7 +45,7 @@ import (
// FuzzerFor can randomly populate api objects that are destined for version. // FuzzerFor can randomly populate api objects that are destined for version.
func FuzzerFor(t *testing.T, version schema.GroupVersion, src rand.Source) *fuzz.Fuzzer { func FuzzerFor(t *testing.T, version schema.GroupVersion, src rand.Source) *fuzz.Fuzzer {
f := fuzz.New().NilChance(.5).NumElements(1, 1) f := fuzz.New().NilChance(.5).NumElements(0, 1)
if src != nil { if src != nil {
f.RandSource(src) f.RandSource(src)
} }
...@@ -153,10 +153,10 @@ func FuzzerFor(t *testing.T, version schema.GroupVersion, src rand.Source) *fuzz ...@@ -153,10 +153,10 @@ func FuzzerFor(t *testing.T, version schema.GroupVersion, src rand.Source) *fuzz
} else { } else {
rollingUpdate := extensions.RollingUpdateDeployment{} rollingUpdate := extensions.RollingUpdateDeployment{}
if c.RandBool() { if c.RandBool() {
rollingUpdate.MaxUnavailable = intstr.FromInt(int(c.RandUint64())) rollingUpdate.MaxUnavailable = intstr.FromInt(int(c.Rand.Int31()))
rollingUpdate.MaxSurge = intstr.FromInt(int(c.RandUint64())) rollingUpdate.MaxSurge = intstr.FromInt(int(c.Rand.Int31()))
} else { } else {
rollingUpdate.MaxSurge = intstr.FromString(fmt.Sprintf("%d%%", c.RandUint64())) rollingUpdate.MaxSurge = intstr.FromString(fmt.Sprintf("%d%%", c.Rand.Int31()))
} }
j.RollingUpdate = &rollingUpdate j.RollingUpdate = &rollingUpdate
} }
......
...@@ -14,21 +14,21 @@ This is useful for testing: ...@@ -14,21 +14,21 @@ This is useful for testing:
Import with ```import "github.com/google/gofuzz"``` Import with ```import "github.com/google/gofuzz"```
You can use it on single variables: You can use it on single variables:
``` ```go
f := fuzz.New() f := fuzz.New()
var myInt int var myInt int
f.Fuzz(&myInt) // myInt gets a random value. f.Fuzz(&myInt) // myInt gets a random value.
``` ```
You can use it on maps: You can use it on maps:
``` ```go
f := fuzz.New().NilChance(0).NumElements(1, 1) f := fuzz.New().NilChance(0).NumElements(1, 1)
var myMap map[ComplexKeyType]string var myMap map[ComplexKeyType]string
f.Fuzz(&myMap) // myMap will have exactly one element. f.Fuzz(&myMap) // myMap will have exactly one element.
``` ```
Customize the chance of getting a nil pointer: Customize the chance of getting a nil pointer:
``` ```go
f := fuzz.New().NilChance(.5) f := fuzz.New().NilChance(.5)
var fancyStruct struct { var fancyStruct struct {
A, B, C, D *string A, B, C, D *string
...@@ -37,7 +37,7 @@ f.Fuzz(&fancyStruct) // About half the pointers should be set. ...@@ -37,7 +37,7 @@ f.Fuzz(&fancyStruct) // About half the pointers should be set.
``` ```
You can even customize the randomization completely if needed: You can even customize the randomization completely if needed:
``` ```go
type MyEnum string type MyEnum string
const ( const (
A MyEnum = "A" A MyEnum = "A"
......
...@@ -129,7 +129,7 @@ func (f *Fuzzer) genElementCount() int { ...@@ -129,7 +129,7 @@ func (f *Fuzzer) genElementCount() int {
if f.minElements == f.maxElements { if f.minElements == f.maxElements {
return f.minElements return f.minElements
} }
return f.minElements + f.r.Intn(f.maxElements-f.minElements) return f.minElements + f.r.Intn(f.maxElements-f.minElements+1)
} }
func (f *Fuzzer) genShouldFill() bool { func (f *Fuzzer) genShouldFill() bool {
...@@ -229,12 +229,19 @@ func (f *Fuzzer) doFuzz(v reflect.Value, flags uint64) { ...@@ -229,12 +229,19 @@ func (f *Fuzzer) doFuzz(v reflect.Value, flags uint64) {
return return
} }
v.Set(reflect.Zero(v.Type())) v.Set(reflect.Zero(v.Type()))
case reflect.Array:
if f.genShouldFill() {
n := v.Len()
for i := 0; i < n; i++ {
f.doFuzz(v.Index(i), 0)
}
return
}
v.Set(reflect.Zero(v.Type()))
case reflect.Struct: case reflect.Struct:
for i := 0; i < v.NumField(); i++ { for i := 0; i < v.NumField(); i++ {
f.doFuzz(v.Field(i), 0) f.doFuzz(v.Field(i), 0)
} }
case reflect.Array:
fallthrough
case reflect.Chan: case reflect.Chan:
fallthrough fallthrough
case reflect.Func: case reflect.Func:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment