]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: deflake TestScript/test2json_interrupt
authorBryan C. Mills <bcmills@google.com>
Wed, 7 Dec 2022 21:33:42 +0000 (16:33 -0500)
committerGopher Robot <gobot@golang.org>
Thu, 8 Dec 2022 03:52:44 +0000 (03:52 +0000)
- Start handling signals in 'go test' just before starting the test
  subprocess instead of just after. (It is unlikely that starting the
  process will cause cmd/go to hang in a way that requires signals to
  debug, and it is possible that something the test does — such as
  sending os.Interrupt to its parent processes — will immediately
  send a signal that needs to be handled.)

- In the test-test, don't try to re-parse the parent PIDs after
  sending signals, and sleep for a much shorter time interval.
  (Overrunning the sleep caused the next call to strconv.Atoi — which
  shouldn't even happen! — to fail with a parse error, leading to the
  failure mode observed in
  https://build.golang.org/log/f0982dcfc6a362f9c737eec3e7072dcc7ef29e32.)

Fixes #56083.
Updates #53563.

Change-Id: I346a95bdda5619632659ea854f98a9e17a6aede7
Reviewed-on: https://go-review.googlesource.com/c/go/+/456115
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Bryan Mills <bcmills@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Run-TryBot: Bryan Mills <bcmills@google.com>

src/cmd/go/internal/test/test.go
src/cmd/go/testdata/script/test2json_interrupt.txt

index 5a5600982941a15b328da17e46656f51062483e1..0051970cfc65a3a2c7879e88a5bedaaedadde086 100644 (file)
@@ -1306,6 +1306,7 @@ func (r *runTestActor) Act(b *work.Builder, ctx context.Context, a *work.Action)
                cmd.Env = env
        }
 
+       base.StartSigHandlers()
        t0 := time.Now()
        err = cmd.Start()
 
@@ -1314,7 +1315,6 @@ func (r *runTestActor) Act(b *work.Builder, ctx context.Context, a *work.Action)
        // running.
        if err == nil {
                tick := time.NewTimer(testKillTimeout)
-               base.StartSigHandlers()
                done := make(chan error)
                go func() {
                        done <- cmd.Wait()
index 5828e86136792bb4d3f33c53a1c0d6dc3ffda687..763c3369914226e32632c684eb8f229aa1f09892 100644 (file)
@@ -7,8 +7,8 @@ stdout -count=1 '"Action":"pass","Package":"example","Test":"FuzzInterrupt"'
 stdout -count=1 '"Action":"pass","Package":"example","Elapsed":'
 
 mkdir $WORK/fuzzcache
-go test -c . -fuzz=. -o test2json_interrupt_obj
-? go tool test2json -p example -t ./test2json_interrupt_obj -test.v -test.paniconexit0 -test.fuzzcachedir $WORK/fuzzcache -test.fuzz FuzzInterrupt -test.run '^$' -test.parallel 1
+go test -c . -fuzz=. -o example_test.exe
+? 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
 stdout -count=1 '"Action":"pass","Package":"example","Test":"FuzzInterrupt"'
 stdout -count=1 '"Action":"pass","Package":"example","Elapsed":'
 
@@ -37,19 +37,22 @@ func FuzzInterrupt(f *testing.F) {
                os.Setenv("GO_TEST_INTERRUPT_PIDS", fmt.Sprintf("%d,%d", ppid, pid))
        }
 
+       sentInterrupt := false
        f.Fuzz(func(t *testing.T, orig string) {
-               // Simulate a ctrl-C on the keyboard by sending SIGINT
-               // to the main test process and its parent.
-               for _, pid := range strings.Split(pids, ",") {
-                       i, err := strconv.Atoi(pid)
-                       if err != nil {
-                               t.Fatal(err)
-                       }
-                       if p, err := os.FindProcess(i); err == nil {
-                               p.Signal(os.Interrupt)
-                               time.Sleep(10 * time.Millisecond)
-                               pids = ""  // Only interrupt once.
+               if !sentInterrupt {
+                       // Simulate a ctrl-C on the keyboard by sending SIGINT
+                       // to the main test process and its parent.
+                       for _, pid := range strings.Split(pids, ",") {
+                               i, err := strconv.Atoi(pid)
+                               if err != nil {
+                                       t.Fatal(err)
+                               }
+                               if p, err := os.FindProcess(i); err == nil {
+                                       p.Signal(os.Interrupt)
+                                       sentInterrupt = true // Only send interrupts once.
+                               }
                        }
                }
+               time.Sleep(1 * time.Millisecond)  // Delay the fuzzer a bit to avoid wasting CPU.
        })
 }