From: Bryan C. Mills Date: Wed, 1 Dec 2021 19:15:08 +0000 (-0500) Subject: os/exec: in TestContextCancel, dump goroutines on failure X-Git-Tag: go1.18beta1~131 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=00dbcb33f8c20ce51de558cbc9de811b1ba0f70c;p=gostls13.git os/exec: in TestContextCancel, dump goroutines on failure If this test fails, we want to know exactly what the os/exec goroutines are doing. Panicking gives us a goroutine dump, whereas t.Fatal does not. While we're here, use exponential backoff instead of a hard-coded 1ms sleep. We want to give the OS enough time to actually terminate the subprocess. For #42061 Change-Id: I3d50a71ac314853c68a935218e7f97ce18b08b5b Reviewed-on: https://go-review.googlesource.com/c/go/+/368317 Trust: Bryan C. Mills Run-TryBot: Bryan C. Mills TryBot-Result: Go Bot Reviewed-by: Ian Lance Taylor --- diff --git a/src/os/exec/exec_test.go b/src/os/exec/exec_test.go index 6172c78dd4..81de018e09 100644 --- a/src/os/exec/exec_test.go +++ b/src/os/exec/exec_test.go @@ -954,6 +954,10 @@ func TestContext(t *testing.T) { } func TestContextCancel(t *testing.T) { + // To reduce noise in the final goroutine dump, + // let other parallel tests complete if possible. + t.Parallel() + ctx, cancel := context.WithCancel(context.Background()) defer cancel() c := helperCommandContext(t, ctx, "cat") @@ -978,14 +982,25 @@ func TestContextCancel(t *testing.T) { // Calling cancel should have killed the process, so writes // should now fail. Give the process a little while to die. start := time.Now() + delay := 1 * time.Millisecond for { if _, err := io.WriteString(stdin, "echo"); err != nil { break } + if time.Since(start) > time.Minute { - t.Fatal("canceling context did not stop program") + // Panic instead of calling t.Fatal so that we get a goroutine dump. + // We want to know exactly what the os/exec goroutines got stuck on. + panic("canceling context did not stop program") + } + + // Back off exponentially (up to 1-second sleeps) to give the OS time to + // terminate the process. + delay *= 2 + if delay > 1*time.Second { + delay = 1 * time.Second } - time.Sleep(time.Millisecond) + time.Sleep(delay) } if err := c.Wait(); err == nil {