diff options
author | Bryan C. Mills <bcmills@google.com> | 2021-12-01 14:15:08 -0500 |
---|---|---|
committer | Bryan C. Mills <bcmills@google.com> | 2021-12-02 05:25:23 +0000 |
commit | 00dbcb33f8c20ce51de558cbc9de811b1ba0f70c (patch) | |
tree | 4724507ff0c425aa0babc33bb970818fc950c6eb /src/os/exec/exec_test.go | |
parent | c3a7fb207409a77b2ad644fe777db04d7df8e08c (diff) | |
download | go-00dbcb33f8c20ce51de558cbc9de811b1ba0f70c.tar.gz go-00dbcb33f8c20ce51de558cbc9de811b1ba0f70c.zip |
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 <bcmills@google.com>
Run-TryBot: Bryan C. Mills <bcmills@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/os/exec/exec_test.go')
-rw-r--r-- | src/os/exec/exec_test.go | 19 |
1 files changed, 17 insertions, 2 deletions
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 { |