[!fuzz] skip [short] skip env GOCACHE=$WORK/cache # When running seed inputs, T.Parallel should let multiple inputs run in # parallel. go test -run=FuzzSeed # When fuzzing, T.Parallel should be safe to call, but it should have no effect. # We just check that it doesn't hang, which would be the most obvious # failure mode. # TODO(jayconrod): check for the string "after T.Parallel". It's not printed # by 'go test', so we can't distinguish that crasher from some other panic. ! go test -run=FuzzMutate -fuzz=FuzzMutate exists testdata/fuzz/FuzzMutate # Testdata should now contain a corpus entry which will fail FuzzMutate. # Run the test without fuzzing, setting -parallel to different values to make # sure it fails, and doesn't hang. ! go test -run=FuzzMutate -parallel=1 ! go test -run=FuzzMutate -parallel=2 ! go test -run=FuzzMutate -parallel=4 -- go.mod -- module fuzz_parallel go 1.17 -- fuzz_parallel_test.go -- package fuzz_parallel import ( "sort" "sync" "testing" ) func FuzzSeed(f *testing.F) { for _, v := range [][]byte{{'a'}, {'b'}, {'c'}} { f.Add(v) } var mu sync.Mutex var before, after []byte f.Cleanup(func() { sort.Slice(after, func(i, j int) bool { return after[i] < after[j] }) got := string(before) + string(after) want := "abcabc" if got != want { f.Fatalf("got %q; want %q", got, want) } }) f.Fuzz(func(t *testing.T, b []byte) { before = append(before, b...) t.Parallel() mu.Lock() after = append(after, b...) mu.Unlock() }) } func FuzzMutate(f *testing.F) { f.Fuzz(func(t *testing.T, _ []byte) { t.Parallel() t.Error("after T.Parallel") }) }