1 [short] skip 'links and runs a test binary'
2 [!fuzz] skip 'tests SIGINT behavior for interrupting fuzz tests'
3 [GOOS:windows] skip 'windows does not support os.Interrupt'
4
5 ? go test -json -fuzz FuzzInterrupt -run '^$' -parallel 1
6 stdout -count=1 '"Action":"pass","Package":"example","Test":"FuzzInterrupt"'
7 stdout -count=1 '"Action":"pass","Package":"example","Elapsed":'
8
9 mkdir $WORK/fuzzcache
10 go test -c . -fuzz=. -o example_test.exe
11 ? go tool test2json -p example -t ./example_test.exe -test.v -test.paniconexit0 -test.fuzzcachedir $WORK/fuzzcache -test.fuzz FuzzInterrupt -test.run '^$' -test.parallel 1
12 stdout -count=1 '"Action":"pass","Package":"example","Test":"FuzzInterrupt"'
13 stdout -count=1 '"Action":"pass","Package":"example","Elapsed":'
14
15 -- go.mod --
16 module example
17 go 1.20
18 -- example_test.go --
19 package example_test
20
21 import (
22 "fmt"
23 "os"
24 "strconv"
25 "testing"
26 "strings"
27 "time"
28 )
29
30 func FuzzInterrupt(f *testing.F) {
31 pids := os.Getenv("GO_TEST_INTERRUPT_PIDS")
32 if pids == "" {
33 // This is the main test process.
34 // Set the environment variable for fuzz workers.
35 pid := os.Getpid()
36 ppid := os.Getppid()
37 os.Setenv("GO_TEST_INTERRUPT_PIDS", fmt.Sprintf("%d,%d", ppid, pid))
38 }
39
40 sentInterrupt := false
41 f.Fuzz(func(t *testing.T, orig string) {
42 if !sentInterrupt {
43 // Simulate a ctrl-C on the keyboard by sending SIGINT
44 // to the main test process and its parent.
45 for _, pid := range strings.Split(pids, ",") {
46 i, err := strconv.Atoi(pid)
47 if err != nil {
48 t.Fatal(err)
49 }
50 if p, err := os.FindProcess(i); err == nil {
51 p.Signal(os.Interrupt)
52 sentInterrupt = true // Only send interrupts once.
53 }
54 }
55 }
56 time.Sleep(1 * time.Millisecond) // Delay the fuzzer a bit to avoid wasting CPU.
57 })
58 }
59
View as plain text