example_test.go 4.5 KB

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