package testenv
import (
+ "bytes"
"errors"
"flag"
"internal/cfg"
"strings"
"sync"
"testing"
+ "time"
)
// Builder reports the name of the builder running this test
t.Skipf("skipping test in -short mode on %s", runtime.GOARCH)
}
}
+
+// RunWithTimeout runs cmd and returns its combined output. If the
+// subprocess exits with a non-zero status, it will log that status
+// and return a non-nil error, but this is not considered fatal.
+func RunWithTimeout(t testing.TB, cmd *exec.Cmd) ([]byte, error) {
+ args := cmd.Args
+ if args == nil {
+ args = []string{cmd.Path}
+ }
+
+ var b bytes.Buffer
+ cmd.Stdout = &b
+ cmd.Stderr = &b
+ if err := cmd.Start(); err != nil {
+ t.Fatalf("starting %s: %v", args, err)
+ }
+
+ // If the process doesn't complete within 1 minute,
+ // assume it is hanging and kill it to get a stack trace.
+ p := cmd.Process
+ done := make(chan bool)
+ go func() {
+ scale := 1
+ // This GOARCH/GOOS test is copied from cmd/dist/test.go.
+ // TODO(iant): Have cmd/dist update the environment variable.
+ if runtime.GOARCH == "arm" || runtime.GOOS == "windows" {
+ scale = 2
+ }
+ if s := os.Getenv("GO_TEST_TIMEOUT_SCALE"); s != "" {
+ if sc, err := strconv.Atoi(s); err == nil {
+ scale = sc
+ }
+ }
+
+ select {
+ case <-done:
+ case <-time.After(time.Duration(scale) * time.Minute):
+ p.Signal(Sigquit)
+ }
+ }()
+
+ err := cmd.Wait()
+ if err != nil {
+ t.Logf("%s exit status: %v", args, err)
+ }
+ close(done)
+
+ return b.Bytes(), err
+}
-// Copyright 2016 The Go Authors. All rights reserved.
+// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build windows || plan9 || (js && wasm)
-package runtime_test
+package testenv
import "os"
-// sigquit is the signal to send to kill a hanging testdata program.
+// Sigquit is the signal to send to kill a hanging subprocess.
// On Unix we send SIGQUIT, but on non-Unix we only have os.Kill.
-var sigquit = os.Kill
+var Sigquit = os.Kill
--- /dev/null
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
+
+package testenv
+
+import "syscall"
+
+// Sigquit is the signal to send to kill a hanging subprocess.
+// Send SIGQUIT to get a stack trace.
+var Sigquit = syscall.SIGQUIT
"path/filepath"
"regexp"
"runtime"
- "strconv"
"strings"
"sync"
"testing"
- "time"
)
var toRemove []string
if testing.Short() {
cmd.Env = append(cmd.Env, "RUNTIME_TEST_SHORT=1")
}
- var b bytes.Buffer
- cmd.Stdout = &b
- cmd.Stderr = &b
- if err := cmd.Start(); err != nil {
- t.Fatalf("starting %s %s: %v", exe, name, err)
- }
-
- // If the process doesn't complete within 1 minute,
- // assume it is hanging and kill it to get a stack trace.
- p := cmd.Process
- done := make(chan bool)
- go func() {
- scale := 1
- // This GOARCH/GOOS test is copied from cmd/dist/test.go.
- // TODO(iant): Have cmd/dist update the environment variable.
- if runtime.GOARCH == "arm" || runtime.GOOS == "windows" {
- scale = 2
- }
- if s := os.Getenv("GO_TEST_TIMEOUT_SCALE"); s != "" {
- if sc, err := strconv.Atoi(s); err == nil {
- scale = sc
- }
- }
-
- select {
- case <-done:
- case <-time.After(time.Duration(scale) * time.Minute):
- p.Signal(sigquit)
- }
- }()
-
- if err := cmd.Wait(); err != nil {
- t.Logf("%s %s exit status: %v", exe, name, err)
- }
- close(done)
-
- return b.String()
+ out, _ := testenv.RunWithTimeout(t, cmd)
+ return string(out)
}
var serializeBuild = make(chan bool, 2)
"unsafe"
)
-// sigquit is the signal to send to kill a hanging testdata program.
-// Send SIGQUIT to get a stack trace.
-var sigquit = syscall.SIGQUIT
-
func init() {
if runtime.Sigisblocked(int(syscall.SIGQUIT)) {
// We can't use SIGQUIT to kill subprocesses because
// it's blocked. Use SIGKILL instead. See issue
// #19196 for an example of when this happens.
- sigquit = syscall.SIGKILL
+ testenv.Sigquit = syscall.SIGKILL
}
}