diff --git a/util/all_tests.go b/util/all_tests.go index a931c755d5..23bb8df670 100644 --- a/util/all_tests.go +++ b/util/all_tests.go @@ -100,14 +100,14 @@ var sdeCPUs = []string{ func targetArchMatchesRuntime(target string) bool { if (target == "") || - (target == "x86" && runtime.GOARCH == "amd64") || - (target == "arm" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64")) { + (target == "x86" && runtime.GOARCH == "amd64") || + (target == "arm" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64")) { return true } return false } -func valgrindOf(dbAttach bool, supps []string, path string, args ...string) *exec.Cmd { +func valgrindOf(ctx context.Context, dbAttach bool, supps []string, path string, args ...string) (context.Context, *exec.Cmd) { valgrindArgs := []string{"--error-exitcode=99", "--track-origins=yes", "--leak-check=full", "--trace-children=yes", "--quiet"} for _, supp := range supps { valgrindArgs = append(valgrindArgs, "--suppressions="+*valgrindSuppDir+"/"+supp) @@ -118,26 +118,26 @@ func valgrindOf(dbAttach bool, supps []string, path string, args ...string) *exe valgrindArgs = append(valgrindArgs, path) valgrindArgs = append(valgrindArgs, args...) - return exec.Command("valgrind", valgrindArgs...) + return ctx, exec.CommandContext(ctx, "valgrind", valgrindArgs...) } -func callgrindOf(path string, args ...string) *exec.Cmd { +func callgrindOf(ctx context.Context, path string, args ...string) (context.Context, *exec.Cmd) { valgrindArgs := []string{"-q", "--tool=callgrind", "--dump-instr=yes", "--collect-jumps=yes", "--callgrind-out-file=" + *buildDir + "/callgrind/callgrind.out.%p"} valgrindArgs = append(valgrindArgs, path) valgrindArgs = append(valgrindArgs, args...) - return exec.Command("valgrind", valgrindArgs...) + return ctx, exec.CommandContext(ctx, "valgrind", valgrindArgs...) } -func gdbOf(path string, args ...string) *exec.Cmd { +func gdbOf(ctx context.Context, path string, args ...string) (context.Context, *exec.Cmd) { xtermArgs := []string{"-e", "gdb", "--args"} xtermArgs = append(xtermArgs, path) xtermArgs = append(xtermArgs, args...) - return exec.Command("xterm", xtermArgs...) + return ctx, exec.CommandContext(ctx, "xterm", xtermArgs...) } -func sdeOf(cpu, path string, args ...string) (*exec.Cmd, context.CancelFunc) { +func sdeOf(ctx context.Context, cpu, path string, args ...string) (context.Context, context.CancelFunc, *exec.Cmd) { sdeArgs := []string{"-" + cpu} // The kernel's vdso code for gettimeofday sometimes uses the RDTSCP // instruction. Although SDE has a -chip_check_vsyscall flag that @@ -152,9 +152,9 @@ func sdeOf(cpu, path string, args ...string) (*exec.Cmd, context.CancelFunc) { // TODO(CryptoAlg-2154):SDE+ASAN tests will hang without exiting if tests pass for an unknown reason. // Current workaround is to manually cancel the run after 20 minutes and check the output. - ctx, cancel := context.WithTimeout(context.Background(), 1200*time.Second) + ctx, cancel := context.WithTimeout(ctx, 1200*time.Second) - return exec.CommandContext(ctx, *sdePath, sdeArgs...), cancel + return ctx, cancel, exec.CommandContext(ctx, *sdePath, sdeArgs...) } var ( @@ -173,23 +173,20 @@ func runTestOnce(test test, mallocNumToFail int64) (passed bool, err error) { } var cmd *exec.Cmd var cancel context.CancelFunc - cancelled := false + + ctx := context.Background() + if *useValgrind { - cmd = valgrindOf(false, test.ValgrindSupp, prog, args...) + ctx, cmd = valgrindOf(ctx, false, test.ValgrindSupp, prog, args...) } else if *useCallgrind { - cmd = callgrindOf(prog, args...) + ctx, cmd = callgrindOf(ctx, prog, args...) } else if *useGDB { - cmd = gdbOf(prog, args...) + ctx, cmd = gdbOf(ctx, prog, args...) } else if *useSDE { - cmd, cancel = sdeOf(test.cpu, prog, args...) + ctx, cancel, cmd = sdeOf(ctx, test.cpu, prog, args...) defer cancel() - - cmd.Cancel = func() error { - cancelled = true - return cmd.Process.Kill() - } } else { - cmd = exec.Command(prog, args...) + cmd = exec.CommandContext(ctx, prog, args...) } if test.Env != nil || test.numShards != 0 { cmd.Env = make([]string, len(os.Environ())) @@ -219,7 +216,8 @@ func runTestOnce(test test, mallocNumToFail int64) (passed bool, err error) { } if err := cmd.Wait(); err != nil { - if exitError, ok := err.(*exec.ExitError); ok { + var exitError *exec.ExitError + if errors.As(err, &exitError) { switch exitError.Sys().(syscall.WaitStatus).ExitStatus() { case 88: return false, errMoreMallocs @@ -227,15 +225,21 @@ func runTestOnce(test test, mallocNumToFail int64) (passed bool, err error) { fmt.Print(string(outBuf.Bytes())) return false, errTestSkipped } - if cancelled { - return testPass(outBuf), errTestHanging + select { + case <-ctx.Done(): + if errors.Is(ctx.Err(), context.DeadlineExceeded) { + return testPass(outBuf), errTestHanging + } else if ctx.Err() != nil { + return false, ctx.Err() + } + default: + // Nothing } } fmt.Print(string(outBuf.Bytes())) return false, err } - return testPass(outBuf), nil }