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