# 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 stdout 'fuzzing process terminated unexpectedly' stdout 'Crash 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, probably because it already exists, // and we're minimizing now. Return without crashing. return } f.Write(b) f.Close() 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) } } }) }