1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
14 exec "internal/execabs"
27 "cmd/go/internal/base"
28 "cmd/go/internal/cache"
30 "cmd/go/internal/load"
31 "cmd/go/internal/lockedfile"
33 "cmd/go/internal/trace"
34 "cmd/go/internal/work"
35 "cmd/internal/test2json"
43 const testUsage = "go test [build/test flags] [packages] [build/test flags & test binary flags]"
45 var CmdTest = &base.Command{
48 Short: "test packages",
50 'Go test' automates testing the packages named by the import paths.
51 It prints a summary of the test results in the format:
54 FAIL archive/zip 0.022s
55 ok compress/gzip 0.033s
58 followed by detailed output for each failed package.
60 'Go test' recompiles each package along with any files with names matching
61 the file pattern "*_test.go".
62 These additional files can contain test functions, benchmark functions, and
63 example functions. See 'go help testfunc' for more.
64 Each listed package causes the execution of a separate test binary.
65 Files whose names begin with "_" (including "_test.go") or "." are ignored.
67 Test files that declare a package with the suffix "_test" will be compiled as a
68 separate package, and then linked and run with the main test binary.
70 The go tool will ignore a directory named "testdata", making it available
71 to hold ancillary data needed by the tests.
73 As part of building a test binary, go test runs go vet on the package
74 and its test source files to identify significant problems. If go vet
75 finds any problems, go test reports those and does not run the test
76 binary. Only a high-confidence subset of the default go vet checks are
77 used. That subset is: 'atomic', 'bool', 'buildtags', 'errorsas',
78 'ifaceassert', 'nilfunc', 'printf', and 'stringintconv'. You can see
79 the documentation for these and other vet tests via "go doc cmd/vet".
80 To disable the running of go vet, use the -vet=off flag.
82 All test output and summary lines are printed to the go command's
83 standard output, even if the test printed them to its own standard
84 error. (The go command's standard error is reserved for printing
85 errors building the tests.)
87 Go test runs in two different modes:
89 The first, called local directory mode, occurs when go test is
90 invoked with no package arguments (for example, 'go test' or 'go
91 test -v'). In this mode, go test compiles the package sources and
92 tests found in the current directory and then runs the resulting
93 test binary. In this mode, caching (discussed below) is disabled.
94 After the package test finishes, go test prints a summary line
95 showing the test status ('ok' or 'FAIL'), package name, and elapsed
98 The second, called package list mode, occurs when go test is invoked
99 with explicit package arguments (for example 'go test math', 'go
100 test ./...', and even 'go test .'). In this mode, go test compiles
101 and tests each of the packages listed on the command line. If a
102 package test passes, go test prints only the final 'ok' summary
103 line. If a package test fails, go test prints the full test output.
104 If invoked with the -bench or -v flag, go test prints the full
105 output even for passing package tests, in order to display the
106 requested benchmark results or verbose logging. After the package
107 tests for all of the listed packages finish, and their output is
108 printed, go test prints a final 'FAIL' status if any package test
111 In package list mode only, go test caches successful package test
112 results to avoid unnecessary repeated running of tests. When the
113 result of a test can be recovered from the cache, go test will
114 redisplay the previous output instead of running the test binary
115 again. When this happens, go test prints '(cached)' in place of the
116 elapsed time in the summary line.
118 The rule for a match in the cache is that the run involves the same
119 test binary and the flags on the command line come entirely from a
120 restricted set of 'cacheable' test flags, defined as -cpu, -list,
121 -parallel, -run, -short, and -v. If a run of go test has any test
122 or non-test flags outside this set, the result is not cached. To
123 disable test caching, use any test flag or argument other than the
124 cacheable flags. The idiomatic way to disable test caching explicitly
125 is to use -count=1. Tests that open files within the package's source
126 root (usually $GOPATH) or that consult environment variables only
127 match future runs in which the files and environment variables are unchanged.
128 A cached test result is treated as executing in no time at all,
129 so a successful package test result will be cached and reused
130 regardless of -timeout setting.
132 In addition to the build flags, the flags handled by 'go test' itself are:
135 Pass the remainder of the command line (everything after -args)
136 to the test binary, uninterpreted and unchanged.
137 Because this flag consumes the remainder of the command line,
138 the package list (if present) must appear before this flag.
141 Compile the test binary to pkg.test but do not run it
142 (where pkg is the last element of the package's import path).
143 The file name can be changed with the -o flag.
146 Run the test binary using xprog. The behavior is the same as
147 in 'go run'. See 'go help run' for details.
150 Install packages that are dependencies of the test.
152 The -i flag is deprecated. Compiled packages are cached automatically.
155 Convert test output to JSON suitable for automated processing.
156 See 'go doc test2json' for the encoding details.
159 Compile the test binary to the named file.
160 The test still runs (unless -c or -i is specified).
162 The test binary also accepts flags that control execution of the test; these
163 flags are also accessible by 'go test'. See 'go help testflag' for details.
165 For more about build flags, see 'go help build'.
166 For more about specifying packages, see 'go help packages'.
168 See also: go build, go vet.
172 var HelpTestflag = &base.Command{
173 UsageLine: "testflag",
174 Short: "testing flags",
176 The 'go test' command takes both flags that apply to 'go test' itself
177 and flags that apply to the resulting test binary.
179 Several of the flags control profiling and write an execution profile
180 suitable for "go tool pprof"; run "go tool pprof -h" for more
181 information. The --alloc_space, --alloc_objects, and --show_bytes
182 options of pprof control how the information is presented.
184 The following flags are recognized by the 'go test' command and
185 control the execution of any test:
188 Run only those benchmarks matching a regular expression.
189 By default, no benchmarks are run.
190 To run all benchmarks, use '-bench .' or '-bench=.'.
191 The regular expression is split by unbracketed slash (/)
192 characters into a sequence of regular expressions, and each
193 part of a benchmark's identifier must match the corresponding
194 element in the sequence, if any. Possible parents of matches
195 are run with b.N=1 to identify sub-benchmarks. For example,
196 given -bench=X/Y, top-level benchmarks matching X are run
197 with b.N=1 to find any sub-benchmarks matching Y, which are
201 Run enough iterations of each benchmark to take t, specified
202 as a time.Duration (for example, -benchtime 1h30s).
203 The default is 1 second (1s).
204 The special syntax Nx means to run the benchmark N times
205 (for example, -benchtime 100x).
208 Run each test and benchmark n times (default 1).
209 If -cpu is set, run n times for each GOMAXPROCS value.
210 Examples are always run once.
213 Enable coverage analysis.
214 Note that because coverage works by annotating the source
215 code before compilation, compilation and test failures with
216 coverage enabled may report line numbers that don't correspond
217 to the original sources.
219 -covermode set,count,atomic
220 Set the mode for coverage analysis for the package[s]
221 being tested. The default is "set" unless -race is enabled,
222 in which case it is "atomic".
224 set: bool: does this statement run?
225 count: int: how many times does this statement run?
226 atomic: int: count, but correct in multithreaded tests;
227 significantly more expensive.
230 -coverpkg pattern1,pattern2,pattern3
231 Apply coverage analysis in each test to packages matching the patterns.
232 The default is for each test to analyze only the package being tested.
233 See 'go help packages' for a description of package patterns.
237 Specify a list of GOMAXPROCS values for which the tests or
238 benchmarks should be executed. The default is the current value
242 Do not start new tests after the first test failure.
245 List tests, benchmarks, or examples matching the regular expression.
246 No tests, benchmarks or examples will be run. This will only
247 list top-level tests. No subtest or subbenchmarks will be shown.
250 Allow parallel execution of test functions that call t.Parallel.
251 The value of this flag is the maximum number of tests to run
252 simultaneously; by default, it is set to the value of GOMAXPROCS.
253 Note that -parallel only applies within a single test binary.
254 The 'go test' command may run tests for different packages
255 in parallel as well, according to the setting of the -p flag
256 (see 'go help build').
259 Run only those tests and examples matching the regular expression.
260 For tests, the regular expression is split by unbracketed slash (/)
261 characters into a sequence of regular expressions, and each part
262 of a test's identifier must match the corresponding element in
263 the sequence, if any. Note that possible parents of matches are
264 run too, so that -run=X/Y matches and runs and reports the result
265 of all tests matching X, even those without sub-tests matching Y,
266 because it must run them to look for those sub-tests.
269 Tell long-running tests to shorten their run time.
270 It is off by default but set during all.bash so that installing
271 the Go tree can run a sanity check but not spend time running
275 If a test binary runs longer than duration d, panic.
276 If d is 0, the timeout is disabled.
277 The default is 10 minutes (10m).
280 Verbose output: log all tests as they are run. Also print all
281 text from Log and Logf calls even if the test succeeds.
284 Configure the invocation of "go vet" during "go test"
285 to use the comma-separated list of vet checks.
286 If list is empty, "go test" runs "go vet" with a curated list of
287 checks believed to be always worth addressing.
288 If list is "off", "go test" does not run "go vet" at all.
290 The following flags are also recognized by 'go test' and can be used to
291 profile the tests during execution:
294 Print memory allocation statistics for benchmarks.
296 -blockprofile block.out
297 Write a goroutine blocking profile to the specified file
298 when all tests are complete.
299 Writes test binary as -c would.
302 Control the detail provided in goroutine blocking profiles by
303 calling runtime.SetBlockProfileRate with n.
304 See 'go doc runtime.SetBlockProfileRate'.
305 The profiler aims to sample, on average, one blocking event every
306 n nanoseconds the program spends blocked. By default,
307 if -test.blockprofile is set without this flag, all blocking events
308 are recorded, equivalent to -test.blockprofilerate=1.
310 -coverprofile cover.out
311 Write a coverage profile to the file after all tests have passed.
315 Write a CPU profile to the specified file before exiting.
316 Writes test binary as -c would.
319 Write an allocation profile to the file after all tests have passed.
320 Writes test binary as -c would.
323 Enable more precise (and expensive) memory allocation profiles by
324 setting runtime.MemProfileRate. See 'go doc runtime.MemProfileRate'.
325 To profile all memory allocations, use -test.memprofilerate=1.
327 -mutexprofile mutex.out
328 Write a mutex contention profile to the specified file
329 when all tests are complete.
330 Writes test binary as -c would.
332 -mutexprofilefraction n
333 Sample 1 in n stack traces of goroutines holding a
337 Place output files from profiling in the specified directory,
338 by default the directory in which "go test" is running.
341 Write an execution trace to the specified file before exiting.
343 Each of these flags is also recognized with an optional 'test.' prefix,
344 as in -test.v. When invoking the generated test binary (the result of
345 'go test -c') directly, however, the prefix is mandatory.
347 The 'go test' command rewrites or removes recognized flags,
348 as appropriate, both before and after the optional package list,
349 before invoking the test binary.
351 For instance, the command
353 go test -v -myflag testdata -cpuprofile=prof.out -x
355 will compile the test binary and then run it as
357 pkg.test -test.v -myflag testdata -test.cpuprofile=prof.out
359 (The -x flag is removed because it applies only to the go command's
360 execution, not to the test itself.)
362 The test flags that generate profiles (other than for coverage) also
363 leave the test binary in pkg.test for use when analyzing the profiles.
365 When 'go test' runs a test binary, it does so from within the
366 corresponding package's source code directory. Depending on the test,
367 it may be necessary to do the same when invoking a generated test
370 The command-line package list, if present, must appear before any
371 flag not known to the go test command. Continuing the example above,
372 the package list would have to appear before -myflag, but could appear
373 on either side of -v.
375 When 'go test' runs in package list mode, 'go test' caches successful
376 package test results to avoid unnecessary repeated running of tests. To
377 disable test caching, use any test flag or argument other than the
378 cacheable flags. The idiomatic way to disable test caching explicitly
381 To keep an argument for a test binary from being interpreted as a
382 known flag or a package name, use -args (see 'go help test') which
383 passes the remainder of the command line through to the test binary
384 uninterpreted and unaltered.
386 For instance, the command
388 go test -v -args -x -v
390 will compile the test binary and then run it as
392 pkg.test -test.v -x -v
398 will compile the test binary and then run it as
402 In the first example, the -x and the second -v are passed through to the
403 test binary unchanged and with no effect on the go command itself.
404 In the second example, the argument math is passed through to the test
405 binary, instead of being interpreted as the package list.
409 var HelpTestfunc = &base.Command{
410 UsageLine: "testfunc",
411 Short: "testing functions",
413 The 'go test' command expects to find test, benchmark, and example functions
414 in the "*_test.go" files corresponding to the package under test.
416 A test function is one named TestXxx (where Xxx does not start with a
417 lower case letter) and should have the signature,
419 func TestXxx(t *testing.T) { ... }
421 A benchmark function is one named BenchmarkXxx and should have the signature,
423 func BenchmarkXxx(b *testing.B) { ... }
425 An example function is similar to a test function but, instead of using
426 *testing.T to report success or failure, prints output to os.Stdout.
427 If the last comment in the function starts with "Output:" then the output
428 is compared exactly against the comment (see examples below). If the last
429 comment begins with "Unordered output:" then the output is compared to the
430 comment, however the order of the lines is ignored. An example with no such
431 comment is compiled but not executed. An example with no text after
432 "Output:" is compiled, executed, and expected to produce no output.
434 Godoc displays the body of ExampleXxx to demonstrate the use
435 of the function, constant, or variable Xxx. An example of a method M with
436 receiver type T or *T is named ExampleT_M. There may be multiple examples
437 for a given function, constant, or variable, distinguished by a trailing _xxx,
438 where xxx is a suffix not beginning with an upper case letter.
440 Here is an example of an example:
442 func ExamplePrintln() {
443 Println("The output of\nthis example.")
444 // Output: The output of
448 Here is another example where the ordering of the output is ignored:
451 for _, value := range Perm(4) {
455 // Unordered output: 4
462 The entire test file is presented as the example when it contains a single
463 example function, at least one other function, type, variable, or constant
464 declaration, and no test or benchmark functions.
466 See the documentation of the testing package for more information.
471 testBench string // -bench flag
472 testC bool // -c flag
473 testCover bool // -cover flag
474 testCoverMode string // -covermode flag
475 testCoverPaths []string // -coverpkg flag
476 testCoverPkgs []*load.Package // -coverpkg flag
477 testCoverProfile string // -coverprofile flag
478 testFuzz string // -fuzz flag
479 testJSON bool // -json flag
480 testList string // -list flag
481 testO string // -o flag
482 testOutputDir = base.Cwd // -outputdir flag
483 testTimeout time.Duration // -timeout flag
484 testV bool // -v flag
485 testVet = vetFlag{flags: defaultVetFlags} // -vet flag
493 testHelp bool // -help option passed to test via -args
495 testKillTimeout = 100 * 365 * 24 * time.Hour // backup alarm; defaults to about a century if no timeout is set
496 testCacheExpire time.Time // ignore cached test results before this time
498 testBlockProfile, testCPUProfile, testMemProfile, testMutexProfile, testTrace string // profiling flag that limits test to one package
501 // testProfile returns the name of an arbitrary single-package profiling flag
502 // that is set, if any.
503 func testProfile() string {
505 case testBlockProfile != "":
506 return "-blockprofile"
507 case testCPUProfile != "":
509 case testMemProfile != "":
511 case testMutexProfile != "":
512 return "-mutexprofile"
513 case testTrace != "":
520 // testNeedBinary reports whether the test needs to keep the binary around.
521 func testNeedBinary() bool {
523 case testBlockProfile != "":
525 case testCPUProfile != "":
527 case testMemProfile != "":
529 case testMutexProfile != "":
538 // testShowPass reports whether the output for a passing test should be shown.
539 func testShowPass() bool {
540 return testV || (testList != "") || testHelp
543 var defaultVetFlags = []string{
544 // TODO(rsc): Decide which tests are enabled by default.
545 // See golang.org/issue/18085.
571 func runTest(ctx context.Context, cmd *base.Command, args []string) {
572 load.ModResolveTests = true
574 pkgArgs, testArgs = testFlags(args)
576 if cfg.DebugTrace != "" {
577 var close func() error
579 ctx, close, err = trace.Start(ctx, cfg.DebugTrace)
581 base.Fatalf("failed to start trace: %v", err)
584 if err := close(); err != nil {
585 base.Fatalf("failed to stop trace: %v", err)
590 ctx, span := trace.StartSpan(ctx, fmt.Sprint("Running ", cmd.Name(), " command"))
593 work.FindExecCmd() // initialize cached result
596 work.VetFlags = testVet.flags
597 work.VetExplicit = testVet.explicit
599 pkgs = load.PackagesAndErrors(ctx, pkgArgs)
600 load.CheckPackageErrors(pkgs)
602 base.Fatalf("no packages to test")
605 if testC && len(pkgs) != 1 {
606 base.Fatalf("cannot use -c flag with multiple packages")
608 if testO != "" && len(pkgs) != 1 {
609 base.Fatalf("cannot use -o flag with multiple packages")
611 if testProfile() != "" && len(pkgs) != 1 {
612 base.Fatalf("cannot use %s flag with multiple packages", testProfile())
615 defer closeCoverProfile()
617 // If a test timeout is finite, set our kill timeout
618 // to that timeout plus one minute. This is a backup alarm in case
619 // the test wedges with a goroutine spinning and its background
620 // timer does not get a chance to fire.
622 testKillTimeout = testTimeout + 1*time.Minute
625 // For 'go test -i -o x.test', we want to build x.test. Imply -c to make the logic easier.
626 if cfg.BuildI && testO != "" {
630 // Read testcache expiration time, if present.
631 // (We implement go clean -testcache by writing an expiration date
632 // instead of searching out and deleting test result cache entries.)
633 if dir := cache.DefaultDir(); dir != "off" {
634 if data, _ := lockedfile.Read(filepath.Join(dir, "testexpire.txt")); len(data) > 0 && data[len(data)-1] == '\n' {
635 if t, err := strconv.ParseInt(string(data[:len(data)-1]), 10, 64); err == nil {
636 testCacheExpire = time.Unix(0, t)
645 fmt.Fprint(os.Stderr, "go test: -i flag is deprecated\n")
648 deps := make(map[string]bool)
649 for _, dep := range load.TestMainDeps {
653 for _, p := range pkgs {
654 // Dependencies for each test.
655 for _, path := range p.Imports {
658 for _, path := range p.Resolve(p.TestImports) {
661 for _, path := range p.Resolve(p.XTestImports) {
666 // translate C to runtime/cgo
669 deps["runtime/cgo"] = true
671 // Ignore pseudo-packages.
672 delete(deps, "unsafe")
675 for path := range deps {
676 if !build.IsLocalImport(path) {
677 all = append(all, path)
682 a := &work.Action{Mode: "go test -i"}
683 pkgs := load.PackagesAndErrors(ctx, all)
684 load.CheckPackageErrors(pkgs)
685 for _, p := range pkgs {
686 if cfg.BuildToolchainName == "gccgo" && p.Standard {
687 // gccgo's standard library packages
688 // can not be reinstalled.
691 a.Deps = append(a.Deps, b.CompileAction(work.ModeInstall, work.ModeInstall, p))
694 if !testC || a.Failed {
700 var builds, runs, prints []*work.Action
702 if testCoverPaths != nil {
703 match := make([]func(*load.Package) bool, len(testCoverPaths))
704 matched := make([]bool, len(testCoverPaths))
705 for i := range testCoverPaths {
706 match[i] = load.MatchPackage(testCoverPaths[i], base.Cwd)
709 // Select for coverage all dependencies matching the testCoverPaths patterns.
710 for _, p := range load.TestPackageList(ctx, pkgs) {
712 for i := range testCoverPaths {
719 // Silently ignore attempts to run coverage on
720 // sync/atomic when using atomic coverage mode.
721 // Atomic coverage mode uses sync/atomic, so
722 // we can't also do coverage on it.
723 if testCoverMode == "atomic" && p.Standard && p.ImportPath == "sync/atomic" {
727 // If using the race detector, silently ignore
728 // attempts to run coverage on the runtime
729 // packages. It will cause the race detector
730 // to be invoked before it has been initialized.
731 if cfg.BuildRace && p.Standard && (p.ImportPath == "runtime" || strings.HasPrefix(p.ImportPath, "runtime/internal")) {
736 testCoverPkgs = append(testCoverPkgs, p)
740 // Warn about -coverpkg arguments that are not actually used.
741 for i := range testCoverPaths {
743 fmt.Fprintf(os.Stderr, "warning: no packages being tested depend on matches for pattern %s\n", testCoverPaths[i])
747 // Mark all the coverage packages for rebuilding with coverage.
748 for _, p := range testCoverPkgs {
749 // There is nothing to cover in package unsafe; it comes from the compiler.
750 if p.ImportPath == "unsafe" {
753 p.Internal.CoverMode = testCoverMode
754 var coverFiles []string
755 coverFiles = append(coverFiles, p.GoFiles...)
756 coverFiles = append(coverFiles, p.CgoFiles...)
757 coverFiles = append(coverFiles, p.TestGoFiles...)
758 p.Internal.CoverVars = declareCoverVars(p, coverFiles...)
759 if testCover && testCoverMode == "atomic" {
760 ensureImport(p, "sync/atomic")
765 // Prepare build + run + print actions for all packages being tested.
766 for _, p := range pkgs {
767 // sync/atomic import is inserted by the cover tool. See #18486
768 if testCover && testCoverMode == "atomic" {
769 ensureImport(p, "sync/atomic")
772 buildTest, runTest, printTest, err := builderTest(&b, ctx, p)
775 str = strings.TrimPrefix(str, "\n")
776 if p.ImportPath != "" {
777 base.Errorf("# %s\n%s", p.ImportPath, str)
779 base.Errorf("%s", str)
781 fmt.Printf("FAIL\t%s [setup failed]\n", p.ImportPath)
784 builds = append(builds, buildTest)
785 runs = append(runs, runTest)
786 prints = append(prints, printTest)
789 // Ultimately the goal is to print the output.
790 root := &work.Action{Mode: "go test", Func: printExitStatus, Deps: prints}
792 // Force the printing of results to happen in order,
794 for i, a := range prints {
796 a.Deps = append(a.Deps, prints[i-1])
800 // Force benchmarks to run in serial.
801 if !testC && (testBench != "") {
802 // The first run must wait for all builds.
803 // Later runs must wait for the previous run's print.
804 for i, run := range runs {
806 run.Deps = append(run.Deps, builds...)
808 run.Deps = append(run.Deps, prints[i-1])
816 // ensures that package p imports the named package
817 func ensureImport(p *load.Package, pkg string) {
818 for _, d := range p.Internal.Imports {
824 p1 := load.LoadImportWithFlags(pkg, p.Dir, p, &load.ImportStack{}, nil, 0)
826 base.Fatalf("load %s: %v", pkg, p1.Error)
829 p.Internal.Imports = append(p.Internal.Imports, p1)
832 var windowsBadWords = []string{
839 func builderTest(b *work.Builder, ctx context.Context, p *load.Package) (buildAction, runAction, printAction *work.Action, err error) {
840 if len(p.TestGoFiles)+len(p.XTestGoFiles) == 0 {
841 build := b.CompileAction(work.ModeBuild, work.ModeBuild, p)
842 run := &work.Action{Mode: "test run", Package: p, Deps: []*work.Action{build}}
843 addTestVet(b, p, run, nil)
844 print := &work.Action{Mode: "test print", Func: builderNoTest, Package: p, Deps: []*work.Action{run}}
845 return build, run, print, nil
848 // Build Package structs describing:
849 // pmain - pkg.test binary
850 // ptest - package + test files
851 // pxtest - package of external test files
852 var cover *load.TestCover
854 cover = &load.TestCover{
856 Local: testCover && testCoverPaths == nil,
858 Paths: testCoverPaths,
859 DeclVars: declareCoverVars,
862 pmain, ptest, pxtest, err := load.TestPackagesFor(ctx, p, cover)
864 return nil, nil, nil, err
867 // Use last element of import path, not package name.
868 // They differ when package name is "main".
869 // But if the import path is "command-line-arguments",
870 // like it is during 'go run', use the package name.
872 if p.ImportPath == "command-line-arguments" {
875 elem = p.DefaultExecName()
877 testBinary := elem + ".test"
879 testDir := b.NewObjdir()
880 if err := b.Mkdir(testDir); err != nil {
881 return nil, nil, nil, err
885 pmain.Internal.OmitDebug = !testC && !testNeedBinary()
888 // writeTestmain writes _testmain.go,
889 // using the test description gathered in t.
890 if err := os.WriteFile(testDir+"_testmain.go", *pmain.Internal.TestmainGo, 0666); err != nil {
891 return nil, nil, nil, err
895 // Set compile objdir to testDir we've already created,
896 // so that the default file path stripping applies to _testmain.go.
897 b.CompileAction(work.ModeBuild, work.ModeBuild, pmain).Objdir = testDir
899 a := b.LinkAction(work.ModeBuild, work.ModeBuild, pmain)
900 a.Target = testDir + testBinary + cfg.ExeSuffix
901 if cfg.Goos == "windows" {
902 // There are many reserved words on Windows that,
903 // if used in the name of an executable, cause Windows
904 // to try to ask for extra permissions.
905 // The word list includes setup, install, update, and patch,
906 // but it does not appear to be defined anywhere.
907 // We have run into this trying to run the
908 // go.codereview/patch tests.
909 // For package names containing those words, use test.test.exe
910 // instead of pkgname.test.exe.
911 // Note that this file name is only used in the Go command's
912 // temporary directory. If the -c or other flags are
913 // given, the code below will still use pkgname.test.exe.
914 // There are two user-visible effects of this change.
915 // First, you can actually run 'go test' in directories that
916 // have names that Windows thinks are installer-like,
917 // without getting a dialog box asking for more permissions.
918 // Second, in the Windows process listing during go test,
919 // the test shows up as test.test.exe, not pkgname.test.exe.
920 // That second one is a drawback, but it seems a small
921 // price to pay for the test running at all.
922 // If maintaining the list of bad words is too onerous,
923 // we could just do this always on Windows.
924 for _, bad := range windowsBadWords {
925 if strings.Contains(testBinary, bad) {
926 a.Target = testDir + "test.test" + cfg.ExeSuffix
932 var installAction, cleanAction *work.Action
933 if testC || testNeedBinary() {
934 // -c or profiling flag: create action to copy binary to ./test.out.
935 target := filepath.Join(base.Cwd, testBinary+cfg.ExeSuffix)
938 if !filepath.IsAbs(target) {
939 target = filepath.Join(base.Cwd, target)
942 if target == os.DevNull {
943 runAction = buildAction
945 pmain.Target = target
946 installAction = &work.Action{
948 Func: work.BuildInstallFunc,
949 Deps: []*work.Action{buildAction},
953 runAction = installAction // make sure runAction != nil even if not running test
956 var vetRunAction *work.Action
958 printAction = &work.Action{Mode: "test print (nop)", Package: p, Deps: []*work.Action{runAction}} // nop
959 vetRunAction = printAction
963 runAction = &work.Action{
965 Func: c.builderRunTest,
966 Deps: []*work.Action{buildAction},
968 IgnoreFail: true, // run (prepare output) even if build failed
969 TryCache: c.tryCache,
972 vetRunAction = runAction
973 cleanAction = &work.Action{
975 Func: builderCleanTest,
976 Deps: []*work.Action{runAction},
978 IgnoreFail: true, // clean even if test failed
981 printAction = &work.Action{
983 Func: builderPrintTest,
984 Deps: []*work.Action{cleanAction},
986 IgnoreFail: true, // print even if test failed
990 if len(ptest.GoFiles)+len(ptest.CgoFiles) > 0 {
991 addTestVet(b, ptest, vetRunAction, installAction)
994 addTestVet(b, pxtest, vetRunAction, installAction)
997 if installAction != nil {
998 if runAction != installAction {
999 installAction.Deps = append(installAction.Deps, runAction)
1001 if cleanAction != nil {
1002 cleanAction.Deps = append(cleanAction.Deps, installAction)
1006 return buildAction, runAction, printAction, nil
1009 func addTestVet(b *work.Builder, p *load.Package, runAction, installAction *work.Action) {
1014 vet := b.VetAction(work.ModeBuild, work.ModeBuild, p)
1015 runAction.Deps = append(runAction.Deps, vet)
1016 // Install will clean the build directory.
1017 // Make sure vet runs first.
1018 // The install ordering in b.VetAction does not apply here
1019 // because we are using a custom installAction (created above).
1020 if installAction != nil {
1021 installAction.Deps = append(installAction.Deps, vet)
1025 // isTestFile reports whether the source file is a set of tests and should therefore
1026 // be excluded from coverage analysis.
1027 func isTestFile(file string) bool {
1028 // We don't cover tests, only the code they test.
1029 return strings.HasSuffix(file, "_test.go")
1032 // declareCoverVars attaches the required cover variables names
1033 // to the files, to be used when annotating the files.
1034 func declareCoverVars(p *load.Package, files ...string) map[string]*load.CoverVar {
1035 coverVars := make(map[string]*load.CoverVar)
1037 // We create the cover counters as new top-level variables in the package.
1038 // We need to avoid collisions with user variables (GoCover_0 is unlikely but still)
1039 // and more importantly with dot imports of other covered packages,
1040 // so we append 12 hex digits from the SHA-256 of the import path.
1041 // The point is only to avoid accidents, not to defeat users determined to
1043 sum := sha256.Sum256([]byte(p.ImportPath))
1044 h := fmt.Sprintf("%x", sum[:6])
1045 for _, file := range files {
1046 if isTestFile(file) {
1049 // For a package that is "local" (imported via ./ import or command line, outside GOPATH),
1050 // we record the full path to the file name.
1051 // Otherwise we record the import path, then a forward slash, then the file name.
1052 // This makes profiles within GOPATH file system-independent.
1053 // These names appear in the cmd/cover HTML interface.
1055 if p.Internal.Local {
1056 longFile = filepath.Join(p.Dir, file)
1058 longFile = path.Join(p.ImportPath, file)
1060 coverVars[file] = &load.CoverVar{
1062 Var: fmt.Sprintf("GoCover_%d_%x", coverIndex, h),
1069 var noTestsToRun = []byte("\ntesting: warning: no tests to run\n")
1070 var noTargetsToFuzz = []byte("\ntesting: warning: no targets to fuzz\n")
1071 var tooManyTargetsToFuzz = []byte("\ntesting: warning: -fuzz matches more than one target, won't fuzz\n")
1073 type runCache struct {
1074 disableCache bool // cache should be disabled for this run
1081 // stdoutMu and lockedStdout provide a locked standard output
1082 // that guarantees never to interlace writes from multiple
1083 // goroutines, so that we can have multiple JSON streams writing
1084 // to a lockedStdout simultaneously and know that events will
1085 // still be intelligible.
1086 var stdoutMu sync.Mutex
1088 type lockedStdout struct{}
1090 func (lockedStdout) Write(b []byte) (int, error) {
1092 defer stdoutMu.Unlock()
1093 return os.Stdout.Write(b)
1096 // builderRunTest is the action for running a test binary.
1097 func (c *runCache) builderRunTest(b *work.Builder, ctx context.Context, a *work.Action) error {
1099 // We were unable to build the binary.
1101 a.TestOutput = new(bytes.Buffer)
1102 fmt.Fprintf(a.TestOutput, "FAIL\t%s [build failed]\n", a.Package.ImportPath)
1103 base.SetExitStatus(1)
1107 var stdout io.Writer = os.Stdout
1110 json := test2json.NewConverter(lockedStdout{}, a.Package.ImportPath, test2json.Timestamp)
1118 var buf bytes.Buffer
1119 if len(pkgArgs) == 0 || (testBench != "") {
1120 // Stream test output (no buffering) when no package has
1121 // been given on the command line (implicit current directory)
1122 // or when benchmarking.
1123 // No change to stdout.
1125 // If we're only running a single package under test or if parallelism is
1126 // set to 1, and if we're displaying all output (testShowPass), we can
1127 // hurry the output along, echoing it as soon as it comes in.
1128 // We still have to copy to &buf for caching the result. This special
1129 // case was introduced in Go 1.5 and is intentionally undocumented:
1130 // the exact details of output buffering are up to the go command and
1131 // subject to change. It would be nice to remove this special case
1132 // entirely, but it is surely very helpful to see progress being made
1133 // when tests are run on slow single-CPU ARM systems.
1135 // If we're showing JSON output, then display output as soon as
1136 // possible even when multiple tests are being run: the JSON output
1137 // events are attributed to specific package tests, so interlacing them
1139 if testShowPass() && (len(pkgs) == 1 || cfg.BuildP == 1) || testJSON {
1140 // Write both to stdout and buf, for possible saving
1141 // to cache, and for looking for the "no tests to run" message.
1142 stdout = io.MultiWriter(stdout, &buf)
1149 // We did not find a cached result using the link step action ID,
1150 // so we ran the link step. Try again now with the link output
1151 // content ID. The attempt using the action ID makes sure that
1152 // if the link inputs don't change, we reuse the cached test
1153 // result without even rerunning the linker. The attempt using
1154 // the link output (test binary) content ID makes sure that if
1155 // we have different link inputs but the same final binary,
1156 // we still reuse the cached test result.
1157 // c.saveOutput will store the result under both IDs.
1158 c.tryCacheWithID(b, a, a.Deps[0].BuildContentID())
1162 stdout.Write(c.buf.Bytes())
1165 a.TestOutput = c.buf
1169 execCmd := work.FindExecCmd()
1170 testlogArg := []string{}
1171 if !c.disableCache && len(execCmd) == 0 {
1172 testlogArg = []string{"-test.testlogfile=" + a.Objdir + "testlog.txt"}
1174 panicArg := "-test.paniconexit0"
1175 fuzzArg := []string{}
1177 fuzzCacheDir := filepath.Join(cache.Default().FuzzDir(), a.Package.ImportPath)
1178 fuzzArg = []string{"-test.fuzzcachedir=" + fuzzCacheDir}
1180 args := str.StringList(execCmd, a.Deps[0].BuiltTarget(), testlogArg, panicArg, fuzzArg, testArgs)
1182 if testCoverProfile != "" {
1183 // Write coverage to temporary profile, for merging later.
1184 for i, arg := range args {
1185 if strings.HasPrefix(arg, "-test.coverprofile=") {
1186 args[i] = "-test.coverprofile=" + a.Objdir + "_cover_.out"
1191 if cfg.BuildN || cfg.BuildX {
1192 b.Showcmd("", "%s", strings.Join(args, " "))
1198 cmd := exec.Command(args[0], args[1:]...)
1199 cmd.Dir = a.Package.Dir
1200 cmd.Env = base.AppendPWD(cfg.OrigEnv[:len(cfg.OrigEnv):len(cfg.OrigEnv)], cmd.Dir)
1204 // If there are any local SWIG dependencies, we want to load
1205 // the shared library from the build directory.
1206 if a.Package.UsesSwig() {
1209 prefix := "LD_LIBRARY_PATH="
1210 for i, v := range env {
1211 if strings.HasPrefix(v, prefix) {
1218 env = append(env, "LD_LIBRARY_PATH=.")
1226 // This is a last-ditch deadline to detect and
1227 // stop wedged test binaries, to keep the builders
1230 tick := time.NewTimer(testKillTimeout)
1231 base.StartSigHandlers()
1232 done := make(chan error)
1241 if base.SignalTrace != nil {
1242 // Send a quit signal in the hope that the program will print
1243 // a stack trace and exit. Give it five seconds before resorting
1245 cmd.Process.Signal(base.SignalTrace)
1248 fmt.Fprintf(cmd.Stdout, "*** Test killed with %v: ran too long (%v).\n", base.SignalTrace, testKillTimeout)
1250 case <-time.After(5 * time.Second):
1255 fmt.Fprintf(cmd.Stdout, "*** Test killed: ran too long (%v).\n", testKillTimeout)
1261 t := fmt.Sprintf("%.3fs", time.Since(t0).Seconds())
1263 mergeCoverProfile(cmd.Stdout, a.Objdir+"_cover_.out")
1267 if !testShowPass() && !testJSON {
1270 if bytes.HasPrefix(out, noTestsToRun[1:]) || bytes.Contains(out, noTestsToRun) {
1271 norun = " [no tests to run]"
1273 if bytes.HasPrefix(out, noTargetsToFuzz[1:]) || bytes.Contains(out, noTargetsToFuzz) {
1274 norun = " [no targets to fuzz]"
1276 if bytes.HasPrefix(out, tooManyTargetsToFuzz[1:]) || bytes.Contains(out, tooManyTargetsToFuzz) {
1277 norun = " [will not fuzz, -fuzz matches more than one target]"
1279 fmt.Fprintf(cmd.Stdout, "ok \t%s\t%s%s%s\n", a.Package.ImportPath, t, coveragePercentage(out), norun)
1282 base.SetExitStatus(1)
1283 // If there was test output, assume we don't need to print the exit status.
1284 // Buf there's no test output, do print the exit status.
1286 fmt.Fprintf(cmd.Stdout, "%s\n", err)
1288 // NOTE(golang.org/issue/37555): test2json reports that a test passes
1289 // unless "FAIL" is printed at the beginning of a line. The test may not
1290 // actually print that if it panics, exits, or terminates abnormally,
1291 // so we print it here. We can't always check whether it was printed
1292 // because some tests need stdout to be a terminal (golang.org/issue/34791),
1294 // TODO(golang.org/issue/29062): tests that exit with status 0 without
1295 // printing a final result should fail.
1296 fmt.Fprintf(cmd.Stdout, "FAIL\t%s\t%s\n", a.Package.ImportPath, t)
1299 if cmd.Stdout != &buf {
1300 buf.Reset() // cmd.Stdout was going to os.Stdout already
1305 // tryCache is called just before the link attempt,
1306 // to see if the test result is cached and therefore the link is unneeded.
1307 // It reports whether the result can be satisfied from cache.
1308 func (c *runCache) tryCache(b *work.Builder, a *work.Action) bool {
1309 return c.tryCacheWithID(b, a, a.Deps[0].BuildActionID())
1312 func (c *runCache) tryCacheWithID(b *work.Builder, a *work.Action, id string) bool {
1313 if len(pkgArgs) == 0 {
1314 // Caching does not apply to "go test",
1315 // only to "go test foo" (including "go test .").
1316 if cache.DebugTest {
1317 fmt.Fprintf(os.Stderr, "testcache: caching disabled in local directory mode\n")
1319 c.disableCache = true
1323 if a.Package.Root == "" {
1324 // Caching does not apply to tests outside of any module, GOPATH, or GOROOT.
1325 if cache.DebugTest {
1326 fmt.Fprintf(os.Stderr, "testcache: caching disabled for package outside of module root, GOPATH, or GOROOT: %s\n", a.Package.ImportPath)
1328 c.disableCache = true
1332 var cacheArgs []string
1333 for _, arg := range testArgs {
1334 i := strings.Index(arg, "=")
1335 if i < 0 || !strings.HasPrefix(arg, "-test.") {
1336 if cache.DebugTest {
1337 fmt.Fprintf(os.Stderr, "testcache: caching disabled for test argument: %s\n", arg)
1339 c.disableCache = true
1350 // These are cacheable.
1351 // Note that this list is documented above,
1352 // so if you add to this list, update the docs too.
1353 cacheArgs = append(cacheArgs, arg)
1356 // nothing else is cacheable
1357 if cache.DebugTest {
1358 fmt.Fprintf(os.Stderr, "testcache: caching disabled for test argument: %s\n", arg)
1360 c.disableCache = true
1365 if cache.Default() == nil {
1366 if cache.DebugTest {
1367 fmt.Fprintf(os.Stderr, "testcache: GOCACHE=off\n")
1369 c.disableCache = true
1373 // The test cache result fetch is a two-level lookup.
1375 // First, we use the content hash of the test binary
1376 // and its command-line arguments to find the
1377 // list of environment variables and files consulted
1378 // the last time the test was run with those arguments.
1379 // (To avoid unnecessary links, we store this entry
1380 // under two hashes: id1 uses the linker inputs as a
1381 // proxy for the test binary, and id2 uses the actual
1382 // test binary. If the linker inputs are unchanged,
1383 // this way we avoid the link step, even though we
1384 // do not cache link outputs.)
1386 // Second, we compute a hash of the values of the
1387 // environment variables and the content of the files
1388 // listed in the log from the previous run.
1389 // Then we look up test output using a combination of
1390 // the hash from the first part (testID) and the hash of the
1391 // test inputs (testInputsID).
1393 // In order to store a new test result, we must redo the
1394 // testInputsID computation using the log from the run
1395 // we want to cache, and then we store that new log and
1398 h := cache.NewHash("testResult")
1399 fmt.Fprintf(h, "test binary %s args %q execcmd %q", id, cacheArgs, work.ExecCmd)
1401 if c.id1 == (cache.ActionID{}) {
1406 if cache.DebugTest {
1407 fmt.Fprintf(os.Stderr, "testcache: %s: test ID %x => %x\n", a.Package.ImportPath, id, testID)
1410 // Load list of referenced environment variables and files
1411 // from last run of testID, and compute hash of that content.
1412 data, entry, err := cache.Default().GetBytes(testID)
1413 if !bytes.HasPrefix(data, testlogMagic) || data[len(data)-1] != '\n' {
1414 if cache.DebugTest {
1416 fmt.Fprintf(os.Stderr, "testcache: %s: input list not found: %v\n", a.Package.ImportPath, err)
1418 fmt.Fprintf(os.Stderr, "testcache: %s: input list malformed\n", a.Package.ImportPath)
1423 testInputsID, err := computeTestInputsID(a, data)
1427 if cache.DebugTest {
1428 fmt.Fprintf(os.Stderr, "testcache: %s: test ID %x => input ID %x => %x\n", a.Package.ImportPath, testID, testInputsID, testAndInputKey(testID, testInputsID))
1431 // Parse cached result in preparation for changing run time to "(cached)".
1432 // If we can't parse the cached result, don't use it.
1433 data, entry, err = cache.Default().GetBytes(testAndInputKey(testID, testInputsID))
1434 if len(data) == 0 || data[len(data)-1] != '\n' {
1435 if cache.DebugTest {
1437 fmt.Fprintf(os.Stderr, "testcache: %s: test output not found: %v\n", a.Package.ImportPath, err)
1439 fmt.Fprintf(os.Stderr, "testcache: %s: test output malformed\n", a.Package.ImportPath)
1444 if entry.Time.Before(testCacheExpire) {
1445 if cache.DebugTest {
1446 fmt.Fprintf(os.Stderr, "testcache: %s: test output expired due to go clean -testcache\n", a.Package.ImportPath)
1450 i := bytes.LastIndexByte(data[:len(data)-1], '\n') + 1
1451 if !bytes.HasPrefix(data[i:], []byte("ok \t")) {
1452 if cache.DebugTest {
1453 fmt.Fprintf(os.Stderr, "testcache: %s: test output malformed\n", a.Package.ImportPath)
1457 j := bytes.IndexByte(data[i+len("ok \t"):], '\t')
1459 if cache.DebugTest {
1460 fmt.Fprintf(os.Stderr, "testcache: %s: test output malformed\n", a.Package.ImportPath)
1464 j += i + len("ok \t") + 1
1466 // Committed to printing.
1467 c.buf = new(bytes.Buffer)
1468 c.buf.Write(data[:j])
1469 c.buf.WriteString("(cached)")
1470 for j < len(data) && ('0' <= data[j] && data[j] <= '9' || data[j] == '.' || data[j] == 's') {
1473 c.buf.Write(data[j:])
1477 var errBadTestInputs = errors.New("error parsing test inputs")
1478 var testlogMagic = []byte("# test log\n") // known to testing/internal/testdeps/deps.go
1480 // computeTestInputsID computes the "test inputs ID"
1481 // (see comment in tryCacheWithID above) for the
1483 func computeTestInputsID(a *work.Action, testlog []byte) (cache.ActionID, error) {
1484 testlog = bytes.TrimPrefix(testlog, testlogMagic)
1485 h := cache.NewHash("testInputs")
1486 pwd := a.Package.Dir
1487 for _, line := range bytes.Split(testlog, []byte("\n")) {
1492 i := strings.Index(s, " ")
1494 if cache.DebugTest {
1495 fmt.Fprintf(os.Stderr, "testcache: %s: input list malformed (%q)\n", a.Package.ImportPath, line)
1497 return cache.ActionID{}, errBadTestInputs
1503 if cache.DebugTest {
1504 fmt.Fprintf(os.Stderr, "testcache: %s: input list malformed (%q)\n", a.Package.ImportPath, line)
1506 return cache.ActionID{}, errBadTestInputs
1508 fmt.Fprintf(h, "env %s %x\n", name, hashGetenv(name))
1510 pwd = name // always absolute
1511 fmt.Fprintf(h, "chdir %s %x\n", name, hashStat(name))
1513 if !filepath.IsAbs(name) {
1514 name = filepath.Join(pwd, name)
1516 if a.Package.Root == "" || !inDir(name, a.Package.Root) {
1517 // Do not recheck files outside the module, GOPATH, or GOROOT root.
1520 fmt.Fprintf(h, "stat %s %x\n", name, hashStat(name))
1522 if !filepath.IsAbs(name) {
1523 name = filepath.Join(pwd, name)
1525 if a.Package.Root == "" || !inDir(name, a.Package.Root) {
1526 // Do not recheck files outside the module, GOPATH, or GOROOT root.
1529 fh, err := hashOpen(name)
1531 if cache.DebugTest {
1532 fmt.Fprintf(os.Stderr, "testcache: %s: input file %s: %s\n", a.Package.ImportPath, name, err)
1534 return cache.ActionID{}, err
1536 fmt.Fprintf(h, "open %s %x\n", name, fh)
1543 func inDir(path, dir string) bool {
1544 if str.HasFilePathPrefix(path, dir) {
1547 xpath, err1 := filepath.EvalSymlinks(path)
1548 xdir, err2 := filepath.EvalSymlinks(dir)
1549 if err1 == nil && err2 == nil && str.HasFilePathPrefix(xpath, xdir) {
1555 func hashGetenv(name string) cache.ActionID {
1556 h := cache.NewHash("getenv")
1557 v, ok := os.LookupEnv(name)
1567 const modTimeCutoff = 2 * time.Second
1569 var errFileTooNew = errors.New("file used as input is too new")
1571 func hashOpen(name string) (cache.ActionID, error) {
1572 h := cache.NewHash("open")
1573 info, err := os.Stat(name)
1575 fmt.Fprintf(h, "err %v\n", err)
1578 hashWriteStat(h, info)
1580 files, err := os.ReadDir(name)
1582 fmt.Fprintf(h, "err %v\n", err)
1584 for _, f := range files {
1585 fmt.Fprintf(h, "file %s ", f.Name())
1586 finfo, err := f.Info()
1588 fmt.Fprintf(h, "err %v\n", err)
1590 hashWriteStat(h, finfo)
1593 } else if info.Mode().IsRegular() {
1594 // Because files might be very large, do not attempt
1595 // to hash the entirety of their content. Instead assume
1596 // the mtime and size recorded in hashWriteStat above
1599 // To avoid problems for very recent files where a new
1600 // write might not change the mtime due to file system
1601 // mtime precision, reject caching if a file was read that
1602 // is less than modTimeCutoff old.
1603 if time.Since(info.ModTime()) < modTimeCutoff {
1604 return cache.ActionID{}, errFileTooNew
1610 func hashStat(name string) cache.ActionID {
1611 h := cache.NewHash("stat")
1612 if info, err := os.Stat(name); err != nil {
1613 fmt.Fprintf(h, "err %v\n", err)
1615 hashWriteStat(h, info)
1617 if info, err := os.Lstat(name); err != nil {
1618 fmt.Fprintf(h, "err %v\n", err)
1620 hashWriteStat(h, info)
1625 func hashWriteStat(h io.Writer, info fs.FileInfo) {
1626 fmt.Fprintf(h, "stat %d %x %v %v\n", info.Size(), uint64(info.Mode()), info.ModTime(), info.IsDir())
1629 // testAndInputKey returns the actual cache key for the pair (testID, testInputsID).
1630 func testAndInputKey(testID, testInputsID cache.ActionID) cache.ActionID {
1631 return cache.Subkey(testID, fmt.Sprintf("inputs:%x", testInputsID))
1634 func (c *runCache) saveOutput(a *work.Action) {
1635 if c.id1 == (cache.ActionID{}) && c.id2 == (cache.ActionID{}) {
1639 // See comment about two-level lookup in tryCacheWithID above.
1640 testlog, err := os.ReadFile(a.Objdir + "testlog.txt")
1641 if err != nil || !bytes.HasPrefix(testlog, testlogMagic) || testlog[len(testlog)-1] != '\n' {
1642 if cache.DebugTest {
1644 fmt.Fprintf(os.Stderr, "testcache: %s: reading testlog: %v\n", a.Package.ImportPath, err)
1646 fmt.Fprintf(os.Stderr, "testcache: %s: reading testlog: malformed\n", a.Package.ImportPath)
1651 testInputsID, err := computeTestInputsID(a, testlog)
1655 if c.id1 != (cache.ActionID{}) {
1656 if cache.DebugTest {
1657 fmt.Fprintf(os.Stderr, "testcache: %s: save test ID %x => input ID %x => %x\n", a.Package.ImportPath, c.id1, testInputsID, testAndInputKey(c.id1, testInputsID))
1659 cache.Default().PutNoVerify(c.id1, bytes.NewReader(testlog))
1660 cache.Default().PutNoVerify(testAndInputKey(c.id1, testInputsID), bytes.NewReader(a.TestOutput.Bytes()))
1662 if c.id2 != (cache.ActionID{}) {
1663 if cache.DebugTest {
1664 fmt.Fprintf(os.Stderr, "testcache: %s: save test ID %x => input ID %x => %x\n", a.Package.ImportPath, c.id2, testInputsID, testAndInputKey(c.id2, testInputsID))
1666 cache.Default().PutNoVerify(c.id2, bytes.NewReader(testlog))
1667 cache.Default().PutNoVerify(testAndInputKey(c.id2, testInputsID), bytes.NewReader(a.TestOutput.Bytes()))
1671 // coveragePercentage returns the coverage results (if enabled) for the
1672 // test. It uncovers the data by scanning the output from the test run.
1673 func coveragePercentage(out []byte) string {
1677 // The string looks like
1678 // test coverage for encoding/binary: 79.9% of statements
1679 // Extract the piece from the percentage to the end of the line.
1680 re := regexp.MustCompile(`coverage: (.*)\n`)
1681 matches := re.FindSubmatch(out)
1683 // Probably running "go test -cover" not "go test -cover fmt".
1684 // The coverage output will appear in the output directly.
1687 return fmt.Sprintf("\tcoverage: %s", matches[1])
1690 // builderCleanTest is the action for cleaning up after a test.
1691 func builderCleanTest(b *work.Builder, ctx context.Context, a *work.Action) error {
1696 b.Showcmd("", "rm -r %s", a.Objdir)
1698 os.RemoveAll(a.Objdir)
1702 // builderPrintTest is the action for printing a test result.
1703 func builderPrintTest(b *work.Builder, ctx context.Context, a *work.Action) error {
1705 run := clean.Deps[0]
1706 if run.TestOutput != nil {
1707 os.Stdout.Write(run.TestOutput.Bytes())
1708 run.TestOutput = nil
1713 // builderNoTest is the action for testing a package with no test files.
1714 func builderNoTest(b *work.Builder, ctx context.Context, a *work.Action) error {
1715 var stdout io.Writer = os.Stdout
1717 json := test2json.NewConverter(lockedStdout{}, a.Package.ImportPath, test2json.Timestamp)
1721 fmt.Fprintf(stdout, "? \t%s\t[no test files]\n", a.Package.ImportPath)
1725 // printExitStatus is the action for printing the exit status
1726 func printExitStatus(b *work.Builder, ctx context.Context, a *work.Action) error {
1727 if !testJSON && len(pkgArgs) != 0 {
1728 if base.GetExitStatus() != 0 {