1 # Test that when the coordinator experiences an I/O error communicating
2 # with a worker, the coordinator stops the worker and reports the error.
3 # The coordinator should not record a crasher.
4 #
5 # We simulate an I/O error in the test by writing garbage to fuzz_out.
6 # This is unlikely, but possible. It's difficult to simulate interruptions
7 # due to ^C and EOF errors which are more common. We don't report those.
8 [short] skip
9 [!fuzz] skip
10
11 # If the I/O error occurs before F.Fuzz is called, the coordinator should
12 # stop the worker and say that.
13 ! go test -fuzz=FuzzClosePipeBefore -parallel=1
14 stdout '\s*fuzzing process terminated without fuzzing:'
15 ! stdout 'communicating with fuzzing process'
16 ! exists testdata
17
18 # If the I/O error occurs after F.Fuzz is called (unlikely), just exit.
19 # It's hard to distinguish this case from the worker being interrupted by ^C
20 # or exiting with status 0 (which it should do when interrupted by ^C).
21 ! go test -fuzz=FuzzClosePipeAfter -parallel=1
22 stdout '^\s*communicating with fuzzing process: invalid character ''!'' looking for beginning of value$'
23 ! exists testdata
24
25 -- go.mod --
26 module test
27
28 go 1.17
29 -- io_error_test.go --
30 package io_error
31
32 import (
33 "flag"
34 "testing"
35 "time"
36 )
37
38 func isWorker() bool {
39 f := flag.Lookup("test.fuzzworker")
40 if f == nil {
41 return false
42 }
43 get, ok := f.Value.(flag.Getter)
44 if !ok {
45 return false
46 }
47 return get.Get() == interface{}(true)
48 }
49
50 func FuzzClosePipeBefore(f *testing.F) {
51 if isWorker() {
52 sendGarbageToCoordinator(f)
53 time.Sleep(3600 * time.Second) // pause until coordinator terminates the process
54 }
55 f.Fuzz(func(*testing.T, []byte) {})
56 }
57
58 func FuzzClosePipeAfter(f *testing.F) {
59 f.Fuzz(func(t *testing.T, _ []byte) {
60 if isWorker() {
61 sendGarbageToCoordinator(t)
62 time.Sleep(3600 * time.Second) // pause until coordinator terminates the process
63 }
64 })
65 }
66 -- io_error_windows_test.go --
67 package io_error
68
69 import (
70 "fmt"
71 "os"
72 "testing"
73 )
74
75 func sendGarbageToCoordinator(tb testing.TB) {
76 v := os.Getenv("GO_TEST_FUZZ_WORKER_HANDLES")
77 var fuzzInFD, fuzzOutFD uintptr
78 if _, err := fmt.Sscanf(v, "%x,%x", &fuzzInFD, &fuzzOutFD); err != nil {
79 tb.Fatalf("parsing GO_TEST_FUZZ_WORKER_HANDLES: %v", err)
80 }
81 f := os.NewFile(fuzzOutFD, "fuzz_out")
82 if _, err := f.Write([]byte("!!")); err != nil {
83 tb.Fatalf("writing fuzz_out: %v", err)
84 }
85 }
86 -- io_error_notwindows_test.go --
87 // +build !windows
88
89 package io_error
90
91 import (
92 "os"
93 "testing"
94 )
95
96 func sendGarbageToCoordinator(tb testing.TB) {
97 f := os.NewFile(4, "fuzz_out")
98 if _, err := f.Write([]byte("!!")); err != nil {
99 tb.Fatalf("writing fuzz_out: %v", err)
100 }
101 }
102
View as plain text