...
1skip # a 5s timeout is never going to be reliable (go.dev/issue/72140)
2
3[!fuzz] skip
4[short] skip
5env GOCACHE=$WORK/cache
6
7# There are no seed values, so 'go test' should finish quickly.
8go 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).
15env GOMAXPROCS=2
16
17# Fuzzing should exit 0 after fuzztime, even if timeout is short.
18go test -timeout=3s -fuzz=FuzzFast -fuzztime=5s
19
20# We should see the same behavior when invoking the test binary directly.
21go test -c
22exec ./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.
30mkdir count
31go test -fuzz=FuzzTestCount -fuzztime=1000x -fuzzminimizetime=1x
32go 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.
40mkdir minimizecount
41! go test -fuzz=FuzzMinimizeCount -fuzzminimizetime=3x -parallel=1
42go run check_file_count.go minimizecount 3
43
44-- go.mod --
45module fuzz
46
47go 1.16
48-- fuzz_fast_test.go --
49package fuzz_test
50
51import "testing"
52
53func FuzzFast(f *testing.F) {
54 f.Fuzz(func (*testing.T, []byte) {})
55}
56-- fuzz_count_test.go --
57package fuzz
58
59import (
60 "fmt"
61 "os"
62 "testing"
63)
64
65func 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 --
77package fuzz
78
79import (
80 "bytes"
81 "fmt"
82 "os"
83 "testing"
84)
85
86func 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
109package main
110
111import (
112 "fmt"
113 "os"
114 "strconv"
115)
116
117func 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}
View as plain text