MCPcopy
hub / github.com/tailscale/tailscale / runOneTest

Function runOneTest

cmd/testwrapper/testwrapper.go:463–533  ·  view source on GitHub ↗

runOneTest runs a single test in a single package via `go test -run` with a per-attempt -timeout. It returns the test's outcome (outcomePass / outcomeFail / outcomeSkip), the wall-clock time spent on this attempt (used for the per-test retry budget), and any captured test logs. On panic, timeout, o

(ctx context.Context, pkg, testName string, perAttemptTimeout time.Duration, attemptNum int, goTestArgs, testArgs []string)

Source from the content-addressed store, hash-verified

461// On panic, timeout, or any other failure mode where the test does not emit a
462// pass/fail/skip JSON event, outcome is reported as outcomeFail.
463func runOneTest(ctx context.Context, pkg, testName string, perAttemptTimeout time.Duration, attemptNum int, goTestArgs, testArgs []string) (outcome testOutcome, wallDur time.Duration, logs bytes.Buffer, err error) {
464 goTestArgs, perAttemptTimeout = extractTimeout(goTestArgs, perAttemptTimeout)
465 testArgs, perAttemptTimeout = extractTimeout(testArgs, perAttemptTimeout)
466 args := []string{"test", "-json"}
467 args = append(args, goTestArgs...)
468 args = append(args, "-timeout", perAttemptTimeout.String())
469 args = append(args, pkg)
470 args = append(args, "--run", "^("+regexp.QuoteMeta(testName)+")$")
471 args = append(args, testArgs...)
472
473 if debug {
474 fmt.Println("running", strings.Join(args, " "))
475 }
476 cmd := exec.CommandContext(ctx, "go", args...)
477 // Strip TS_TEST_SHARD so the child doesn't try to shard inside a
478 // single-test retry — we are telling it exactly what to run.
479 cmd.Env = slices.DeleteFunc(os.Environ(), func(s string) bool {
480 return strings.HasPrefix(s, "TS_TEST_SHARD=")
481 })
482 cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%d", flakytest.FlakeAttemptEnv, attemptNum))
483 r, perr := cmd.StdoutPipe()
484 if perr != nil {
485 return "", 0, logs, fmt.Errorf("stdout pipe: %w", perr)
486 }
487 defer r.Close()
488 cmd.Stderr = os.Stderr
489
490 wallStart := time.Now()
491 if err := cmd.Start(); err != nil {
492 return "", 0, logs, fmt.Errorf("starting go test: %w", err)
493 }
494
495 s := bufio.NewScanner(r)
496 for s.Scan() {
497 var ev goTestOutput
498 if err := json.Unmarshal(s.Bytes(), &ev); err != nil {
499 continue
500 }
501 if ev.Test == "" {
502 continue // package-level events ignored for single-test runs
503 }
504 // Collapse subtests to parent.
505 parent, _, _ := strings.Cut(ev.Test, "/")
506 if parent != testName {
507 continue
508 }
509 switch ev.Action {
510 case "pass", "fail", "skip":
511 if ev.Test == testName {
512 outcome = testOutcome(ev.Action)
513 }
514 case "output":
515 logs.WriteString(ev.Output)
516 }
517 }
518 waitErr := cmd.Wait()
519 wallDur = time.Since(wallStart)
520 if scanErr := s.Err(); scanErr != nil && err == nil {

Callers 1

retryFailedTestFunction · 0.85

Calls 15

extractTimeoutFunction · 0.85
testOutcomeTypeAlias · 0.85
EnvironMethod · 0.80
StdoutPipeMethod · 0.80
ScanMethod · 0.80
BytesMethod · 0.80
WriteStringMethod · 0.80
StringMethod · 0.65
ErrorfMethod · 0.65
CloseMethod · 0.65
NowMethod · 0.65
StartMethod · 0.65

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…