diff options
Diffstat (limited to 'src/internal/testenv/testenv.go')
| -rw-r--r-- | src/internal/testenv/testenv.go | 158 |
1 files changed, 0 insertions, 158 deletions
diff --git a/src/internal/testenv/testenv.go b/src/internal/testenv/testenv.go index b61a44c855..6190000d02 100644 --- a/src/internal/testenv/testenv.go +++ b/src/internal/testenv/testenv.go @@ -11,7 +11,6 @@ package testenv import ( - "context" "errors" "flag" "fmt" @@ -26,7 +25,6 @@ import ( "strings" "sync" "testing" - "time" ) // Builder reports the name of the builder running this test @@ -217,16 +215,6 @@ func GoTool() (string, error) { return goBin, nil } -// HasExec reports whether the current system can start new processes -// using os.StartProcess or (more commonly) exec.Command. -func HasExec() bool { - switch runtime.GOOS { - case "js", "ios": - return false - } - return true -} - // HasSrc reports whether the entire source tree is available under GOROOT. func HasSrc() bool { switch runtime.GOOS { @@ -236,33 +224,6 @@ func HasSrc() bool { return true } -// MustHaveExec checks that the current system can start new processes -// using os.StartProcess or (more commonly) exec.Command. -// If not, MustHaveExec calls t.Skip with an explanation. -func MustHaveExec(t testing.TB) { - if !HasExec() { - t.Skipf("skipping test: cannot exec subprocess on %s/%s", runtime.GOOS, runtime.GOARCH) - } -} - -var execPaths sync.Map // path -> error - -// MustHaveExecPath checks that the current system can start the named executable -// using os.StartProcess or (more commonly) exec.Command. -// If not, MustHaveExecPath calls t.Skip with an explanation. -func MustHaveExecPath(t testing.TB, path string) { - MustHaveExec(t) - - err, found := execPaths.Load(path) - if !found { - _, err = exec.LookPath(path) - err, _ = execPaths.LoadOrStore(path, err) - } - if err != nil { - t.Skipf("skipping test: %s: %s", path, err) - } -} - // HasExternalNetwork reports whether the current system can use // external (non-localhost) networks. func HasExternalNetwork() bool { @@ -357,125 +318,6 @@ func SkipFlakyNet(t testing.TB) { } } -// CleanCmdEnv will fill cmd.Env with the environment, excluding certain -// variables that could modify the behavior of the Go tools such as -// GODEBUG and GOTRACEBACK. -func CleanCmdEnv(cmd *exec.Cmd) *exec.Cmd { - if cmd.Env != nil { - panic("environment already set") - } - for _, env := range os.Environ() { - // Exclude GODEBUG from the environment to prevent its output - // from breaking tests that are trying to parse other command output. - if strings.HasPrefix(env, "GODEBUG=") { - continue - } - // Exclude GOTRACEBACK for the same reason. - if strings.HasPrefix(env, "GOTRACEBACK=") { - continue - } - cmd.Env = append(cmd.Env, env) - } - return cmd -} - -// CommandContext is like exec.CommandContext, but: -// - skips t if the platform does not support os/exec, -// - sends SIGQUIT (if supported by the platform) instead of SIGKILL -// in its Cancel function -// - adds a timeout (with an arbitrary grace period) before the test's deadline expires, -// - sets a WaitDelay for an arbitrary grace period, -// - fails the test if the command does not complete before the test's deadline, and -// - sets a Cleanup function that verifies that the test did not leak a subprocess. -func CommandContext(t testing.TB, ctx context.Context, name string, args ...string) *exec.Cmd { - t.Helper() - MustHaveExec(t) - - var ( - gracePeriod = 100 * time.Millisecond - cancel context.CancelFunc - ) - if s := os.Getenv("GO_TEST_TIMEOUT_SCALE"); s != "" { - scale, err := strconv.Atoi(s) - if err != nil { - t.Fatalf("invalid GO_TEST_TIMEOUT_SCALE: %v", err) - } - gracePeriod *= time.Duration(scale) - } - - if t, ok := t.(interface { - testing.TB - Deadline() (time.Time, bool) - }); ok { - if td, ok := t.Deadline(); ok { - if cd, ok := ctx.Deadline(); !ok || cd.Sub(td) > gracePeriod { - // Either ctx doesn't have a deadline, or its deadline would expire - // after (or too close before) the test has already timed out. - // Compute a new timeout that will expire before the test does so that - // we can terminate the subprocess with a more useful signal. - - timeout := time.Until(td) - - // If time allows, increase the termination grace period to 5% of the - // remaining time. - if gp := timeout / 20; gp > gracePeriod { - gracePeriod = gp - } - - // When we run commands that execute subprocesses, we want to reserve two - // grace periods to clean up. We will send the first termination signal when - // the context expires, then wait one grace period for the process to - // produce whatever useful output it can (such as a stack trace). After the - // first grace period expires, we'll escalate to os.Kill, leaving the second - // grace period for the test function to record its output before the test - // process itself terminates. - timeout -= 2 * gracePeriod - - ctx, cancel = context.WithTimeout(ctx, timeout) - t.Cleanup(cancel) - } - } - } - - cmd := exec.CommandContext(ctx, name, args...) - cmd.Cancel = func() error { - if cancel != nil && ctx.Err() == context.DeadlineExceeded { - // The command timed out due to running too close to the test's deadline. - // There is no way the test did that intentionally — it's too close to the - // wire! — so mark it as a test failure. That way, if the test expects the - // command to fail for some other reason, it doesn't have to distinguish - // between that reason and a timeout. - t.Errorf("test timed out while running command: %v", cmd) - } else { - // The command is being terminated due to ctx being canceled, but - // apparently not due to an explicit test deadline that we added. - // Log that information in case it is useful for diagnosing a failure, - // but don't actually fail the test because of it. - t.Logf("%v: terminating command: %v", ctx.Err(), cmd) - } - return cmd.Process.Signal(Sigquit) - } - cmd.WaitDelay = gracePeriod - - t.Cleanup(func() { - if cancel != nil { - cancel() - } - if cmd.Process != nil && cmd.ProcessState == nil { - t.Errorf("command was started, but test did not wait for it to complete: %v", cmd) - } - }) - - return cmd -} - -// Command is like exec.Command, but applies the same changes as -// testenv.CommandContext (with a default Context). -func Command(t testing.TB, name string, args ...string) *exec.Cmd { - t.Helper() - return CommandContext(t, context.Background(), name, args...) -} - // CPUIsSlow reports whether the CPU running the test is suspected to be slow. func CPUIsSlow() bool { switch runtime.GOARCH { |
