1/* 2Copyright 2014 Google Inc. All rights reserved. 3 4Licensed under the Apache License, Version 2.0 (the "License"); 5you may not use this file except in compliance with the License. 6You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10Unless required by applicable law or agreed to in writing, software 11distributed under the License is distributed on an "AS IS" BASIS, 12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13See the License for the specific language governing permissions and 14limitations under the License. 15*/ 16 17package fuzz_test 18 19import ( 20 "encoding/json" 21 "fmt" 22 "math/rand" 23 24 "github.com/google/gofuzz" 25) 26 27func ExampleSimple() { 28 type MyType struct { 29 A string 30 B string 31 C int 32 D struct { 33 E float64 34 } 35 } 36 37 f := fuzz.New() 38 object := MyType{} 39 40 uniqueObjects := map[MyType]int{} 41 42 for i := 0; i < 1000; i++ { 43 f.Fuzz(&object) 44 uniqueObjects[object]++ 45 } 46 fmt.Printf("Got %v unique objects.\n", len(uniqueObjects)) 47 // Output: 48 // Got 1000 unique objects. 49} 50 51func ExampleCustom() { 52 type MyType struct { 53 A int 54 B string 55 } 56 57 counter := 0 58 f := fuzz.New().Funcs( 59 func(i *int, c fuzz.Continue) { 60 *i = counter 61 counter++ 62 }, 63 ) 64 object := MyType{} 65 66 uniqueObjects := map[MyType]int{} 67 68 for i := 0; i < 100; i++ { 69 f.Fuzz(&object) 70 if object.A != i { 71 fmt.Printf("Unexpected value: %#v\n", object) 72 } 73 uniqueObjects[object]++ 74 } 75 fmt.Printf("Got %v unique objects.\n", len(uniqueObjects)) 76 // Output: 77 // Got 100 unique objects. 78} 79 80func ExampleComplex() { 81 type OtherType struct { 82 A string 83 B string 84 } 85 type MyType struct { 86 Pointer *OtherType 87 Map map[string]OtherType 88 PointerMap *map[string]OtherType 89 Slice []OtherType 90 SlicePointer []*OtherType 91 PointerSlicePointer *[]*OtherType 92 } 93 94 f := fuzz.New().RandSource(rand.NewSource(0)).NilChance(0).NumElements(1, 1).Funcs( 95 func(o *OtherType, c fuzz.Continue) { 96 o.A = "Foo" 97 o.B = "Bar" 98 }, 99 func(op **OtherType, c fuzz.Continue) { 100 *op = &OtherType{"A", "B"} 101 }, 102 func(m map[string]OtherType, c fuzz.Continue) { 103 m["Works Because"] = OtherType{ 104 "Fuzzer", 105 "Preallocated", 106 } 107 }, 108 ) 109 object := MyType{} 110 f.Fuzz(&object) 111 bytes, err := json.MarshalIndent(&object, "", " ") 112 if err != nil { 113 fmt.Printf("error: %v\n", err) 114 } 115 fmt.Printf("%s\n", string(bytes)) 116 // Output: 117 // { 118 // "Pointer": { 119 // "A": "A", 120 // "B": "B" 121 // }, 122 // "Map": { 123 // "Works Because": { 124 // "A": "Fuzzer", 125 // "B": "Preallocated" 126 // } 127 // }, 128 // "PointerMap": { 129 // "Works Because": { 130 // "A": "Fuzzer", 131 // "B": "Preallocated" 132 // } 133 // }, 134 // "Slice": [ 135 // { 136 // "A": "Foo", 137 // "B": "Bar" 138 // } 139 // ], 140 // "SlicePointer": [ 141 // { 142 // "A": "A", 143 // "B": "B" 144 // } 145 // ], 146 // "PointerSlicePointer": [ 147 // { 148 // "A": "A", 149 // "B": "B" 150 // } 151 // ] 152 // } 153} 154 155func ExampleMap() { 156 f := fuzz.New().NilChance(0).NumElements(1, 1) 157 var myMap map[struct{ A, B, C int }]string 158 f.Fuzz(&myMap) 159 fmt.Printf("myMap has %v element(s).\n", len(myMap)) 160 // Output: 161 // myMap has 1 element(s). 162} 163 164func ExampleSingle() { 165 f := fuzz.New() 166 var i int 167 f.Fuzz(&i) 168 169 // Technically, we'd expect this to fail one out of 2 billion attempts... 170 fmt.Printf("(i == 0) == %v", i == 0) 171 // Output: 172 // (i == 0) == false 173} 174 175func ExampleEnum() { 176 type MyEnum string 177 const ( 178 A MyEnum = "A" 179 B MyEnum = "B" 180 ) 181 type MyInfo struct { 182 Type MyEnum 183 AInfo *string 184 BInfo *string 185 } 186 187 f := fuzz.New().NilChance(0).Funcs( 188 func(e *MyInfo, c fuzz.Continue) { 189 // Note c's embedded Rand allows for direct use. 190 // We could also use c.RandBool() here. 191 switch c.Intn(2) { 192 case 0: 193 e.Type = A 194 c.Fuzz(&e.AInfo) 195 case 1: 196 e.Type = B 197 c.Fuzz(&e.BInfo) 198 } 199 }, 200 ) 201 202 for i := 0; i < 100; i++ { 203 var myObject MyInfo 204 f.Fuzz(&myObject) 205 switch myObject.Type { 206 case A: 207 if myObject.AInfo == nil { 208 fmt.Println("AInfo should have been set!") 209 } 210 if myObject.BInfo != nil { 211 fmt.Println("BInfo should NOT have been set!") 212 } 213 case B: 214 if myObject.BInfo == nil { 215 fmt.Println("BInfo should have been set!") 216 } 217 if myObject.AInfo != nil { 218 fmt.Println("AInfo should NOT have been set!") 219 } 220 default: 221 fmt.Println("Invalid enum value!") 222 } 223 } 224 // Output: 225} 226