Dep helper (#2151)

* Add dep task to update go dependencies

* Update go dependencies
This commit is contained in:
Manuel Alejandro de Brito Fontes
2018-09-29 19:47:07 -03:00
committed by Miek Gieben
parent 8f8b81f56b
commit 0e8977761d
764 changed files with 172 additions and 267451 deletions

View File

@@ -1,770 +0,0 @@
// Copyright 2014 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package btree
import (
"flag"
"fmt"
"math/rand"
"reflect"
"sort"
"sync"
"testing"
"time"
)
func init() {
seed := time.Now().Unix()
fmt.Println(seed)
rand.Seed(seed)
}
// perm returns a random permutation of n Int items in the range [0, n).
func perm(n int) (out []Item) {
for _, v := range rand.Perm(n) {
out = append(out, Int(v))
}
return
}
// rang returns an ordered list of Int items in the range [0, n).
func rang(n int) (out []Item) {
for i := 0; i < n; i++ {
out = append(out, Int(i))
}
return
}
// all extracts all items from a tree in order as a slice.
func all(t *BTree) (out []Item) {
t.Ascend(func(a Item) bool {
out = append(out, a)
return true
})
return
}
// rangerev returns a reversed ordered list of Int items in the range [0, n).
func rangrev(n int) (out []Item) {
for i := n - 1; i >= 0; i-- {
out = append(out, Int(i))
}
return
}
// allrev extracts all items from a tree in reverse order as a slice.
func allrev(t *BTree) (out []Item) {
t.Descend(func(a Item) bool {
out = append(out, a)
return true
})
return
}
var btreeDegree = flag.Int("degree", 32, "B-Tree degree")
func TestBTree(t *testing.T) {
tr := New(*btreeDegree)
const treeSize = 10000
for i := 0; i < 10; i++ {
if min := tr.Min(); min != nil {
t.Fatalf("empty min, got %+v", min)
}
if max := tr.Max(); max != nil {
t.Fatalf("empty max, got %+v", max)
}
for _, item := range perm(treeSize) {
if x := tr.ReplaceOrInsert(item); x != nil {
t.Fatal("insert found item", item)
}
}
for _, item := range perm(treeSize) {
if x := tr.ReplaceOrInsert(item); x == nil {
t.Fatal("insert didn't find item", item)
}
}
if min, want := tr.Min(), Item(Int(0)); min != want {
t.Fatalf("min: want %+v, got %+v", want, min)
}
if max, want := tr.Max(), Item(Int(treeSize-1)); max != want {
t.Fatalf("max: want %+v, got %+v", want, max)
}
got := all(tr)
want := rang(treeSize)
if !reflect.DeepEqual(got, want) {
t.Fatalf("mismatch:\n got: %v\nwant: %v", got, want)
}
gotrev := allrev(tr)
wantrev := rangrev(treeSize)
if !reflect.DeepEqual(gotrev, wantrev) {
t.Fatalf("mismatch:\n got: %v\nwant: %v", got, want)
}
for _, item := range perm(treeSize) {
if x := tr.Delete(item); x == nil {
t.Fatalf("didn't find %v", item)
}
}
if got = all(tr); len(got) > 0 {
t.Fatalf("some left!: %v", got)
}
}
}
func ExampleBTree() {
tr := New(*btreeDegree)
for i := Int(0); i < 10; i++ {
tr.ReplaceOrInsert(i)
}
fmt.Println("len: ", tr.Len())
fmt.Println("get3: ", tr.Get(Int(3)))
fmt.Println("get100: ", tr.Get(Int(100)))
fmt.Println("del4: ", tr.Delete(Int(4)))
fmt.Println("del100: ", tr.Delete(Int(100)))
fmt.Println("replace5: ", tr.ReplaceOrInsert(Int(5)))
fmt.Println("replace100:", tr.ReplaceOrInsert(Int(100)))
fmt.Println("min: ", tr.Min())
fmt.Println("delmin: ", tr.DeleteMin())
fmt.Println("max: ", tr.Max())
fmt.Println("delmax: ", tr.DeleteMax())
fmt.Println("len: ", tr.Len())
// Output:
// len: 10
// get3: 3
// get100: <nil>
// del4: 4
// del100: <nil>
// replace5: 5
// replace100: <nil>
// min: 0
// delmin: 0
// max: 100
// delmax: 100
// len: 8
}
func TestDeleteMin(t *testing.T) {
tr := New(3)
for _, v := range perm(100) {
tr.ReplaceOrInsert(v)
}
var got []Item
for v := tr.DeleteMin(); v != nil; v = tr.DeleteMin() {
got = append(got, v)
}
if want := rang(100); !reflect.DeepEqual(got, want) {
t.Fatalf("ascendrange:\n got: %v\nwant: %v", got, want)
}
}
func TestDeleteMax(t *testing.T) {
tr := New(3)
for _, v := range perm(100) {
tr.ReplaceOrInsert(v)
}
var got []Item
for v := tr.DeleteMax(); v != nil; v = tr.DeleteMax() {
got = append(got, v)
}
// Reverse our list.
for i := 0; i < len(got)/2; i++ {
got[i], got[len(got)-i-1] = got[len(got)-i-1], got[i]
}
if want := rang(100); !reflect.DeepEqual(got, want) {
t.Fatalf("ascendrange:\n got: %v\nwant: %v", got, want)
}
}
func TestAscendRange(t *testing.T) {
tr := New(2)
for _, v := range perm(100) {
tr.ReplaceOrInsert(v)
}
var got []Item
tr.AscendRange(Int(40), Int(60), func(a Item) bool {
got = append(got, a)
return true
})
if want := rang(100)[40:60]; !reflect.DeepEqual(got, want) {
t.Fatalf("ascendrange:\n got: %v\nwant: %v", got, want)
}
got = got[:0]
tr.AscendRange(Int(40), Int(60), func(a Item) bool {
if a.(Int) > 50 {
return false
}
got = append(got, a)
return true
})
if want := rang(100)[40:51]; !reflect.DeepEqual(got, want) {
t.Fatalf("ascendrange:\n got: %v\nwant: %v", got, want)
}
}
func TestDescendRange(t *testing.T) {
tr := New(2)
for _, v := range perm(100) {
tr.ReplaceOrInsert(v)
}
var got []Item
tr.DescendRange(Int(60), Int(40), func(a Item) bool {
got = append(got, a)
return true
})
if want := rangrev(100)[39:59]; !reflect.DeepEqual(got, want) {
t.Fatalf("descendrange:\n got: %v\nwant: %v", got, want)
}
got = got[:0]
tr.DescendRange(Int(60), Int(40), func(a Item) bool {
if a.(Int) < 50 {
return false
}
got = append(got, a)
return true
})
if want := rangrev(100)[39:50]; !reflect.DeepEqual(got, want) {
t.Fatalf("descendrange:\n got: %v\nwant: %v", got, want)
}
}
func TestAscendLessThan(t *testing.T) {
tr := New(*btreeDegree)
for _, v := range perm(100) {
tr.ReplaceOrInsert(v)
}
var got []Item
tr.AscendLessThan(Int(60), func(a Item) bool {
got = append(got, a)
return true
})
if want := rang(100)[:60]; !reflect.DeepEqual(got, want) {
t.Fatalf("ascendrange:\n got: %v\nwant: %v", got, want)
}
got = got[:0]
tr.AscendLessThan(Int(60), func(a Item) bool {
if a.(Int) > 50 {
return false
}
got = append(got, a)
return true
})
if want := rang(100)[:51]; !reflect.DeepEqual(got, want) {
t.Fatalf("ascendrange:\n got: %v\nwant: %v", got, want)
}
}
func TestDescendLessOrEqual(t *testing.T) {
tr := New(*btreeDegree)
for _, v := range perm(100) {
tr.ReplaceOrInsert(v)
}
var got []Item
tr.DescendLessOrEqual(Int(40), func(a Item) bool {
got = append(got, a)
return true
})
if want := rangrev(100)[59:]; !reflect.DeepEqual(got, want) {
t.Fatalf("descendlessorequal:\n got: %v\nwant: %v", got, want)
}
got = got[:0]
tr.DescendLessOrEqual(Int(60), func(a Item) bool {
if a.(Int) < 50 {
return false
}
got = append(got, a)
return true
})
if want := rangrev(100)[39:50]; !reflect.DeepEqual(got, want) {
t.Fatalf("descendlessorequal:\n got: %v\nwant: %v", got, want)
}
}
func TestAscendGreaterOrEqual(t *testing.T) {
tr := New(*btreeDegree)
for _, v := range perm(100) {
tr.ReplaceOrInsert(v)
}
var got []Item
tr.AscendGreaterOrEqual(Int(40), func(a Item) bool {
got = append(got, a)
return true
})
if want := rang(100)[40:]; !reflect.DeepEqual(got, want) {
t.Fatalf("ascendrange:\n got: %v\nwant: %v", got, want)
}
got = got[:0]
tr.AscendGreaterOrEqual(Int(40), func(a Item) bool {
if a.(Int) > 50 {
return false
}
got = append(got, a)
return true
})
if want := rang(100)[40:51]; !reflect.DeepEqual(got, want) {
t.Fatalf("ascendrange:\n got: %v\nwant: %v", got, want)
}
}
func TestDescendGreaterThan(t *testing.T) {
tr := New(*btreeDegree)
for _, v := range perm(100) {
tr.ReplaceOrInsert(v)
}
var got []Item
tr.DescendGreaterThan(Int(40), func(a Item) bool {
got = append(got, a)
return true
})
if want := rangrev(100)[:59]; !reflect.DeepEqual(got, want) {
t.Fatalf("descendgreaterthan:\n got: %v\nwant: %v", got, want)
}
got = got[:0]
tr.DescendGreaterThan(Int(40), func(a Item) bool {
if a.(Int) < 50 {
return false
}
got = append(got, a)
return true
})
if want := rangrev(100)[:50]; !reflect.DeepEqual(got, want) {
t.Fatalf("descendgreaterthan:\n got: %v\nwant: %v", got, want)
}
}
const benchmarkTreeSize = 10000
func BenchmarkInsert(b *testing.B) {
b.StopTimer()
insertP := perm(benchmarkTreeSize)
b.StartTimer()
i := 0
for i < b.N {
tr := New(*btreeDegree)
for _, item := range insertP {
tr.ReplaceOrInsert(item)
i++
if i >= b.N {
return
}
}
}
}
func BenchmarkDeleteInsert(b *testing.B) {
b.StopTimer()
insertP := perm(benchmarkTreeSize)
tr := New(*btreeDegree)
for _, item := range insertP {
tr.ReplaceOrInsert(item)
}
b.StartTimer()
for i := 0; i < b.N; i++ {
tr.Delete(insertP[i%benchmarkTreeSize])
tr.ReplaceOrInsert(insertP[i%benchmarkTreeSize])
}
}
func BenchmarkDeleteInsertCloneOnce(b *testing.B) {
b.StopTimer()
insertP := perm(benchmarkTreeSize)
tr := New(*btreeDegree)
for _, item := range insertP {
tr.ReplaceOrInsert(item)
}
tr = tr.Clone()
b.StartTimer()
for i := 0; i < b.N; i++ {
tr.Delete(insertP[i%benchmarkTreeSize])
tr.ReplaceOrInsert(insertP[i%benchmarkTreeSize])
}
}
func BenchmarkDeleteInsertCloneEachTime(b *testing.B) {
b.StopTimer()
insertP := perm(benchmarkTreeSize)
tr := New(*btreeDegree)
for _, item := range insertP {
tr.ReplaceOrInsert(item)
}
b.StartTimer()
for i := 0; i < b.N; i++ {
tr = tr.Clone()
tr.Delete(insertP[i%benchmarkTreeSize])
tr.ReplaceOrInsert(insertP[i%benchmarkTreeSize])
}
}
func BenchmarkDelete(b *testing.B) {
b.StopTimer()
insertP := perm(benchmarkTreeSize)
removeP := perm(benchmarkTreeSize)
b.StartTimer()
i := 0
for i < b.N {
b.StopTimer()
tr := New(*btreeDegree)
for _, v := range insertP {
tr.ReplaceOrInsert(v)
}
b.StartTimer()
for _, item := range removeP {
tr.Delete(item)
i++
if i >= b.N {
return
}
}
if tr.Len() > 0 {
panic(tr.Len())
}
}
}
func BenchmarkGet(b *testing.B) {
b.StopTimer()
insertP := perm(benchmarkTreeSize)
removeP := perm(benchmarkTreeSize)
b.StartTimer()
i := 0
for i < b.N {
b.StopTimer()
tr := New(*btreeDegree)
for _, v := range insertP {
tr.ReplaceOrInsert(v)
}
b.StartTimer()
for _, item := range removeP {
tr.Get(item)
i++
if i >= b.N {
return
}
}
}
}
func BenchmarkGetCloneEachTime(b *testing.B) {
b.StopTimer()
insertP := perm(benchmarkTreeSize)
removeP := perm(benchmarkTreeSize)
b.StartTimer()
i := 0
for i < b.N {
b.StopTimer()
tr := New(*btreeDegree)
for _, v := range insertP {
tr.ReplaceOrInsert(v)
}
b.StartTimer()
for _, item := range removeP {
tr = tr.Clone()
tr.Get(item)
i++
if i >= b.N {
return
}
}
}
}
type byInts []Item
func (a byInts) Len() int {
return len(a)
}
func (a byInts) Less(i, j int) bool {
return a[i].(Int) < a[j].(Int)
}
func (a byInts) Swap(i, j int) {
a[i], a[j] = a[j], a[i]
}
func BenchmarkAscend(b *testing.B) {
arr := perm(benchmarkTreeSize)
tr := New(*btreeDegree)
for _, v := range arr {
tr.ReplaceOrInsert(v)
}
sort.Sort(byInts(arr))
b.ResetTimer()
for i := 0; i < b.N; i++ {
j := 0
tr.Ascend(func(item Item) bool {
if item.(Int) != arr[j].(Int) {
b.Fatalf("mismatch: expected: %v, got %v", arr[j].(Int), item.(Int))
}
j++
return true
})
}
}
func BenchmarkDescend(b *testing.B) {
arr := perm(benchmarkTreeSize)
tr := New(*btreeDegree)
for _, v := range arr {
tr.ReplaceOrInsert(v)
}
sort.Sort(byInts(arr))
b.ResetTimer()
for i := 0; i < b.N; i++ {
j := len(arr) - 1
tr.Descend(func(item Item) bool {
if item.(Int) != arr[j].(Int) {
b.Fatalf("mismatch: expected: %v, got %v", arr[j].(Int), item.(Int))
}
j--
return true
})
}
}
func BenchmarkAscendRange(b *testing.B) {
arr := perm(benchmarkTreeSize)
tr := New(*btreeDegree)
for _, v := range arr {
tr.ReplaceOrInsert(v)
}
sort.Sort(byInts(arr))
b.ResetTimer()
for i := 0; i < b.N; i++ {
j := 100
tr.AscendRange(Int(100), arr[len(arr)-100], func(item Item) bool {
if item.(Int) != arr[j].(Int) {
b.Fatalf("mismatch: expected: %v, got %v", arr[j].(Int), item.(Int))
}
j++
return true
})
if j != len(arr)-100 {
b.Fatalf("expected: %v, got %v", len(arr)-100, j)
}
}
}
func BenchmarkDescendRange(b *testing.B) {
arr := perm(benchmarkTreeSize)
tr := New(*btreeDegree)
for _, v := range arr {
tr.ReplaceOrInsert(v)
}
sort.Sort(byInts(arr))
b.ResetTimer()
for i := 0; i < b.N; i++ {
j := len(arr) - 100
tr.DescendRange(arr[len(arr)-100], Int(100), func(item Item) bool {
if item.(Int) != arr[j].(Int) {
b.Fatalf("mismatch: expected: %v, got %v", arr[j].(Int), item.(Int))
}
j--
return true
})
if j != 100 {
b.Fatalf("expected: %v, got %v", len(arr)-100, j)
}
}
}
func BenchmarkAscendGreaterOrEqual(b *testing.B) {
arr := perm(benchmarkTreeSize)
tr := New(*btreeDegree)
for _, v := range arr {
tr.ReplaceOrInsert(v)
}
sort.Sort(byInts(arr))
b.ResetTimer()
for i := 0; i < b.N; i++ {
j := 100
k := 0
tr.AscendGreaterOrEqual(Int(100), func(item Item) bool {
if item.(Int) != arr[j].(Int) {
b.Fatalf("mismatch: expected: %v, got %v", arr[j].(Int), item.(Int))
}
j++
k++
return true
})
if j != len(arr) {
b.Fatalf("expected: %v, got %v", len(arr), j)
}
if k != len(arr)-100 {
b.Fatalf("expected: %v, got %v", len(arr)-100, k)
}
}
}
func BenchmarkDescendLessOrEqual(b *testing.B) {
arr := perm(benchmarkTreeSize)
tr := New(*btreeDegree)
for _, v := range arr {
tr.ReplaceOrInsert(v)
}
sort.Sort(byInts(arr))
b.ResetTimer()
for i := 0; i < b.N; i++ {
j := len(arr) - 100
k := len(arr)
tr.DescendLessOrEqual(arr[len(arr)-100], func(item Item) bool {
if item.(Int) != arr[j].(Int) {
b.Fatalf("mismatch: expected: %v, got %v", arr[j].(Int), item.(Int))
}
j--
k--
return true
})
if j != -1 {
b.Fatalf("expected: %v, got %v", -1, j)
}
if k != 99 {
b.Fatalf("expected: %v, got %v", 99, k)
}
}
}
const cloneTestSize = 10000
func cloneTest(t *testing.T, b *BTree, start int, p []Item, wg *sync.WaitGroup, trees *[]*BTree) {
t.Logf("Starting new clone at %v", start)
*trees = append(*trees, b)
for i := start; i < cloneTestSize; i++ {
b.ReplaceOrInsert(p[i])
if i%(cloneTestSize/5) == 0 {
wg.Add(1)
go cloneTest(t, b.Clone(), i+1, p, wg, trees)
}
}
wg.Done()
}
func TestCloneConcurrentOperations(t *testing.T) {
b := New(*btreeDegree)
trees := []*BTree{}
p := perm(cloneTestSize)
var wg sync.WaitGroup
wg.Add(1)
go cloneTest(t, b, 0, p, &wg, &trees)
wg.Wait()
want := rang(cloneTestSize)
t.Logf("Starting equality checks on %d trees", len(trees))
for i, tree := range trees {
if !reflect.DeepEqual(want, all(tree)) {
t.Errorf("tree %v mismatch", i)
}
}
t.Log("Removing half from first half")
toRemove := rang(cloneTestSize)[cloneTestSize/2:]
for i := 0; i < len(trees)/2; i++ {
tree := trees[i]
wg.Add(1)
go func() {
for _, item := range toRemove {
tree.Delete(item)
}
wg.Done()
}()
}
wg.Wait()
t.Log("Checking all values again")
for i, tree := range trees {
var wantpart []Item
if i < len(trees)/2 {
wantpart = want[:cloneTestSize/2]
} else {
wantpart = want
}
if got := all(tree); !reflect.DeepEqual(wantpart, got) {
t.Errorf("tree %v mismatch, want %v got %v", i, len(want), len(got))
}
}
}
func BenchmarkDeleteAndRestore(b *testing.B) {
items := perm(16392)
b.ResetTimer()
b.Run(`CopyBigFreeList`, func(b *testing.B) {
fl := NewFreeList(16392)
tr := NewWithFreeList(*btreeDegree, fl)
for _, v := range items {
tr.ReplaceOrInsert(v)
}
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
dels := make([]Item, 0, tr.Len())
tr.Ascend(ItemIterator(func(b Item) bool {
dels = append(dels, b)
return true
}))
for _, del := range dels {
tr.Delete(del)
}
// tr is now empty, we make a new empty copy of it.
tr = NewWithFreeList(*btreeDegree, fl)
for _, v := range items {
tr.ReplaceOrInsert(v)
}
}
})
b.Run(`Copy`, func(b *testing.B) {
tr := New(*btreeDegree)
for _, v := range items {
tr.ReplaceOrInsert(v)
}
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
dels := make([]Item, 0, tr.Len())
tr.Ascend(ItemIterator(func(b Item) bool {
dels = append(dels, b)
return true
}))
for _, del := range dels {
tr.Delete(del)
}
// tr is now empty, we make a new empty copy of it.
tr = New(*btreeDegree)
for _, v := range items {
tr.ReplaceOrInsert(v)
}
}
})
b.Run(`ClearBigFreelist`, func(b *testing.B) {
fl := NewFreeList(16392)
tr := NewWithFreeList(*btreeDegree, fl)
for _, v := range items {
tr.ReplaceOrInsert(v)
}
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
tr.Clear(true)
for _, v := range items {
tr.ReplaceOrInsert(v)
}
}
})
b.Run(`Clear`, func(b *testing.B) {
tr := New(*btreeDegree)
for _, v := range items {
tr.ReplaceOrInsert(v)
}
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
tr.Clear(true)
for _, v := range items {
tr.ReplaceOrInsert(v)
}
}
})
}

