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.
This commit is contained in:
Kubernetes Submit Queue
2016-12-03 14:20:50 -08:00
committed by GitHub
4 changed files with 19 additions and 12 deletions

2
Godeps/Godeps.json generated
View File

@@ -1348,7 +1348,7 @@
},
{
"ImportPath": "github.com/google/gofuzz",
"Rev": "bbcb9da2d746f8bdbd6a936686a0a6067ada0ec5"
"Rev": "44d81051d367757e1c7c6a5a86423ece9afcf63c"
},
{
"ImportPath": "github.com/gorilla/context",

View File

@@ -45,7 +45,7 @@ import (
// FuzzerFor can randomly populate api objects that are destined for version.
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 {
f.RandSource(src)
}
@@ -153,10 +153,10 @@ func FuzzerFor(t *testing.T, version schema.GroupVersion, src rand.Source) *fuzz
} else {
rollingUpdate := extensions.RollingUpdateDeployment{}
if c.RandBool() {
rollingUpdate.MaxUnavailable = intstr.FromInt(int(c.RandUint64()))
rollingUpdate.MaxSurge = intstr.FromInt(int(c.RandUint64()))
rollingUpdate.MaxUnavailable = intstr.FromInt(int(c.Rand.Int31()))
rollingUpdate.MaxSurge = intstr.FromInt(int(c.Rand.Int31()))
} else {
rollingUpdate.MaxSurge = intstr.FromString(fmt.Sprintf("%d%%", c.RandUint64()))
rollingUpdate.MaxSurge = intstr.FromString(fmt.Sprintf("%d%%", c.Rand.Int31()))
}
j.RollingUpdate = &rollingUpdate
}

View File

@@ -14,21 +14,21 @@ This is useful for testing:
Import with ```import "github.com/google/gofuzz"```
You can use it on single variables:
```
```go
f := fuzz.New()
var myInt int
f.Fuzz(&myInt) // myInt gets a random value.
```
You can use it on maps:
```
```go
f := fuzz.New().NilChance(0).NumElements(1, 1)
var myMap map[ComplexKeyType]string
f.Fuzz(&myMap) // myMap will have exactly one element.
```
Customize the chance of getting a nil pointer:
```
```go
f := fuzz.New().NilChance(.5)
var fancyStruct struct {
A, B, C, D *string
@@ -37,7 +37,7 @@ f.Fuzz(&fancyStruct) // About half the pointers should be set.
```
You can even customize the randomization completely if needed:
```
```go
type MyEnum string
const (
A MyEnum = "A"

View File

@@ -129,7 +129,7 @@ func (f *Fuzzer) genElementCount() int {
if f.minElements == f.maxElements {
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 {
@@ -229,12 +229,19 @@ func (f *Fuzzer) doFuzz(v reflect.Value, flags uint64) {
return
}
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:
for i := 0; i < v.NumField(); i++ {
f.doFuzz(v.Field(i), 0)
}
case reflect.Array:
fallthrough
case reflect.Chan:
fallthrough
case reflect.Func: