diff --git a/cmd/testwrapper/testwrapper.go b/cmd/testwrapper/testwrapper.go index d9d3cc7db..e35b83407 100644 --- a/cmd/testwrapper/testwrapper.go +++ b/cmd/testwrapper/testwrapper.go @@ -130,7 +130,10 @@ func runTests(ctx context.Context, attempt int, pt *packageTests, goTestArgs, te resultMap[pkg] = pkgTests } if goOutput.Test == "" { - if strings.HasSuffix(goOutput.Output, "\t(cached)\n") && goOutput.Package != "" { + // Detect output lines like: + // ok \ttailscale.com/cmd/testwrapper\t(cached) + // ok \ttailscale.com/cmd/testwrapper\t(cached)\tcoverage: 17.0% of statements + if goOutput.Package != "" && strings.Contains(goOutput.Output, fmt.Sprintf("%s\t(cached)", goOutput.Package)) { pkgCached[goOutput.Package] = true } switch goOutput.Action { diff --git a/cmd/testwrapper/testwrapper_test.go b/cmd/testwrapper/testwrapper_test.go index 0ca13e854..cf023f436 100644 --- a/cmd/testwrapper/testwrapper_test.go +++ b/cmd/testwrapper/testwrapper_test.go @@ -11,6 +11,7 @@ import ( "os/exec" "path/filepath" "regexp" + "runtime" "strings" "sync" "testing" @@ -214,6 +215,63 @@ func TestTimeout(t *testing.T) { } } +func TestCached(t *testing.T) { + t.Parallel() + + // Construct our trivial package. + pkgDir := t.TempDir() + goMod := fmt.Sprintf(`module example.com + +go %s +`, runtime.Version()[2:]) // strip leading "go" + + test := `package main +import "testing" + +func TestCached(t *testing.T) {} +` + + for f, c := range map[string]string{ + "go.mod": goMod, + "cached_test.go": test, + } { + err := os.WriteFile(filepath.Join(pkgDir, f), []byte(c), 0o644) + if err != nil { + t.Fatalf("writing package: %s", err) + } + } + + for name, args := range map[string][]string{ + "without_flags": {"./..."}, + "with_short": {"./...", "-short"}, + "with_coverprofile": {"./...", "-coverprofile=" + filepath.Join(t.TempDir(), "coverage.out")}, + } { + t.Run(name, func(t *testing.T) { + var ( + out []byte + err error + ) + for range 2 { + cmd := cmdTestwrapper(t, args...) + cmd.Dir = pkgDir + out, err = cmd.CombinedOutput() + if err != nil { + t.Fatalf("testwrapper ./...: expected no error but got: %v; output was:\n%s", err, out) + } + } + + want := []byte("ok\texample.com\t(cached)") + if !bytes.Contains(out, want) { + t.Fatalf("wanted output containing %q but got:\n%s", want, out) + } + + if testing.Verbose() { + t.Logf("success - output:\n%s", out) + } + }) + } +} + func errExitCode(err error) (int, bool) { var exit *exec.ExitError if errors.As(err, &exit) {