]> Cypherpunks repositories - gostls13.git/commitdiff
os/exec: in TestContextCancel, dump goroutines on failure
authorBryan C. Mills <bcmills@google.com>
Wed, 1 Dec 2021 19:15:08 +0000 (14:15 -0500)
committerBryan C. Mills <bcmills@google.com>
Thu, 2 Dec 2021 05:25:23 +0000 (05:25 +0000)
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>
src/os/exec/exec_test.go

index 6172c78dd4d90c8295094ca3375d6360d80a68c6..81de018e09e5af0bcd748bedbd4eeef41a255a5f 100644 (file)
@@ -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 {