| # TODO(jayconrod): support shared memory on more platforms. |
| [!darwin] [!linux] [!windows] skip |
| |
| # Verify that the fuzzing engine records the actual crashing input, even when |
| # a worker process terminates without communicating the crashing input back |
| # to the coordinator. |
| |
| [short] skip |
| |
| # Start fuzzing. The worker crashes after 100 iterations. |
| # The fuzz function writes the crashing input to "want" before exiting. |
| # The fuzzing engine reconstructs the crashing input and saves it to testdata. |
| ! exists want |
| ! go test -fuzz=. -parallel=1 -fuzztime=110x -fuzzminimizetime=10x -v |
| stdout '^\s+fuzzing process hung or terminated unexpectedly: exit status' |
| stdout 'Failing input written to testdata' |
| |
| # Run the fuzz target without fuzzing. The fuzz function is called with the |
| # crashing input in testdata. The test passes if that input is identical to |
| # the one saved in "want". |
| exists want |
| go test -want=want |
| |
| -- go.mod -- |
| module fuzz |
| |
| go 1.17 |
| -- fuzz_test.go -- |
| package fuzz |
| |
| import ( |
| "bytes" |
| "flag" |
| "os" |
| "testing" |
| ) |
| |
| var wantFlag = flag.String("want", "", "file containing previous crashing input") |
| |
| func FuzzRepeat(f *testing.F) { |
| i := 0 |
| f.Fuzz(func(t *testing.T, b []byte) { |
| i++ |
| if i == 100 { |
| f, err := os.OpenFile("want", os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0666) |
| if err != nil { |
| // Couldn't create the file. Return without crashing, and try |
| // again. |
| i-- |
| t.Skip(err) |
| } |
| if _, err := f.Write(b); err != nil { |
| // We already created the file, so if we failed to write it |
| // there's not much we can do. The test will fail anyway, but |
| // at least make sure the error is logged to stdout. |
| t.Fatal(err) |
| } |
| if err := f.Close(); err != nil { |
| t.Fatal(err) |
| } |
| os.Exit(1) // crash without communicating |
| } |
| |
| if *wantFlag != "" { |
| want, err := os.ReadFile(*wantFlag) |
| if err != nil { |
| t.Fatal(err) |
| } |
| if !bytes.Equal(want, b) { |
| t.Fatalf("inputs are not equal!\n got: %q\nwant:%q", b, want) |
| } |
| } |
| }) |
| } |