1 skip # a 5s timeout is never going to be reliable (go.dev/issue/72140)
2
3 [!fuzz] skip
4 [short] skip
5 env GOCACHE=$WORK/cache
6
7 # There are no seed values, so 'go test' should finish quickly.
8 go test
9
10 # For the fuzzing phase, we reduce GOMAXPROCS to avoid consuming too many
11 # resources during the test. Ideally this would just free up resources to run
12 # other parallel tests more quickly, but unfortunately it is actually necessary
13 # in some 32-bit environments to prevent the fuzzing engine from running out of
14 # address space (see https://go.dev/issue/65434).
15 env GOMAXPROCS=2
16
17 # Fuzzing should exit 0 after fuzztime, even if timeout is short.
18 go test -timeout=3s -fuzz=FuzzFast -fuzztime=5s
19
20 # We should see the same behavior when invoking the test binary directly.
21 go test -c
22 exec ./fuzz.test$GOEXE -test.timeout=3s -test.fuzz=FuzzFast -test.fuzztime=5s -test.parallel=1 -test.fuzzcachedir=$WORK/cache
23
24 # Timeout should not cause inputs to be written as crashers.
25 ! exists testdata/fuzz
26
27 # When we use fuzztime with an "x" suffix, it runs a specific number of times.
28 # This fuzz function creates a file with a unique name ($pid.$count) on each
29 # run. We count the files to find the number of runs.
30 mkdir count
31 go test -fuzz=FuzzTestCount -fuzztime=1000x -fuzzminimizetime=1x
32 go run check_file_count.go count 1000
33
34 # When we use fuzzminimizetime with an "x" suffix, it runs a specific number of
35 # times while minimizing. This fuzz function creates a file with a unique name
36 # ($pid.$count) on each run once the first crash has been found. That means that
37 # there should be one file for each execution of the fuzz function during
38 # minimization, so we count these to determine how many times minimization was
39 # run.
40 mkdir minimizecount
41 ! go test -fuzz=FuzzMinimizeCount -fuzzminimizetime=3x -parallel=1
42 go run check_file_count.go minimizecount 3
43
44 -- go.mod --
45 module fuzz
46
47 go 1.16
48 -- fuzz_fast_test.go --
49 package fuzz_test
50
51 import "testing"
52
53 func FuzzFast(f *testing.F) {
54 f.Fuzz(func (*testing.T, []byte) {})
55 }
56 -- fuzz_count_test.go --
57 package fuzz
58
59 import (
60 "fmt"
61 "os"
62 "testing"
63 )
64
65 func FuzzTestCount(f *testing.F) {
66 pid := os.Getpid()
67 n := 0
68 f.Fuzz(func(t *testing.T, _ []byte) {
69 name := fmt.Sprintf("count/%v.%d", pid, n)
70 if err := os.WriteFile(name, nil, 0666); err != nil {
71 t.Fatal(err)
72 }
73 n++
74 })
75 }
76 -- fuzz_minimize_count_test.go --
77 package fuzz
78
79 import (
80 "bytes"
81 "fmt"
82 "os"
83 "testing"
84 )
85
86 func FuzzMinimizeCount(f *testing.F) {
87 pid := os.Getpid()
88 n := 0
89 seed := bytes.Repeat([]byte("a"), 357)
90 f.Add(seed)
91 crashFound := false
92 f.Fuzz(func(t *testing.T, b []byte) {
93 if crashFound {
94 name := fmt.Sprintf("minimizecount/%v.%d", pid, n)
95 if err := os.WriteFile(name, nil, 0666); err != nil {
96 t.Fatal(err)
97 }
98 n++
99 }
100 if !bytes.Equal(b, seed) { // this should happen right away
101 crashFound = true
102 t.Error("minimize this!")
103 }
104 })
105 }
106 -- check_file_count.go --
107 // +build ignore
108
109 package main
110
111 import (
112 "fmt"
113 "os"
114 "strconv"
115 )
116
117 func main() {
118 dir, err := os.ReadDir(os.Args[1])
119 if err != nil {
120 fmt.Fprintln(os.Stderr, err)
121 os.Exit(1)
122 }
123 got := len(dir)
124 want, _ := strconv.Atoi(os.Args[2])
125 if got != want {
126 fmt.Fprintf(os.Stderr, "got %d files; want %d\n", got, want)
127 os.Exit(1)
128 }
129 }
130
View as plain text