1 [!fuzz] skip
2 [short] skip
3
4 # We clean the fuzz cache during this test. Don't clean the user's cache.
5 env GOCACHE=$WORK/gocache
6
7 # Test that fuzzminimizetime cannot be negative seconds
8 ! go test -fuzz=FuzzMinimizerRecoverable -run=FuzzMinimizerRecoverable -fuzztime=10000x -fuzzminimizetime=-1ms .
9 ! stdout '^ok'
10 ! stdout 'contains a non-zero byte'
11 stdout 'invalid duration'
12 stdout FAIL
13
14 # Test that fuzzminimizetime cannot be negative times
15 ! go test -fuzz=FuzzMinimizerRecoverable -run=FuzzMinimizerRecoverable -fuzztime=10000x -fuzzminimizetime=-1x .
16 ! stdout '^ok'
17 ! stdout 'contains a non-zero byte'
18 stdout 'invalid count'
19 stdout FAIL
20
21 # Test that fuzzminimizetime can be zero seconds, and minimization is disabled
22 ! go test -fuzz=FuzzMinimizeZeroDurationSet -run=FuzzMinimizeZeroDurationSet -fuzztime=10000x -fuzzminimizetime=0s .
23 ! stdout '^ok'
24 ! stdout 'minimizing'
25 stdout 'there was an Error'
26 stdout FAIL
27
28 # Test that fuzzminimizetime can be zero times, and minimization is disabled
29 ! go test -fuzz=FuzzMinimizeZeroLimitSet -run=FuzzMinimizeZeroLimitSet -fuzztime=10000x -fuzzminimizetime=0x .
30 ! stdout '^ok'
31 ! stdout 'minimizing'
32 stdout -count=1 'there was an Error'
33 stdout FAIL
34
35 # Test that minimization is working for recoverable errors.
36 ! go test -fuzz=FuzzMinimizerRecoverable -run=FuzzMinimizerRecoverable -fuzztime=10000x .
37 ! stdout '^ok'
38 stdout 'got the minimum size!'
39 # The error message that was printed should be for the one written to testdata.
40 stdout 'contains a non-zero byte of length 50'
41 stdout FAIL
42
43 # Check that the bytes written to testdata are of length 50 (the minimum size)
44 go run ./check_testdata FuzzMinimizerRecoverable 50
45
46 # Test that re-running the minimized value causes a crash.
47 ! go test -run=FuzzMinimizerRecoverable .
48 rm testdata
49
50 # Test that minimization is working for recoverable errors. Run it with -v this
51 # time to ensure the command line output still looks right.
52 ! go test -v -fuzz=FuzzMinimizerRecoverable -run=FuzzMinimizerRecoverable -fuzztime=10000x .
53 ! stdout '^ok'
54 stdout 'got the minimum size!'
55 # The error message that was printed should be for the one written to testdata.
56 stdout 'contains a non-zero byte of length 50'
57 stdout FAIL
58
59 # Check that the bytes written to testdata are of length 50 (the minimum size)
60 go run ./check_testdata FuzzMinimizerRecoverable 50
61
62 # Test that re-running the minimized value causes a crash.
63 ! go test -run=FuzzMinimizerRecoverable .
64 rm testdata
65
66 # Test that minimization doesn't run for non-recoverable errors.
67 ! go test -fuzz=FuzzMinimizerNonrecoverable -run=FuzzMinimizerNonrecoverable -fuzztime=10000x .
68 ! stdout '^ok'
69 ! stdout 'minimizing'
70 stdout -count=1 '^\s+fuzzing process hung or terminated unexpectedly: exit status 99'
71 stdout FAIL
72
73 # Check that re-running the value causes a crash.
74 ! go test -run=FuzzMinimizerNonrecoverable .
75 rm testdata
76
77 # Clear the fuzzing cache. There may already be minimized inputs that would
78 # interfere with the next stage of the test.
79 go clean -fuzzcache
80
81 # Test that minimization can be cancelled by fuzzminimizetime and the latest
82 # crash will still be logged and written to testdata.
83 ! go test -fuzz=FuzzMinimizerRecoverable -run=FuzzMinimizerRecoverable -fuzztime=100x -fuzzminimizetime=1x .
84 ! stdout '^ok'
85 stdout 'testdata[/\\]fuzz[/\\]FuzzMinimizerRecoverable[/\\]'
86 ! stdout 'got the minimum size!' # it shouldn't have had enough time to minimize it
87 stdout FAIL
88
89 # Test that re-running the unminimized value causes a crash.
90 ! go test -run=FuzzMinimizerRecoverable .
91
92 # TODO(jayconrod,katiehockman): add a test which verifies that the right bytes
93 # are written to testdata in the case of an interrupt during minimization.
94
95 -- go.mod --
96 module example.com/y
97
98 go 1.16
99 -- y_test.go --
100 package y
101
102 import (
103 "os"
104 "testing"
105 )
106
107 func FuzzMinimizeZeroDurationSet(f *testing.F) {
108 f.Fuzz(func(t *testing.T, b []byte) {
109 if len(b) > 5 {
110 t.Errorf("there was an Error")
111 }
112 })
113 }
114
115 func FuzzMinimizeZeroLimitSet(f *testing.F) {
116 f.Fuzz(func(t *testing.T, b []byte) {
117 if len(b) > 5 {
118 t.Errorf("there was an Error")
119 }
120 })
121 }
122
123 func FuzzMinimizerRecoverable(f *testing.F) {
124 f.Add(make([]byte, 100))
125 f.Fuzz(func(t *testing.T, b []byte) {
126 if len(b) < 50 {
127 // Make sure that b is large enough that it can be minimized
128 return
129 }
130 // Given the randomness of the mutations, this should allow the
131 // minimizer to trim down the value a bit.
132 for _, n := range b {
133 if n != 0 {
134 if len(b) == 50 {
135 t.Log("got the minimum size!")
136 }
137 t.Fatalf("contains a non-zero byte of length %d", len(b))
138 }
139 }
140 })
141 }
142
143 func FuzzMinimizerNonrecoverable(f *testing.F) {
144 f.Fuzz(func(t *testing.T, b []byte) {
145 os.Exit(99)
146 })
147 }
148 -- empty/empty.go --
149 package empty
150 -- check_testdata/check_testdata.go --
151 package main
152
153 import (
154 "bytes"
155 "fmt"
156 "io/ioutil"
157 "os"
158 "path/filepath"
159 "strconv"
160 )
161
162 func main() {
163 target := os.Args[1]
164 numBytes, err := strconv.Atoi(os.Args[2])
165 if err != nil {
166 fmt.Fprintln(os.Stderr, err)
167 os.Exit(1)
168 }
169
170 // Open the file in testdata (there should only be one)
171 dir := fmt.Sprintf("testdata/fuzz/%s", target)
172 files, err := ioutil.ReadDir(dir)
173 if err != nil {
174 fmt.Fprintln(os.Stderr, err)
175 os.Exit(1)
176 }
177 if len(files) != 1 {
178 fmt.Fprintf(os.Stderr, "expected one file, got %d", len(files))
179 os.Exit(1)
180 }
181 got, err := ioutil.ReadFile(filepath.Join(dir, files[0].Name()))
182 if err != nil {
183 fmt.Fprintln(os.Stderr, err)
184 os.Exit(1)
185 }
186
187 // Trim the newline at the end of the file
188 got = bytes.TrimSpace(got)
189
190 // Make sure that there were exactly 100 bytes written to the corpus entry
191 prefix := []byte("[]byte(")
192 i := bytes.Index(got, prefix)
193 gotBytes := got[i+len(prefix) : len(got)-1]
194 s, err := strconv.Unquote(string(gotBytes))
195 if err != nil {
196 fmt.Fprintln(os.Stderr, err)
197 os.Exit(1)
198 }
199 if want, got := numBytes, len(s); want != got {
200 fmt.Fprintf(os.Stderr, "want %d bytes, got %d\n", want, got)
201 os.Exit(1)
202 }
203 }
204
View as plain text