1 # TODO(jayconrod): support shared memory on more platforms.
2 [!GOOS:darwin] [!GOOS:linux] [!GOOS:windows] skip
3
4 # Verify that the fuzzing engine records the actual crashing input, even when
5 # a worker process terminates without communicating the crashing input back
6 # to the coordinator.
7
8 [short] skip
9 env GOCACHE=$WORK/cache
10
11 # Start fuzzing. The worker crashes after 100 iterations.
12 # The fuzz function writes the crashing input to "want" before exiting.
13 # The fuzzing engine reconstructs the crashing input and saves it to testdata.
14 ! exists want
15 ! go test -fuzz=. -parallel=1 -fuzztime=110x -fuzzminimizetime=10x -v
16 stdout '^\s+fuzzing process hung or terminated unexpectedly: exit status'
17 stdout 'Failing input written to testdata'
18
19 # Run the fuzz target without fuzzing. The fuzz function is called with the
20 # crashing input in testdata. The test passes if that input is identical to
21 # the one saved in "want".
22 exists want
23 go test -want=want
24
25 -- go.mod --
26 module fuzz
27
28 go 1.17
29 -- fuzz_test.go --
30 package fuzz
31
32 import (
33 "bytes"
34 "flag"
35 "os"
36 "testing"
37 )
38
39 var wantFlag = flag.String("want", "", "file containing previous crashing input")
40
41 func FuzzRepeat(f *testing.F) {
42 i := 0
43 f.Fuzz(func(t *testing.T, b []byte) {
44 i++
45 if i == 100 {
46 f, err := os.OpenFile("want", os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0666)
47 if err != nil {
48 // Couldn't create the file. Return without crashing, and try
49 // again.
50 i--
51 t.Skip(err)
52 }
53 if _, err := f.Write(b); err != nil {
54 // We already created the file, so if we failed to write it
55 // there's not much we can do. The test will fail anyway, but
56 // at least make sure the error is logged to stdout.
57 t.Fatal(err)
58 }
59 if err := f.Close(); err != nil {
60 t.Fatal(err)
61 }
62 os.Exit(1) // crash without communicating
63 }
64
65 if *wantFlag != "" {
66 want, err := os.ReadFile(*wantFlag)
67 if err != nil {
68 t.Fatal(err)
69 }
70 if !bytes.Equal(want, b) {
71 t.Fatalf("inputs are not equal!\n got: %q\nwant:%q", b, want)
72 }
73 }
74 })
75 }
76
View as plain text