]> Cypherpunks repositories - gostls13.git/commitdiff
os: use testenv.Command and os.Executable in tests
authorBryan C. Mills <bcmills@google.com>
Tue, 22 Aug 2023 15:32:20 +0000 (11:32 -0400)
committerGopher Robot <gobot@golang.org>
Wed, 23 Aug 2023 19:03:28 +0000 (19:03 +0000)
On Unix platforms, testenv.Command sends SIGQUIT to stuck commands
before the test times out. For subprocesses that are written in Go,
that causes the runtime to dump running goroutines, and in other
languages it triggers similar behavior (such as a core dump).
If the subprocess is stuck due to a bug (such as #57999), that may
help to diagnose it.

For #57999.

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

src/os/signal/signal_cgo_test.go
src/os/signal/signal_test.go

index ac5921591e5929e363a5c8c4c6aed4596d15f6fc..5e85f45e705ef3aa33f479794924f91b542c95e8 100644 (file)
@@ -14,9 +14,9 @@ import (
        "context"
        "encoding/binary"
        "fmt"
+       "internal/testenv"
        "internal/testpty"
        "os"
-       "os/exec"
        "os/signal"
        "runtime"
        "strconv"
@@ -93,7 +93,7 @@ func TestTerminalSignal(t *testing.T) {
                // Main test process, run code below.
                break
        case "1":
-               runSessionLeader(pause)
+               runSessionLeader(t, pause)
                panic("unreachable")
        case "2":
                runStoppingChild()
@@ -128,9 +128,22 @@ func TestTerminalSignal(t *testing.T) {
                t.Fatal(err)
        }
 
-       ctx, cancel := context.WithTimeout(context.Background(), 100*time.Second)
-       defer cancel()
-       cmd := exec.CommandContext(ctx, os.Args[0], "-test.run=TestTerminalSignal")
+       var (
+               ctx     = context.Background()
+               cmdArgs = []string{"-test.run=TestTerminalSignal"}
+       )
+       if deadline, ok := t.Deadline(); ok {
+               d := time.Until(deadline)
+               var cancel context.CancelFunc
+               ctx, cancel = context.WithTimeout(ctx, d)
+               t.Cleanup(cancel)
+
+               // We run the subprocess with an additional 20% margin to allow it to fail
+               // and clean up gracefully if it times out.
+               cmdArgs = append(cmdArgs, fmt.Sprintf("-test.timeout=%v", d*5/4))
+       }
+
+       cmd := testenv.CommandContext(t, ctx, os.Args[0], cmdArgs...)
        cmd.Env = append(os.Environ(), "GO_TEST_TERMINAL_SIGNALS=1")
        cmd.Stdin = os.Stdin
        cmd.Stdout = os.Stdout // for logging
@@ -216,7 +229,7 @@ func TestTerminalSignal(t *testing.T) {
 }
 
 // GO_TEST_TERMINAL_SIGNALS=1 subprocess above.
-func runSessionLeader(pause time.Duration) {
+func runSessionLeader(t *testing.T, pause time.Duration) {
        // "Attempts to use tcsetpgrp() from a process which is a
        // member of a background process group on a fildes associated
        // with its controlling terminal shall cause the process group
@@ -235,10 +248,22 @@ func runSessionLeader(pause time.Duration) {
        pty := os.NewFile(ptyFD, "pty")
        controlW := os.NewFile(controlFD, "control-pipe")
 
-       // Slightly shorter timeout than in the parent.
-       ctx, cancel := context.WithTimeout(context.Background(), 90*time.Second)
-       defer cancel()
-       cmd := exec.CommandContext(ctx, os.Args[0], "-test.run=TestTerminalSignal")
+       var (
+               ctx     = context.Background()
+               cmdArgs = []string{"-test.run=TestTerminalSignal"}
+       )
+       if deadline, ok := t.Deadline(); ok {
+               d := time.Until(deadline)
+               var cancel context.CancelFunc
+               ctx, cancel = context.WithTimeout(ctx, d)
+               t.Cleanup(cancel)
+
+               // We run the subprocess with an additional 20% margin to allow it to fail
+               // and clean up gracefully if it times out.
+               cmdArgs = append(cmdArgs, fmt.Sprintf("-test.timeout=%v", d*5/4))
+       }
+
+       cmd := testenv.CommandContext(t, ctx, os.Args[0], cmdArgs...)
        cmd.Env = append(os.Environ(), "GO_TEST_TERMINAL_SIGNALS=2")
        cmd.Stdin = os.Stdin
        cmd.Stdout = os.Stdout
index ddbd458a6da3cce5b52c8acc4e595ada4233e1a8..e5af885511983fe152837bf46b7a4c7e052af37c 100644 (file)
@@ -483,7 +483,7 @@ func TestNohup(t *testing.T) {
                        defer wg.Done()
 
                        // POSIX specifies that nohup writes to a file named nohup.out if standard
-                       // output is a terminal. However, for an exec.Command, standard output is
+                       // output is a terminal. However, for an exec.Cmd, standard output is
                        // not a terminal — so we don't need to read or remove that file (and,
                        // indeed, cannot even create it if the current user is unable to write to
                        // GOROOT/src, such as when GOROOT is installed and owned by root).