aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/go/testdata/script/test_fuzz_mutator_repeat.txt
blob: 0924ed37e6cea4a5fafd9cea64921632ebf9c72a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# 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)
			}
		}
	})
}