View File

@@ -1,225 +0,0 @@
/*
Copyright 2014 Google Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package fuzz_test
import (
"encoding/json"
"fmt"
"math/rand"
"github.com/google/gofuzz"
)
func ExampleSimple() {
type MyType struct {
A string
B string
C int
D struct {
E float64
}
}
f := fuzz.New()
object := MyType{}
uniqueObjects := map[MyType]int{}
for i := 0; i < 1000; i++ {
f.Fuzz(&object)
uniqueObjects[object]++
}
fmt.Printf("Got %v unique objects.\n", len(uniqueObjects))
// Output:
// Got 1000 unique objects.
}
func ExampleCustom() {
type MyType struct {
A int
B string
}
counter := 0
f := fuzz.New().Funcs(
func(i *int, c fuzz.Continue) {
*i = counter
counter++
},
)
object := MyType{}
uniqueObjects := map[MyType]int{}
for i := 0; i < 100; i++ {
f.Fuzz(&object)
if object.A != i {
fmt.Printf("Unexpected value: %#v\n", object)
}
uniqueObjects[object]++
}
fmt.Printf("Got %v unique objects.\n", len(uniqueObjects))
// Output:
// Got 100 unique objects.
}
func ExampleComplex() {
type OtherType struct {
A string
B string
}
type MyType struct {
Pointer *OtherType
Map map[string]OtherType
PointerMap *map[string]OtherType
Slice []OtherType
SlicePointer []*OtherType
PointerSlicePointer *[]*OtherType
}
f := fuzz.New().RandSource(rand.NewSource(0)).NilChance(0).NumElements(1, 1).Funcs(
func(o *OtherType, c fuzz.Continue) {
o.A = "Foo"
o.B = "Bar"
},
func(op **OtherType, c fuzz.Continue) {
*op = &OtherType{"A", "B"}
},
func(m map[string]OtherType, c fuzz.Continue) {
m["Works Because"] = OtherType{
"Fuzzer",
"Preallocated",
}
},
)
object := MyType{}
f.Fuzz(&object)
bytes, err := json.MarshalIndent(&object, "", " ")
if err != nil {
fmt.Printf("error: %v\n", err)
}
fmt.Printf("%s\n", string(bytes))
// Output:
// {
// "Pointer": {
// "A": "A",
// "B": "B"
// },
// "Map": {
// "Works Because": {
// "A": "Fuzzer",
// "B": "Preallocated"
// }
// },
// "PointerMap": {
// "Works Because": {
// "A": "Fuzzer",
// "B": "Preallocated"
// }
// },
// "Slice": [
// {
// "A": "Foo",
// "B": "Bar"
// }
// ],
// "SlicePointer": [
// {
// "A": "A",
// "B": "B"
// }
// ],
// "PointerSlicePointer": [
// {
// "A": "A",
// "B": "B"
// }
// ]
// }
}
func ExampleMap() {
f := fuzz.New().NilChance(0).NumElements(1, 1)
var myMap map[struct{ A, B, C int }]string
f.Fuzz(&myMap)
fmt.Printf("myMap has %v element(s).\n", len(myMap))
// Output:
// myMap has 1 element(s).
}
func ExampleSingle() {
f := fuzz.New()
var i int
f.Fuzz(&i)
// Technically, we'd expect this to fail one out of 2 billion attempts...
fmt.Printf("(i == 0) == %v", i == 0)
// Output:
// (i == 0) == false
}
func ExampleEnum() {
type MyEnum string
const (
A MyEnum = "A"
B MyEnum = "B"
)
type MyInfo struct {
Type MyEnum
AInfo *string
BInfo *string
}
f := fuzz.New().NilChance(0).Funcs(
func(e *MyInfo, c fuzz.Continue) {
// Note c's embedded Rand allows for direct use.
// We could also use c.RandBool() here.
switch c.Intn(2) {
case 0:
e.Type = A
c.Fuzz(&e.AInfo)
case 1:
e.Type = B
c.Fuzz(&e.BInfo)
}
},
)
for i := 0; i < 100; i++ {
var myObject MyInfo
f.Fuzz(&myObject)
switch myObject.Type {
case A:
if myObject.AInfo == nil {
fmt.Println("AInfo should have been set!")
}
if myObject.BInfo != nil {
fmt.Println("BInfo should NOT have been set!")
}
case B:
if myObject.BInfo == nil {
fmt.Println("BInfo should have been set!")
}
if myObject.AInfo != nil {
fmt.Println("AInfo should NOT have been set!")
}
default:
fmt.Println("Invalid enum value!")
}
}
// Output:
}

View File

@@ -1,472 +0,0 @@
/*
Copyright 2014 Google Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package fuzz
import (
"reflect"
"testing"
"time"
)
func TestFuzz_basic(t *testing.T) {
obj := &struct {
I int
I8 int8
I16 int16
I32 int32
I64 int64
U uint
U8 uint8
U16 uint16
U32 uint32
U64 uint64
Uptr uintptr
S string
B bool
T time.Time
}{}
failed := map[string]int{}
for i := 0; i < 10; i++ {
New().Fuzz(obj)
if n, v := "i", obj.I; v == 0 {
failed[n] = failed[n] + 1
}
if n, v := "i8", obj.I8; v == 0 {
failed[n] = failed[n] + 1
}
if n, v := "i16", obj.I16; v == 0 {
failed[n] = failed[n] + 1
}
if n, v := "i32", obj.I32; v == 0 {
failed[n] = failed[n] + 1
}
if n, v := "i64", obj.I64; v == 0 {
failed[n] = failed[n] + 1
}
if n, v := "u", obj.U; v == 0 {
failed[n] = failed[n] + 1
}
if n, v := "u8", obj.U8; v == 0 {
failed[n] = failed[n] + 1
}
if n, v := "u16", obj.U16; v == 0 {
failed[n] = failed[n] + 1
}
if n, v := "u32", obj.U32; v == 0 {
failed[n] = failed[n] + 1
}
if n, v := "u64", obj.U64; v == 0 {
failed[n] = failed[n] + 1
}
if n, v := "uptr", obj.Uptr; v == 0 {
failed[n] = failed[n] + 1
}
if n, v := "s", obj.S; v == "" {
failed[n] = failed[n] + 1
}
if n, v := "b", obj.B; v == false {
failed[n] = failed[n] + 1
}
if n, v := "t", obj.T; v.IsZero() {
failed[n] = failed[n] + 1
}
}
checkFailed(t, failed)
}
func checkFailed(t *testing.T, failed map[string]int) {
for k, v := range failed {
if v > 8 {
t.Errorf("%v seems to not be getting set, was zero value %v times", k, v)
}
}
}
func TestFuzz_structptr(t *testing.T) {
obj := &struct {
A *struct {
S string
}
}{}
f := New().NilChance(.5)
failed := map[string]int{}
for i := 0; i < 10; i++ {
f.Fuzz(obj)
if n, v := "a not nil", obj.A; v == nil {
failed[n] = failed[n] + 1
}
if n, v := "a nil", obj.A; v != nil {
failed[n] = failed[n] + 1
}
if n, v := "as", obj.A; v == nil || v.S == "" {
failed[n] = failed[n] + 1
}
}
checkFailed(t, failed)
}
// tryFuzz tries fuzzing up to 20 times. Fail if check() never passes, report the highest
// stage it ever got to.
func tryFuzz(t *testing.T, f *Fuzzer, obj interface{}, check func() (stage int, passed bool)) {
maxStage := 0
for i := 0; i < 20; i++ {
f.Fuzz(obj)
stage, passed := check()
if stage > maxStage {
maxStage = stage
}
if passed {
return
}
}
t.Errorf("Only ever got to stage %v", maxStage)
}
func TestFuzz_structmap(t *testing.T) {
obj := &struct {
A map[struct {
S string
}]struct {
S2 string
}
B map[string]string
}{}
tryFuzz(t, New(), obj, func() (int, bool) {
if obj.A == nil {
return 1, false
}
if len(obj.A) == 0 {
return 2, false
}
for k, v := range obj.A {
if k.S == "" {
return 3, false
}
if v.S2 == "" {
return 4, false
}
}
if obj.B == nil {
return 5, false
}
if len(obj.B) == 0 {
return 6, false
}
for k, v := range obj.B {
if k == "" {
return 7, false
}
if v == "" {
return 8, false
}
}
return 9, true
})
}
func TestFuzz_structslice(t *testing.T) {
obj := &struct {
A []struct {
S string
}
B []string
}{}
tryFuzz(t, New(), obj, func() (int, bool) {
if obj.A == nil {
return 1, false
}
if len(obj.A) == 0 {
return 2, false
}
for _, v := range obj.A {
if v.S == "" {
return 3, false
}
}
if obj.B == nil {
return 4, false
}
if len(obj.B) == 0 {
return 5, false
}
for _, v := range obj.B {
if v == "" {
return 6, false
}
}
return 7, true
})
}
func TestFuzz_structarray(t *testing.T) {
obj := &struct {
A [3]struct {
S string
}
B [2]int
}{}
tryFuzz(t, New(), obj, func() (int, bool) {
for _, v := range obj.A {
if v.S == "" {
return 1, false
}
}
for _, v := range obj.B {
if v == 0 {
return 2, false
}
}
return 3, true
})
}
func TestFuzz_custom(t *testing.T) {
obj := &struct {
A string
B *string
C map[string]string
D *map[string]string
}{}
testPhrase := "gotcalled"
testMap := map[string]string{"C": "D"}
f := New().Funcs(
func(s *string, c Continue) {
*s = testPhrase
},
func(m map[string]string, c Continue) {
m["C"] = "D"
},
)
tryFuzz(t, f, obj, func() (int, bool) {
if obj.A != testPhrase {
return 1, false
}
if obj.B == nil {
return 2, false
}
if *obj.B != testPhrase {
return 3, false
}
if e, a := testMap, obj.C; !reflect.DeepEqual(e, a) {
return 4, false
}
if obj.D == nil {
return 5, false
}
if e, a := testMap, *obj.D; !reflect.DeepEqual(e, a) {
return 6, false
}
return 7, true
})
}
type SelfFuzzer string
// Implement fuzz.Interface.
func (sf *SelfFuzzer) Fuzz(c Continue) {
*sf = selfFuzzerTestPhrase
}
const selfFuzzerTestPhrase = "was fuzzed"
func TestFuzz_interface(t *testing.T) {
f := New()
var obj1 SelfFuzzer
tryFuzz(t, f, &obj1, func() (int, bool) {
if obj1 != selfFuzzerTestPhrase {
return 1, false
}
return 1, true
})
var obj2 map[int]SelfFuzzer
tryFuzz(t, f, &obj2, func() (int, bool) {
for _, v := range obj2 {
if v != selfFuzzerTestPhrase {
return 1, false
}
}
return 1, true
})
}
func TestFuzz_interfaceAndFunc(t *testing.T) {
const privateTestPhrase = "private phrase"
f := New().Funcs(
// This should take precedence over SelfFuzzer.Fuzz().
func(s *SelfFuzzer, c Continue) {
*s = privateTestPhrase
},
)
var obj1 SelfFuzzer
tryFuzz(t, f, &obj1, func() (int, bool) {
if obj1 != privateTestPhrase {
return 1, false
}
return 1, true
})
var obj2 map[int]SelfFuzzer
tryFuzz(t, f, &obj2, func() (int, bool) {
for _, v := range obj2 {
if v != privateTestPhrase {
return 1, false
}
}
return 1, true
})
}
func TestFuzz_noCustom(t *testing.T) {
type Inner struct {
Str string
}
type Outer struct {
Str string
In Inner
}
testPhrase := "gotcalled"
f := New().Funcs(
func(outer *Outer, c Continue) {
outer.Str = testPhrase
c.Fuzz(&outer.In)
},
func(inner *Inner, c Continue) {
inner.Str = testPhrase
},
)
c := Continue{fc: &fuzzerContext{fuzzer: f}, Rand: f.r}
// Fuzzer.Fuzz()
obj1 := Outer{}
f.Fuzz(&obj1)
if obj1.Str != testPhrase {
t.Errorf("expected Outer custom function to have been called")
}
if obj1.In.Str != testPhrase {
t.Errorf("expected Inner custom function to have been called")
}
// Continue.Fuzz()
obj2 := Outer{}
c.Fuzz(&obj2)
if obj2.Str != testPhrase {
t.Errorf("expected Outer custom function to have been called")
}
if obj2.In.Str != testPhrase {
t.Errorf("expected Inner custom function to have been called")
}
// Fuzzer.FuzzNoCustom()
obj3 := Outer{}
f.FuzzNoCustom(&obj3)
if obj3.Str == testPhrase {
t.Errorf("expected Outer custom function to not have been called")
}
if obj3.In.Str != testPhrase {
t.Errorf("expected Inner custom function to have been called")
}
// Continue.FuzzNoCustom()
obj4 := Outer{}
c.FuzzNoCustom(&obj4)
if obj4.Str == testPhrase {
t.Errorf("expected Outer custom function to not have been called")
}
if obj4.In.Str != testPhrase {
t.Errorf("expected Inner custom function to have been called")
}
}
func TestFuzz_NumElements(t *testing.T) {
f := New().NilChance(0).NumElements(0, 1)
obj := &struct {
A []int
}{}
tryFuzz(t, f, obj, func() (int, bool) {
if obj.A == nil {
return 1, false
}
return 2, len(obj.A) == 0
})
tryFuzz(t, f, obj, func() (int, bool) {
if obj.A == nil {
return 3, false
}
return 4, len(obj.A) == 1
})
}
func TestFuzz_Maxdepth(t *testing.T) {
type S struct {
S *S
}
f := New().NilChance(0)
f.MaxDepth(1)
for i := 0; i < 100; i++ {
obj := S{}
f.Fuzz(&obj)
if obj.S != nil {
t.Errorf("Expected nil")
}
}
f.MaxDepth(3) // field, ptr
for i := 0; i < 100; i++ {
obj := S{}
f.Fuzz(&obj)
if obj.S == nil {
t.Errorf("Expected obj.S not nil")
} else if obj.S.S != nil {
t.Errorf("Expected obj.S.S nil")
}
}
f.MaxDepth(5) // field, ptr, field, ptr
for i := 0; i < 100; i++ {
obj := S{}
f.Fuzz(&obj)
if obj.S == nil {
t.Errorf("Expected obj.S not nil")
} else if obj.S.S == nil {
t.Errorf("Expected obj.S.S not nil")
} else if obj.S.S.S != nil {
t.Errorf("Expected obj.S.S.S nil")
}
}
}