...

Source file src/github.com/google/gofuzz/example_test.go

Documentation: github.com/google/gofuzz

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

View as plain text