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.
4
5package test
6
7import (
8	"bytes"
9	"context"
10	"crypto/sha256"
11	"errors"
12	"fmt"
13	"go/build"
14	exec "internal/execabs"
15	"io"
16	"io/fs"
17	"os"
18	"path"
19	"path/filepath"
20	"regexp"
21	"sort"
22	"strconv"
23	"strings"
24	"sync"
25	"time"
26
27	"cmd/go/internal/base"
28	"cmd/go/internal/cache"
29	"cmd/go/internal/cfg"
30	"cmd/go/internal/load"
31	"cmd/go/internal/lockedfile"
32	"cmd/go/internal/search"
33	"cmd/go/internal/str"
34	"cmd/go/internal/trace"
35	"cmd/go/internal/work"
36	"cmd/internal/test2json"
37)
38
39// Break init loop.
40func init() {
41	CmdTest.Run = runTest
42}
43
44const testUsage = "go test [build/test flags] [packages] [build/test flags & test binary flags]"
45
46var CmdTest = &base.Command{
47	CustomFlags: true,
48	UsageLine:   testUsage,
49	Short:       "test packages",
50	Long: `
51'Go test' automates testing the packages named by the import paths.
52It prints a summary of the test results in the format:
53
54	ok   archive/tar   0.011s
55	FAIL archive/zip   0.022s
56	ok   compress/gzip 0.033s
57	...
58
59followed by detailed output for each failed package.
60
61'Go test' recompiles each package along with any files with names matching
62the file pattern "*_test.go".
63These additional files can contain test functions, benchmark functions, and
64example functions. See 'go help testfunc' for more.
65Each listed package causes the execution of a separate test binary.
66Files whose names begin with "_" (including "_test.go") or "." are ignored.
67
68Test files that declare a package with the suffix "_test" will be compiled as a
69separate package, and then linked and run with the main test binary.
70
71The go tool will ignore a directory named "testdata", making it available
72to hold ancillary data needed by the tests.
73
74As part of building a test binary, go test runs go vet on the package
75and its test source files to identify significant problems. If go vet
76finds any problems, go test reports those and does not run the test
77binary. Only a high-confidence subset of the default go vet checks are
78used. That subset is: 'atomic', 'bool', 'buildtags', 'errorsas',
79'ifaceassert', 'nilfunc', 'printf', and 'stringintconv'. You can see
80the documentation for these and other vet tests via "go doc cmd/vet".
81To disable the running of go vet, use the -vet=off flag.
82
83All test output and summary lines are printed to the go command's
84standard output, even if the test printed them to its own standard
85error. (The go command's standard error is reserved for printing
86errors building the tests.)
87
88Go test runs in two different modes:
89
90The first, called local directory mode, occurs when go test is
91invoked with no package arguments (for example, 'go test' or 'go
92test -v'). In this mode, go test compiles the package sources and
93tests found in the current directory and then runs the resulting
94test binary. In this mode, caching (discussed below) is disabled.
95After the package test finishes, go test prints a summary line
96showing the test status ('ok' or 'FAIL'), package name, and elapsed
97time.
98
99The second, called package list mode, occurs when go test is invoked
100with explicit package arguments (for example 'go test math', 'go
101test ./...', and even 'go test .'). In this mode, go test compiles
102and tests each of the packages listed on the command line. If a
103package test passes, go test prints only the final 'ok' summary
104line. If a package test fails, go test prints the full test output.
105If invoked with the -bench or -v flag, go test prints the full
106output even for passing package tests, in order to display the
107requested benchmark results or verbose logging. After the package
108tests for all of the listed packages finish, and their output is
109printed, go test prints a final 'FAIL' status if any package test
110has failed.
111
112In package list mode only, go test caches successful package test
113results to avoid unnecessary repeated running of tests. When the
114result of a test can be recovered from the cache, go test will
115redisplay the previous output instead of running the test binary
116again. When this happens, go test prints '(cached)' in place of the
117elapsed time in the summary line.
118
119The rule for a match in the cache is that the run involves the same
120test binary and the flags on the command line come entirely from a
121restricted set of 'cacheable' test flags, defined as -benchtime, -cpu,
122-list, -parallel, -run, -short, and -v. If a run of go test has any test
123or non-test flags outside this set, the result is not cached. To
124disable test caching, use any test flag or argument other than the
125cacheable flags. The idiomatic way to disable test caching explicitly
126is to use -count=1. Tests that open files within the package's source
127root (usually $GOPATH) or that consult environment variables only
128match future runs in which the files and environment variables are unchanged.
129A cached test result is treated as executing in no time at all,
130so a successful package test result will be cached and reused
131regardless of -timeout setting.
132
133In addition to the build flags, the flags handled by 'go test' itself are:
134
135	-args
136	    Pass the remainder of the command line (everything after -args)
137	    to the test binary, uninterpreted and unchanged.
138	    Because this flag consumes the remainder of the command line,
139	    the package list (if present) must appear before this flag.
140
141	-c
142	    Compile the test binary to pkg.test but do not run it
143	    (where pkg is the last element of the package's import path).
144	    The file name can be changed with the -o flag.
145
146	-exec xprog
147	    Run the test binary using xprog. The behavior is the same as
148	    in 'go run'. See 'go help run' for details.
149
150	-i
151	    Install packages that are dependencies of the test.
152	    Do not run the test.
153	    The -i flag is deprecated. Compiled packages are cached automatically.
154
155	-json
156	    Convert test output to JSON suitable for automated processing.
157	    See 'go doc test2json' for the encoding details.
158
159	-o file
160	    Compile the test binary to the named file.
161	    The test still runs (unless -c or -i is specified).
162
163The test binary also accepts flags that control execution of the test; these
164flags are also accessible by 'go test'. See 'go help testflag' for details.
165
166For more about build flags, see 'go help build'.
167For more about specifying packages, see 'go help packages'.
168
169See also: go build, go vet.
170`,
171}
172
173var HelpTestflag = &base.Command{
174	UsageLine: "testflag",
175	Short:     "testing flags",
176	Long: `
177The 'go test' command takes both flags that apply to 'go test' itself
178and flags that apply to the resulting test binary.
179
180Several of the flags control profiling and write an execution profile
181suitable for "go tool pprof"; run "go tool pprof -h" for more
182information. The --alloc_space, --alloc_objects, and --show_bytes
183options of pprof control how the information is presented.
184
185The following flags are recognized by the 'go test' command and
186control the execution of any test:
187
188	-bench regexp
189	    Run only those benchmarks matching a regular expression.
190	    By default, no benchmarks are run.
191	    To run all benchmarks, use '-bench .' or '-bench=.'.
192	    The regular expression is split by unbracketed slash (/)
193	    characters into a sequence of regular expressions, and each
194	    part of a benchmark's identifier must match the corresponding
195	    element in the sequence, if any. Possible parents of matches
196	    are run with b.N=1 to identify sub-benchmarks. For example,
197	    given -bench=X/Y, top-level benchmarks matching X are run
198	    with b.N=1 to find any sub-benchmarks matching Y, which are
199	    then run in full.
200
201	-benchtime t
202	    Run enough iterations of each benchmark to take t, specified
203	    as a time.Duration (for example, -benchtime 1h30s).
204	    The default is 1 second (1s).
205	    The special syntax Nx means to run the benchmark N times
206	    (for example, -benchtime 100x).
207
208	-count n
209	    Run each test and benchmark n times (default 1).
210	    If -cpu is set, run n times for each GOMAXPROCS value.
211	    Examples are always run once.
212
213	-cover
214	    Enable coverage analysis.
215	    Note that because coverage works by annotating the source
216	    code before compilation, compilation and test failures with
217	    coverage enabled may report line numbers that don't correspond
218	    to the original sources.
219
220	-covermode set,count,atomic
221	    Set the mode for coverage analysis for the package[s]
222	    being tested. The default is "set" unless -race is enabled,
223	    in which case it is "atomic".
224	    The values:
225		set: bool: does this statement run?
226		count: int: how many times does this statement run?
227		atomic: int: count, but correct in multithreaded tests;
228			significantly more expensive.
229	    Sets -cover.
230
231	-coverpkg pattern1,pattern2,pattern3
232	    Apply coverage analysis in each test to packages matching the patterns.
233	    The default is for each test to analyze only the package being tested.
234	    See 'go help packages' for a description of package patterns.
235	    Sets -cover.
236
237	-cpu 1,2,4
238	    Specify a list of GOMAXPROCS values for which the tests or
239	    benchmarks should be executed. The default is the current value
240	    of GOMAXPROCS.
241
242	-failfast
243	    Do not start new tests after the first test failure.
244
245	-list regexp
246	    List tests, benchmarks, or examples matching the regular expression.
247	    No tests, benchmarks or examples will be run. This will only
248	    list top-level tests. No subtest or subbenchmarks will be shown.
249
250	-parallel n
251	    Allow parallel execution of test functions that call t.Parallel.
252	    The value of this flag is the maximum number of tests to run
253	    simultaneously; by default, it is set to the value of GOMAXPROCS.
254	    Note that -parallel only applies within a single test binary.
255	    The 'go test' command may run tests for different packages
256	    in parallel as well, according to the setting of the -p flag
257	    (see 'go help build').
258
259	-run regexp
260	    Run only those tests and examples matching the regular expression.
261	    For tests, the regular expression is split by unbracketed slash (/)
262	    characters into a sequence of regular expressions, and each part
263	    of a test's identifier must match the corresponding element in
264	    the sequence, if any. Note that possible parents of matches are
265	    run too, so that -run=X/Y matches and runs and reports the result
266	    of all tests matching X, even those without sub-tests matching Y,
267	    because it must run them to look for those sub-tests.
268
269	-short
270	    Tell long-running tests to shorten their run time.
271	    It is off by default but set during all.bash so that installing
272	    the Go tree can run a sanity check but not spend time running
273	    exhaustive tests.
274
275	-shuffle off,on,N
276		Randomize the execution order of tests and benchmarks.
277		It is off by default. If -shuffle is set to on, then it will seed
278		the randomizer using the system clock. If -shuffle is set to an
279		integer N, then N will be used as the seed value. In both cases,
280		the seed will be reported for reproducibility.
281
282	-timeout d
283	    If a test binary runs longer than duration d, panic.
284	    If d is 0, the timeout is disabled.
285	    The default is 10 minutes (10m).
286
287	-v
288	    Verbose output: log all tests as they are run. Also print all
289	    text from Log and Logf calls even if the test succeeds.
290
291	-vet list
292	    Configure the invocation of "go vet" during "go test"
293	    to use the comma-separated list of vet checks.
294	    If list is empty, "go test" runs "go vet" with a curated list of
295	    checks believed to be always worth addressing.
296	    If list is "off", "go test" does not run "go vet" at all.
297
298The following flags are also recognized by 'go test' and can be used to
299profile the tests during execution:
300
301	-benchmem
302	    Print memory allocation statistics for benchmarks.
303
304	-blockprofile block.out
305	    Write a goroutine blocking profile to the specified file
306	    when all tests are complete.
307	    Writes test binary as -c would.
308
309	-blockprofilerate n
310	    Control the detail provided in goroutine blocking profiles by
311	    calling runtime.SetBlockProfileRate with n.
312	    See 'go doc runtime.SetBlockProfileRate'.
313	    The profiler aims to sample, on average, one blocking event every
314	    n nanoseconds the program spends blocked. By default,
315	    if -test.blockprofile is set without this flag, all blocking events
316	    are recorded, equivalent to -test.blockprofilerate=1.
317
318	-coverprofile cover.out
319	    Write a coverage profile to the file after all tests have passed.
320	    Sets -cover.
321
322	-cpuprofile cpu.out
323	    Write a CPU profile to the specified file before exiting.
324	    Writes test binary as -c would.
325
326	-memprofile mem.out
327	    Write an allocation profile to the file after all tests have passed.
328	    Writes test binary as -c would.
329
330	-memprofilerate n
331	    Enable more precise (and expensive) memory allocation profiles by
332	    setting runtime.MemProfileRate. See 'go doc runtime.MemProfileRate'.
333	    To profile all memory allocations, use -test.memprofilerate=1.
334
335	-mutexprofile mutex.out
336	    Write a mutex contention profile to the specified file
337	    when all tests are complete.
338	    Writes test binary as -c would.
339
340	-mutexprofilefraction n
341	    Sample 1 in n stack traces of goroutines holding a
342	    contended mutex.
343
344	-outputdir directory
345	    Place output files from profiling in the specified directory,
346	    by default the directory in which "go test" is running.
347
348	-trace trace.out
349	    Write an execution trace to the specified file before exiting.
350
351Each of these flags is also recognized with an optional 'test.' prefix,
352as in -test.v. When invoking the generated test binary (the result of
353'go test -c') directly, however, the prefix is mandatory.
354
355The 'go test' command rewrites or removes recognized flags,
356as appropriate, both before and after the optional package list,
357before invoking the test binary.
358
359For instance, the command
360
361	go test -v -myflag testdata -cpuprofile=prof.out -x
362
363will compile the test binary and then run it as
364
365	pkg.test -test.v -myflag testdata -test.cpuprofile=prof.out
366
367(The -x flag is removed because it applies only to the go command's
368execution, not to the test itself.)
369
370The test flags that generate profiles (other than for coverage) also
371leave the test binary in pkg.test for use when analyzing the profiles.
372
373When 'go test' runs a test binary, it does so from within the
374corresponding package's source code directory. Depending on the test,
375it may be necessary to do the same when invoking a generated test
376binary directly.
377
378The command-line package list, if present, must appear before any
379flag not known to the go test command. Continuing the example above,
380the package list would have to appear before -myflag, but could appear
381on either side of -v.
382
383When 'go test' runs in package list mode, 'go test' caches successful
384package test results to avoid unnecessary repeated running of tests. To
385disable test caching, use any test flag or argument other than the
386cacheable flags. The idiomatic way to disable test caching explicitly
387is to use -count=1.
388
389To keep an argument for a test binary from being interpreted as a
390known flag or a package name, use -args (see 'go help test') which
391passes the remainder of the command line through to the test binary
392uninterpreted and unaltered.
393
394For instance, the command
395
396	go test -v -args -x -v
397
398will compile the test binary and then run it as
399
400	pkg.test -test.v -x -v
401
402Similarly,
403
404	go test -args math
405
406will compile the test binary and then run it as
407
408	pkg.test math
409
410In the first example, the -x and the second -v are passed through to the
411test binary unchanged and with no effect on the go command itself.
412In the second example, the argument math is passed through to the test
413binary, instead of being interpreted as the package list.
414`,
415}
416
417var HelpTestfunc = &base.Command{
418	UsageLine: "testfunc",
419	Short:     "testing functions",
420	Long: `
421The 'go test' command expects to find test, benchmark, and example functions
422in the "*_test.go" files corresponding to the package under test.
423
424A test function is one named TestXxx (where Xxx does not start with a
425lower case letter) and should have the signature,
426
427	func TestXxx(t *testing.T) { ... }
428
429A benchmark function is one named BenchmarkXxx and should have the signature,
430
431	func BenchmarkXxx(b *testing.B) { ... }
432
433An example function is similar to a test function but, instead of using
434*testing.T to report success or failure, prints output to os.Stdout.
435If the last comment in the function starts with "Output:" then the output
436is compared exactly against the comment (see examples below). If the last
437comment begins with "Unordered output:" then the output is compared to the
438comment, however the order of the lines is ignored. An example with no such
439comment is compiled but not executed. An example with no text after
440"Output:" is compiled, executed, and expected to produce no output.
441
442Godoc displays the body of ExampleXxx to demonstrate the use
443of the function, constant, or variable Xxx. An example of a method M with
444receiver type T or *T is named ExampleT_M. There may be multiple examples
445for a given function, constant, or variable, distinguished by a trailing _xxx,
446where xxx is a suffix not beginning with an upper case letter.
447
448Here is an example of an example:
449
450	func ExamplePrintln() {
451		Println("The output of\nthis example.")
452		// Output: The output of
453		// this example.
454	}
455
456Here is another example where the ordering of the output is ignored:
457
458	func ExamplePerm() {
459		for _, value := range Perm(4) {
460			fmt.Println(value)
461		}
462
463		// Unordered output: 4
464		// 2
465		// 1
466		// 3
467		// 0
468	}
469
470The entire test file is presented as the example when it contains a single
471example function, at least one other function, type, variable, or constant
472declaration, and no test or benchmark functions.
473
474See the documentation of the testing package for more information.
475`,
476}
477
478var (
479	testBench        string                            // -bench flag
480	testC            bool                              // -c flag
481	testCover        bool                              // -cover flag
482	testCoverMode    string                            // -covermode flag
483	testCoverPaths   []string                          // -coverpkg flag
484	testCoverPkgs    []*load.Package                   // -coverpkg flag
485	testCoverProfile string                            // -coverprofile flag
486	testJSON         bool                              // -json flag
487	testList         string                            // -list flag
488	testO            string                            // -o flag
489	testOutputDir    outputdirFlag                     // -outputdir flag
490	testShuffle      shuffleFlag                       // -shuffle flag
491	testTimeout      time.Duration                     // -timeout flag
492	testV            bool                              // -v flag
493	testVet          = vetFlag{flags: defaultVetFlags} // -vet flag
494)
495
496var (
497	testArgs []string
498	pkgArgs  []string
499	pkgs     []*load.Package
500
501	testHelp bool // -help option passed to test via -args
502
503	testKillTimeout = 100 * 365 * 24 * time.Hour // backup alarm; defaults to about a century if no timeout is set
504	testCacheExpire time.Time                    // ignore cached test results before this time
505
506	testBlockProfile, testCPUProfile, testMemProfile, testMutexProfile, testTrace string // profiling flag that limits test to one package
507)
508
509// testProfile returns the name of an arbitrary single-package profiling flag
510// that is set, if any.
511func testProfile() string {
512	switch {
513	case testBlockProfile != "":
514		return "-blockprofile"
515	case testCPUProfile != "":
516		return "-cpuprofile"
517	case testMemProfile != "":
518		return "-memprofile"
519	case testMutexProfile != "":
520		return "-mutexprofile"
521	case testTrace != "":
522		return "-trace"
523	default:
524		return ""
525	}
526}
527
528// testNeedBinary reports whether the test needs to keep the binary around.
529func testNeedBinary() bool {
530	switch {
531	case testBlockProfile != "":
532		return true
533	case testCPUProfile != "":
534		return true
535	case testMemProfile != "":
536		return true
537	case testMutexProfile != "":
538		return true
539	case testO != "":
540		return true
541	default:
542		return false
543	}
544}
545
546// testShowPass reports whether the output for a passing test should be shown.
547func testShowPass() bool {
548	return testV || (testList != "") || testHelp
549}
550
551var defaultVetFlags = []string{
552	// TODO(rsc): Decide which tests are enabled by default.
553	// See golang.org/issue/18085.
554	// "-asmdecl",
555	// "-assign",
556	"-atomic",
557	"-bool",
558	"-buildtags",
559	// "-cgocall",
560	// "-composites",
561	// "-copylocks",
562	"-errorsas",
563	// "-httpresponse",
564	"-ifaceassert",
565	// "-lostcancel",
566	// "-methods",
567	"-nilfunc",
568	"-printf",
569	// "-rangeloops",
570	// "-shift",
571	"-stringintconv",
572	// "-structtags",
573	// "-tests",
574	// "-unreachable",
575	// "-unsafeptr",
576	// "-unusedresult",
577}
578
579func runTest(ctx context.Context, cmd *base.Command, args []string) {
580	pkgArgs, testArgs = testFlags(args)
581
582	if cfg.DebugTrace != "" {
583		var close func() error
584		var err error
585		ctx, close, err = trace.Start(ctx, cfg.DebugTrace)
586		if err != nil {
587			base.Fatalf("failed to start trace: %v", err)
588		}
589		defer func() {
590			if err := close(); err != nil {
591				base.Fatalf("failed to stop trace: %v", err)
592			}
593		}()
594	}
595
596	ctx, span := trace.StartSpan(ctx, fmt.Sprint("Running ", cmd.Name(), " command"))
597	defer span.Done()
598
599	work.FindExecCmd() // initialize cached result
600
601	work.BuildInit()
602	work.VetFlags = testVet.flags
603	work.VetExplicit = testVet.explicit
604
605	pkgOpts := load.PackageOpts{ModResolveTests: true}
606	pkgs = load.PackagesAndErrors(ctx, pkgOpts, pkgArgs)
607	load.CheckPackageErrors(pkgs)
608	if len(pkgs) == 0 {
609		base.Fatalf("no packages to test")
610	}
611
612	if testC && len(pkgs) != 1 {
613		base.Fatalf("cannot use -c flag with multiple packages")
614	}
615	if testO != "" && len(pkgs) != 1 {
616		base.Fatalf("cannot use -o flag with multiple packages")
617	}
618	if testProfile() != "" && len(pkgs) != 1 {
619		base.Fatalf("cannot use %s flag with multiple packages", testProfile())
620	}
621	initCoverProfile()
622	defer closeCoverProfile()
623
624	// If a test timeout is finite, set our kill timeout
625	// to that timeout plus one minute. This is a backup alarm in case
626	// the test wedges with a goroutine spinning and its background
627	// timer does not get a chance to fire.
628	if testTimeout > 0 {
629		testKillTimeout = testTimeout + 1*time.Minute
630	}
631
632	// For 'go test -i -o x.test', we want to build x.test. Imply -c to make the logic easier.
633	if cfg.BuildI && testO != "" {
634		testC = true
635	}
636
637	// Read testcache expiration time, if present.
638	// (We implement go clean -testcache by writing an expiration date
639	// instead of searching out and deleting test result cache entries.)
640	if dir := cache.DefaultDir(); dir != "off" {
641		if data, _ := lockedfile.Read(filepath.Join(dir, "testexpire.txt")); len(data) > 0 && data[len(data)-1] == '\n' {
642			if t, err := strconv.ParseInt(string(data[:len(data)-1]), 10, 64); err == nil {
643				testCacheExpire = time.Unix(0, t)
644			}
645		}
646	}
647
648	var b work.Builder
649	b.Init()
650
651	if cfg.BuildI {
652		fmt.Fprint(os.Stderr, "go test: -i flag is deprecated\n")
653		cfg.BuildV = testV
654
655		deps := make(map[string]bool)
656		for _, dep := range load.TestMainDeps {
657			deps[dep] = true
658		}
659
660		for _, p := range pkgs {
661			// Dependencies for each test.
662			for _, path := range p.Imports {
663				deps[path] = true
664			}
665			for _, path := range p.Resolve(p.TestImports) {
666				deps[path] = true
667			}
668			for _, path := range p.Resolve(p.XTestImports) {
669				deps[path] = true
670			}
671		}
672
673		// translate C to runtime/cgo
674		if deps["C"] {
675			delete(deps, "C")
676			deps["runtime/cgo"] = true
677		}
678		// Ignore pseudo-packages.
679		delete(deps, "unsafe")
680
681		all := []string{}
682		for path := range deps {
683			if !build.IsLocalImport(path) {
684				all = append(all, path)
685			}
686		}
687		sort.Strings(all)
688
689		a := &work.Action{Mode: "go test -i"}
690		pkgs := load.PackagesAndErrors(ctx, pkgOpts, all)
691		load.CheckPackageErrors(pkgs)
692		for _, p := range pkgs {
693			if cfg.BuildToolchainName == "gccgo" && p.Standard {
694				// gccgo's standard library packages
695				// can not be reinstalled.
696				continue
697			}
698			a.Deps = append(a.Deps, b.CompileAction(work.ModeInstall, work.ModeInstall, p))
699		}
700		b.Do(ctx, a)
701		if !testC || a.Failed {
702			return
703		}
704		b.Init()
705	}
706
707	var builds, runs, prints []*work.Action
708
709	if testCoverPaths != nil {
710		match := make([]func(*load.Package) bool, len(testCoverPaths))
711		matched := make([]bool, len(testCoverPaths))
712		for i := range testCoverPaths {
713			match[i] = load.MatchPackage(testCoverPaths[i], base.Cwd())
714		}
715
716		// Select for coverage all dependencies matching the testCoverPaths patterns.
717		for _, p := range load.TestPackageList(ctx, pkgOpts, pkgs) {
718			haveMatch := false
719			for i := range testCoverPaths {
720				if match[i](p) {
721					matched[i] = true
722					haveMatch = true
723				}
724			}
725
726			// A package which only has test files can't be imported
727			// as a dependency, nor can it be instrumented for coverage.
728			if len(p.GoFiles)+len(p.CgoFiles) == 0 {
729				continue
730			}
731
732			// Silently ignore attempts to run coverage on
733			// sync/atomic when using atomic coverage mode.
734			// Atomic coverage mode uses sync/atomic, so
735			// we can't also do coverage on it.
736			if testCoverMode == "atomic" && p.Standard && p.ImportPath == "sync/atomic" {
737				continue
738			}
739
740			// If using the race detector, silently ignore
741			// attempts to run coverage on the runtime
742			// packages. It will cause the race detector
743			// to be invoked before it has been initialized.
744			if cfg.BuildRace && p.Standard && (p.ImportPath == "runtime" || strings.HasPrefix(p.ImportPath, "runtime/internal")) {
745				continue
746			}
747
748			if haveMatch {
749				testCoverPkgs = append(testCoverPkgs, p)
750			}
751		}
752
753		// Warn about -coverpkg arguments that are not actually used.
754		for i := range testCoverPaths {
755			if !matched[i] {
756				fmt.Fprintf(os.Stderr, "warning: no packages being tested depend on matches for pattern %s\n", testCoverPaths[i])
757			}
758		}
759
760		// Mark all the coverage packages for rebuilding with coverage.
761		for _, p := range testCoverPkgs {
762			// There is nothing to cover in package unsafe; it comes from the compiler.
763			if p.ImportPath == "unsafe" {
764				continue
765			}
766			p.Internal.CoverMode = testCoverMode
767			var coverFiles []string
768			coverFiles = append(coverFiles, p.GoFiles...)
769			coverFiles = append(coverFiles, p.CgoFiles...)
770			coverFiles = append(coverFiles, p.TestGoFiles...)
771			p.Internal.CoverVars = declareCoverVars(p, coverFiles...)
772			if testCover && testCoverMode == "atomic" {
773				ensureImport(p, "sync/atomic")
774			}
775		}
776	}
777
778	// Prepare build + run + print actions for all packages being tested.
779	for _, p := range pkgs {
780		// sync/atomic import is inserted by the cover tool. See #18486
781		if testCover && testCoverMode == "atomic" {
782			ensureImport(p, "sync/atomic")
783		}
784
785		buildTest, runTest, printTest, err := builderTest(&b, ctx, pkgOpts, p)
786		if err != nil {
787			str := err.Error()
788			str = strings.TrimPrefix(str, "\n")
789			if p.ImportPath != "" {
790				base.Errorf("# %s\n%s", p.ImportPath, str)
791			} else {
792				base.Errorf("%s", str)
793			}
794			fmt.Printf("FAIL\t%s [setup failed]\n", p.ImportPath)
795			continue
796		}
797		builds = append(builds, buildTest)
798		runs = append(runs, runTest)
799		prints = append(prints, printTest)
800	}
801
802	// Ultimately the goal is to print the output.
803	root := &work.Action{Mode: "go test", Func: printExitStatus, Deps: prints}
804
805	// Force the printing of results to happen in order,
806	// one at a time.
807	for i, a := range prints {
808		if i > 0 {
809			a.Deps = append(a.Deps, prints[i-1])
810		}
811	}
812
813	// Force benchmarks to run in serial.
814	if !testC && (testBench != "") {
815		// The first run must wait for all builds.
816		// Later runs must wait for the previous run's print.
817		for i, run := range runs {
818			if i == 0 {
819				run.Deps = append(run.Deps, builds...)
820			} else {
821				run.Deps = append(run.Deps, prints[i-1])
822			}
823		}
824	}
825
826	b.Do(ctx, root)
827}
828
829// ensures that package p imports the named package
830func ensureImport(p *load.Package, pkg string) {
831	for _, d := range p.Internal.Imports {
832		if d.Name == pkg {
833			return
834		}
835	}
836
837	p1 := load.LoadImportWithFlags(pkg, p.Dir, p, &load.ImportStack{}, nil, 0)
838	if p1.Error != nil {
839		base.Fatalf("load %s: %v", pkg, p1.Error)
840	}
841
842	p.Internal.Imports = append(p.Internal.Imports, p1)
843}
844
845var windowsBadWords = []string{
846	"install",
847	"patch",
848	"setup",
849	"update",
850}
851
852func builderTest(b *work.Builder, ctx context.Context, pkgOpts load.PackageOpts, p *load.Package) (buildAction, runAction, printAction *work.Action, err error) {
853	if len(p.TestGoFiles)+len(p.XTestGoFiles) == 0 {
854		build := b.CompileAction(work.ModeBuild, work.ModeBuild, p)
855		run := &work.Action{Mode: "test run", Package: p, Deps: []*work.Action{build}}
856		addTestVet(b, p, run, nil)
857		print := &work.Action{Mode: "test print", Func: builderNoTest, Package: p, Deps: []*work.Action{run}}
858		return build, run, print, nil
859	}
860
861	// Build Package structs describing:
862	//	pmain - pkg.test binary
863	//	ptest - package + test files
864	//	pxtest - package of external test files
865	var cover *load.TestCover
866	if testCover {
867		cover = &load.TestCover{
868			Mode:     testCoverMode,
869			Local:    testCover && testCoverPaths == nil,
870			Pkgs:     testCoverPkgs,
871			Paths:    testCoverPaths,
872			DeclVars: declareCoverVars,
873		}
874	}
875	pmain, ptest, pxtest, err := load.TestPackagesFor(ctx, pkgOpts, p, cover)
876	if err != nil {
877		return nil, nil, nil, err
878	}
879
880	// Use last element of import path, not package name.
881	// They differ when package name is "main".
882	// But if the import path is "command-line-arguments",
883	// like it is during 'go run', use the package name.
884	var elem string
885	if p.ImportPath == "command-line-arguments" {
886		elem = p.Name
887	} else {
888		elem = p.DefaultExecName()
889	}
890	testBinary := elem + ".test"
891
892	testDir := b.NewObjdir()
893	if err := b.Mkdir(testDir); err != nil {
894		return nil, nil, nil, err
895	}
896
897	pmain.Dir = testDir
898	pmain.Internal.OmitDebug = !testC && !testNeedBinary()
899
900	if !cfg.BuildN {
901		// writeTestmain writes _testmain.go,
902		// using the test description gathered in t.
903		if err := os.WriteFile(testDir+"_testmain.go", *pmain.Internal.TestmainGo, 0666); err != nil {
904			return nil, nil, nil, err
905		}
906	}
907
908	// Set compile objdir to testDir we've already created,
909	// so that the default file path stripping applies to _testmain.go.
910	b.CompileAction(work.ModeBuild, work.ModeBuild, pmain).Objdir = testDir
911
912	a := b.LinkAction(work.ModeBuild, work.ModeBuild, pmain)
913	a.Target = testDir + testBinary + cfg.ExeSuffix
914	if cfg.Goos == "windows" {
915		// There are many reserved words on Windows that,
916		// if used in the name of an executable, cause Windows
917		// to try to ask for extra permissions.
918		// The word list includes setup, install, update, and patch,
919		// but it does not appear to be defined anywhere.
920		// We have run into this trying to run the
921		// go.codereview/patch tests.
922		// For package names containing those words, use test.test.exe
923		// instead of pkgname.test.exe.
924		// Note that this file name is only used in the Go command's
925		// temporary directory. If the -c or other flags are
926		// given, the code below will still use pkgname.test.exe.
927		// There are two user-visible effects of this change.
928		// First, you can actually run 'go test' in directories that
929		// have names that Windows thinks are installer-like,
930		// without getting a dialog box asking for more permissions.
931		// Second, in the Windows process listing during go test,
932		// the test shows up as test.test.exe, not pkgname.test.exe.
933		// That second one is a drawback, but it seems a small
934		// price to pay for the test running at all.
935		// If maintaining the list of bad words is too onerous,
936		// we could just do this always on Windows.
937		for _, bad := range windowsBadWords {
938			if strings.Contains(testBinary, bad) {
939				a.Target = testDir + "test.test" + cfg.ExeSuffix
940				break
941			}
942		}
943	}
944	buildAction = a
945	var installAction, cleanAction *work.Action
946	if testC || testNeedBinary() {
947		// -c or profiling flag: create action to copy binary to ./test.out.
948		target := filepath.Join(base.Cwd(), testBinary+cfg.ExeSuffix)
949		if testO != "" {
950			target = testO
951			if !filepath.IsAbs(target) {
952				target = filepath.Join(base.Cwd(), target)
953			}
954		}
955		if target == os.DevNull {
956			runAction = buildAction
957		} else {
958			pmain.Target = target
959			installAction = &work.Action{
960				Mode:    "test build",
961				Func:    work.BuildInstallFunc,
962				Deps:    []*work.Action{buildAction},
963				Package: pmain,
964				Target:  target,
965			}
966			runAction = installAction // make sure runAction != nil even if not running test
967		}
968	}
969	var vetRunAction *work.Action
970	if testC {
971		printAction = &work.Action{Mode: "test print (nop)", Package: p, Deps: []*work.Action{runAction}} // nop
972		vetRunAction = printAction
973	} else {
974		// run test
975		c := new(runCache)
976		runAction = &work.Action{
977			Mode:       "test run",
978			Func:       c.builderRunTest,
979			Deps:       []*work.Action{buildAction},
980			Package:    p,
981			IgnoreFail: true, // run (prepare output) even if build failed
982			TryCache:   c.tryCache,
983			Objdir:     testDir,
984		}
985		vetRunAction = runAction
986		cleanAction = &work.Action{
987			Mode:       "test clean",
988			Func:       builderCleanTest,
989			Deps:       []*work.Action{runAction},
990			Package:    p,
991			IgnoreFail: true, // clean even if test failed
992			Objdir:     testDir,
993		}
994		printAction = &work.Action{
995			Mode:       "test print",
996			Func:       builderPrintTest,
997			Deps:       []*work.Action{cleanAction},
998			Package:    p,
999			IgnoreFail: true, // print even if test failed
1000		}
1001	}
1002
1003	if len(ptest.GoFiles)+len(ptest.CgoFiles) > 0 {
1004		addTestVet(b, ptest, vetRunAction, installAction)
1005	}
1006	if pxtest != nil {
1007		addTestVet(b, pxtest, vetRunAction, installAction)
1008	}
1009
1010	if installAction != nil {
1011		if runAction != installAction {
1012			installAction.Deps = append(installAction.Deps, runAction)
1013		}
1014		if cleanAction != nil {
1015			cleanAction.Deps = append(cleanAction.Deps, installAction)
1016		}
1017	}
1018
1019	return buildAction, runAction, printAction, nil
1020}
1021
1022func addTestVet(b *work.Builder, p *load.Package, runAction, installAction *work.Action) {
1023	if testVet.off {
1024		return
1025	}
1026
1027	vet := b.VetAction(work.ModeBuild, work.ModeBuild, p)
1028	runAction.Deps = append(runAction.Deps, vet)
1029	// Install will clean the build directory.
1030	// Make sure vet runs first.
1031	// The install ordering in b.VetAction does not apply here
1032	// because we are using a custom installAction (created above).
1033	if installAction != nil {
1034		installAction.Deps = append(installAction.Deps, vet)
1035	}
1036}
1037
1038// isTestFile reports whether the source file is a set of tests and should therefore
1039// be excluded from coverage analysis.
1040func isTestFile(file string) bool {
1041	// We don't cover tests, only the code they test.
1042	return strings.HasSuffix(file, "_test.go")
1043}
1044
1045// declareCoverVars attaches the required cover variables names
1046// to the files, to be used when annotating the files.
1047func declareCoverVars(p *load.Package, files ...string) map[string]*load.CoverVar {
1048	coverVars := make(map[string]*load.CoverVar)
1049	coverIndex := 0
1050	// We create the cover counters as new top-level variables in the package.
1051	// We need to avoid collisions with user variables (GoCover_0 is unlikely but still)
1052	// and more importantly with dot imports of other covered packages,
1053	// so we append 12 hex digits from the SHA-256 of the import path.
1054	// The point is only to avoid accidents, not to defeat users determined to
1055	// break things.
1056	sum := sha256.Sum256([]byte(p.ImportPath))
1057	h := fmt.Sprintf("%x", sum[:6])
1058	for _, file := range files {
1059		if isTestFile(file) {
1060			continue
1061		}
1062		// For a package that is "local" (imported via ./ import or command line, outside GOPATH),
1063		// we record the full path to the file name.
1064		// Otherwise we record the import path, then a forward slash, then the file name.
1065		// This makes profiles within GOPATH file system-independent.
1066		// These names appear in the cmd/cover HTML interface.
1067		var longFile string
1068		if p.Internal.Local {
1069			longFile = filepath.Join(p.Dir, file)
1070		} else {
1071			longFile = path.Join(p.ImportPath, file)
1072		}
1073		coverVars[file] = &load.CoverVar{
1074			File: longFile,
1075			Var:  fmt.Sprintf("GoCover_%d_%x", coverIndex, h),
1076		}
1077		coverIndex++
1078	}
1079	return coverVars
1080}
1081
1082var noTestsToRun = []byte("\ntesting: warning: no tests to run\n")
1083
1084type runCache struct {
1085	disableCache bool // cache should be disabled for this run
1086
1087	buf *bytes.Buffer
1088	id1 cache.ActionID
1089	id2 cache.ActionID
1090}
1091
1092// stdoutMu and lockedStdout provide a locked standard output
1093// that guarantees never to interlace writes from multiple
1094// goroutines, so that we can have multiple JSON streams writing
1095// to a lockedStdout simultaneously and know that events will
1096// still be intelligible.
1097var stdoutMu sync.Mutex
1098
1099type lockedStdout struct{}
1100
1101func (lockedStdout) Write(b []byte) (int, error) {
1102	stdoutMu.Lock()
1103	defer stdoutMu.Unlock()
1104	return os.Stdout.Write(b)
1105}
1106
1107// builderRunTest is the action for running a test binary.
1108func (c *runCache) builderRunTest(b *work.Builder, ctx context.Context, a *work.Action) error {
1109	if a.Failed {
1110		// We were unable to build the binary.
1111		a.Failed = false
1112		a.TestOutput = new(bytes.Buffer)
1113		fmt.Fprintf(a.TestOutput, "FAIL\t%s [build failed]\n", a.Package.ImportPath)
1114		base.SetExitStatus(1)
1115		return nil
1116	}
1117
1118	var stdout io.Writer = os.Stdout
1119	var err error
1120	if testJSON {
1121		json := test2json.NewConverter(lockedStdout{}, a.Package.ImportPath, test2json.Timestamp)
1122		defer func() {
1123			json.Exited(err)
1124			json.Close()
1125		}()
1126		stdout = json
1127	}
1128
1129	var buf bytes.Buffer
1130	if len(pkgArgs) == 0 || (testBench != "") {
1131		// Stream test output (no buffering) when no package has
1132		// been given on the command line (implicit current directory)
1133		// or when benchmarking.
1134		// No change to stdout.
1135	} else {
1136		// If we're only running a single package under test or if parallelism is
1137		// set to 1, and if we're displaying all output (testShowPass), we can
1138		// hurry the output along, echoing it as soon as it comes in.
1139		// We still have to copy to &buf for caching the result. This special
1140		// case was introduced in Go 1.5 and is intentionally undocumented:
1141		// the exact details of output buffering are up to the go command and
1142		// subject to change. It would be nice to remove this special case
1143		// entirely, but it is surely very helpful to see progress being made
1144		// when tests are run on slow single-CPU ARM systems.
1145		//
1146		// If we're showing JSON output, then display output as soon as
1147		// possible even when multiple tests are being run: the JSON output
1148		// events are attributed to specific package tests, so interlacing them
1149		// is OK.
1150		if testShowPass() && (len(pkgs) == 1 || cfg.BuildP == 1) || testJSON {
1151			// Write both to stdout and buf, for possible saving
1152			// to cache, and for looking for the "no tests to run" message.
1153			stdout = io.MultiWriter(stdout, &buf)
1154		} else {
1155			stdout = &buf
1156		}
1157	}
1158
1159	if c.buf == nil {
1160		// We did not find a cached result using the link step action ID,
1161		// so we ran the link step. Try again now with the link output
1162		// content ID. The attempt using the action ID makes sure that
1163		// if the link inputs don't change, we reuse the cached test
1164		// result without even rerunning the linker. The attempt using
1165		// the link output (test binary) content ID makes sure that if
1166		// we have different link inputs but the same final binary,
1167		// we still reuse the cached test result.
1168		// c.saveOutput will store the result under both IDs.
1169		c.tryCacheWithID(b, a, a.Deps[0].BuildContentID())
1170	}
1171	if c.buf != nil {
1172		if stdout != &buf {
1173			stdout.Write(c.buf.Bytes())
1174			c.buf.Reset()
1175		}
1176		a.TestOutput = c.buf
1177		return nil
1178	}
1179
1180	execCmd := work.FindExecCmd()
1181	testlogArg := []string{}
1182	if !c.disableCache && len(execCmd) == 0 {
1183		testlogArg = []string{"-test.testlogfile=" + a.Objdir + "testlog.txt"}
1184	}
1185	panicArg := "-test.paniconexit0"
1186	args := str.StringList(execCmd, a.Deps[0].BuiltTarget(), testlogArg, panicArg, testArgs)
1187
1188	if testCoverProfile != "" {
1189		// Write coverage to temporary profile, for merging later.
1190		for i, arg := range args {
1191			if strings.HasPrefix(arg, "-test.coverprofile=") {
1192				args[i] = "-test.coverprofile=" + a.Objdir + "_cover_.out"
1193			}
1194		}
1195	}
1196
1197	if cfg.BuildN || cfg.BuildX {
1198		b.Showcmd("", "%s", strings.Join(args, " "))
1199		if cfg.BuildN {
1200			return nil
1201		}
1202	}
1203
1204	cmd := exec.Command(args[0], args[1:]...)
1205	cmd.Dir = a.Package.Dir
1206	cmd.Env = base.AppendPWD(cfg.OrigEnv[:len(cfg.OrigEnv):len(cfg.OrigEnv)], cmd.Dir)
1207	cmd.Stdout = stdout
1208	cmd.Stderr = stdout
1209
1210	// If there are any local SWIG dependencies, we want to load
1211	// the shared library from the build directory.
1212	if a.Package.UsesSwig() {
1213		env := cmd.Env
1214		found := false
1215		prefix := "LD_LIBRARY_PATH="
1216		for i, v := range env {
1217			if strings.HasPrefix(v, prefix) {
1218				env[i] = v + ":."
1219				found = true
1220				break
1221			}
1222		}
1223		if !found {
1224			env = append(env, "LD_LIBRARY_PATH=.")
1225		}
1226		cmd.Env = env
1227	}
1228
1229	t0 := time.Now()
1230	err = cmd.Start()
1231
1232	// This is a last-ditch deadline to detect and
1233	// stop wedged test binaries, to keep the builders
1234	// running.
1235	if err == nil {
1236		tick := time.NewTimer(testKillTimeout)
1237		base.StartSigHandlers()
1238		done := make(chan error)
1239		go func() {
1240			done <- cmd.Wait()
1241		}()
1242	Outer:
1243		select {
1244		case err = <-done:
1245			// ok
1246		case <-tick.C:
1247			if base.SignalTrace != nil {
1248				// Send a quit signal in the hope that the program will print
1249				// a stack trace and exit. Give it five seconds before resorting
1250				// to Kill.
1251				cmd.Process.Signal(base.SignalTrace)
1252				select {
1253				case err = <-done:
1254					fmt.Fprintf(cmd.Stdout, "*** Test killed with %v: ran too long (%v).\n", base.SignalTrace, testKillTimeout)
1255					break Outer
1256				case <-time.After(5 * time.Second):
1257				}
1258			}
1259			cmd.Process.Kill()
1260			err = <-done
1261			fmt.Fprintf(cmd.Stdout, "*** Test killed: ran too long (%v).\n", testKillTimeout)
1262		}
1263		tick.Stop()
1264	}
1265	out := buf.Bytes()
1266	a.TestOutput = &buf
1267	t := fmt.Sprintf("%.3fs", time.Since(t0).Seconds())
1268
1269	mergeCoverProfile(cmd.Stdout, a.Objdir+"_cover_.out")
1270
1271	if err == nil {
1272		norun := ""
1273		if !testShowPass() && !testJSON {
1274			buf.Reset()
1275		}
1276		if bytes.HasPrefix(out, noTestsToRun[1:]) || bytes.Contains(out, noTestsToRun) {
1277			norun = " [no tests to run]"
1278		}
1279		fmt.Fprintf(cmd.Stdout, "ok  \t%s\t%s%s%s\n", a.Package.ImportPath, t, coveragePercentage(out), norun)
1280		c.saveOutput(a)
1281	} else {
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.
1285		if len(out) == 0 {
1286			fmt.Fprintf(cmd.Stdout, "%s\n", err)
1287		}
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),
1293		// not a pipe.
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)
1297	}
1298
1299	if cmd.Stdout != &buf {
1300		buf.Reset() // cmd.Stdout was going to os.Stdout already
1301	}
1302	return nil
1303}
1304
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.
1308func (c *runCache) tryCache(b *work.Builder, a *work.Action) bool {
1309	return c.tryCacheWithID(b, a, a.Deps[0].BuildActionID())
1310}
1311
1312func (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")
1318		}
1319		c.disableCache = true
1320		return false
1321	}
1322
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)
1327		}
1328		c.disableCache = true
1329		return false
1330	}
1331
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)
1338			}
1339			c.disableCache = true
1340			return false
1341		}
1342		switch arg[:i] {
1343		case "-test.benchtime",
1344			"-test.cpu",
1345			"-test.list",
1346			"-test.parallel",
1347			"-test.run",
1348			"-test.short",
1349			"-test.timeout",
1350			"-test.v":
1351			// These are cacheable.
1352			// Note that this list is documented above,
1353			// so if you add to this list, update the docs too.
1354			cacheArgs = append(cacheArgs, arg)
1355
1356		default:
1357			// nothing else is cacheable
1358			if cache.DebugTest {
1359				fmt.Fprintf(os.Stderr, "testcache: caching disabled for test argument: %s\n", arg)
1360			}
1361			c.disableCache = true
1362			return false
1363		}
1364	}
1365
1366	if cache.Default() == nil {
1367		if cache.DebugTest {
1368			fmt.Fprintf(os.Stderr, "testcache: GOCACHE=off\n")
1369		}
1370		c.disableCache = true
1371		return false
1372	}
1373
1374	// The test cache result fetch is a two-level lookup.
1375	//
1376	// First, we use the content hash of the test binary
1377	// and its command-line arguments to find the
1378	// list of environment variables and files consulted
1379	// the last time the test was run with those arguments.
1380	// (To avoid unnecessary links, we store this entry
1381	// under two hashes: id1 uses the linker inputs as a
1382	// proxy for the test binary, and id2 uses the actual
1383	// test binary. If the linker inputs are unchanged,
1384	// this way we avoid the link step, even though we
1385	// do not cache link outputs.)
1386	//
1387	// Second, we compute a hash of the values of the
1388	// environment variables and the content of the files
1389	// listed in the log from the previous run.
1390	// Then we look up test output using a combination of
1391	// the hash from the first part (testID) and the hash of the
1392	// test inputs (testInputsID).
1393	//
1394	// In order to store a new test result, we must redo the
1395	// testInputsID computation using the log from the run
1396	// we want to cache, and then we store that new log and
1397	// the new outputs.
1398
1399	h := cache.NewHash("testResult")
1400	fmt.Fprintf(h, "test binary %s args %q execcmd %q", id, cacheArgs, work.ExecCmd)
1401	testID := h.Sum()
1402	if c.id1 == (cache.ActionID{}) {
1403		c.id1 = testID
1404	} else {
1405		c.id2 = testID
1406	}
1407	if cache.DebugTest {
1408		fmt.Fprintf(os.Stderr, "testcache: %s: test ID %x => %x\n", a.Package.ImportPath, id, testID)
1409	}
1410
1411	// Load list of referenced environment variables and files
1412	// from last run of testID, and compute hash of that content.
1413	data, entry, err := cache.Default().GetBytes(testID)
1414	if !bytes.HasPrefix(data, testlogMagic) || data[len(data)-1] != '\n' {
1415		if cache.DebugTest {
1416			if err != nil {
1417				fmt.Fprintf(os.Stderr, "testcache: %s: input list not found: %v\n", a.Package.ImportPath, err)
1418			} else {
1419				fmt.Fprintf(os.Stderr, "testcache: %s: input list malformed\n", a.Package.ImportPath)
1420			}
1421		}
1422		return false
1423	}
1424	testInputsID, err := computeTestInputsID(a, data)
1425	if err != nil {
1426		return false
1427	}
1428	if cache.DebugTest {
1429		fmt.Fprintf(os.Stderr, "testcache: %s: test ID %x => input ID %x => %x\n", a.Package.ImportPath, testID, testInputsID, testAndInputKey(testID, testInputsID))
1430	}
1431
1432	// Parse cached result in preparation for changing run time to "(cached)".
1433	// If we can't parse the cached result, don't use it.
1434	data, entry, err = cache.Default().GetBytes(testAndInputKey(testID, testInputsID))
1435	if len(data) == 0 || data[len(data)-1] != '\n' {
1436		if cache.DebugTest {
1437			if err != nil {
1438				fmt.Fprintf(os.Stderr, "testcache: %s: test output not found: %v\n", a.Package.ImportPath, err)
1439			} else {
1440				fmt.Fprintf(os.Stderr, "testcache: %s: test output malformed\n", a.Package.ImportPath)
1441			}
1442		}
1443		return false
1444	}
1445	if entry.Time.Before(testCacheExpire) {
1446		if cache.DebugTest {
1447			fmt.Fprintf(os.Stderr, "testcache: %s: test output expired due to go clean -testcache\n", a.Package.ImportPath)
1448		}
1449		return false
1450	}
1451	i := bytes.LastIndexByte(data[:len(data)-1], '\n') + 1
1452	if !bytes.HasPrefix(data[i:], []byte("ok  \t")) {
1453		if cache.DebugTest {
1454			fmt.Fprintf(os.Stderr, "testcache: %s: test output malformed\n", a.Package.ImportPath)
1455		}
1456		return false
1457	}
1458	j := bytes.IndexByte(data[i+len("ok  \t"):], '\t')
1459	if j < 0 {
1460		if cache.DebugTest {
1461			fmt.Fprintf(os.Stderr, "testcache: %s: test output malformed\n", a.Package.ImportPath)
1462		}
1463		return false
1464	}
1465	j += i + len("ok  \t") + 1
1466
1467	// Committed to printing.
1468	c.buf = new(bytes.Buffer)
1469	c.buf.Write(data[:j])
1470	c.buf.WriteString("(cached)")
1471	for j < len(data) && ('0' <= data[j] && data[j] <= '9' || data[j] == '.' || data[j] == 's') {
1472		j++
1473	}
1474	c.buf.Write(data[j:])
1475	return true
1476}
1477
1478var errBadTestInputs = errors.New("error parsing test inputs")
1479var testlogMagic = []byte("# test log\n") // known to testing/internal/testdeps/deps.go
1480
1481// computeTestInputsID computes the "test inputs ID"
1482// (see comment in tryCacheWithID above) for the
1483// test log.
1484func computeTestInputsID(a *work.Action, testlog []byte) (cache.ActionID, error) {
1485	testlog = bytes.TrimPrefix(testlog, testlogMagic)
1486	h := cache.NewHash("testInputs")
1487	pwd := a.Package.Dir
1488	for _, line := range bytes.Split(testlog, []byte("\n")) {
1489		if len(line) == 0 {
1490			continue
1491		}
1492		s := string(line)
1493		i := strings.Index(s, " ")
1494		if i < 0 {
1495			if cache.DebugTest {
1496				fmt.Fprintf(os.Stderr, "testcache: %s: input list malformed (%q)\n", a.Package.ImportPath, line)
1497			}
1498			return cache.ActionID{}, errBadTestInputs
1499		}
1500		op := s[:i]
1501		name := s[i+1:]
1502		switch op {
1503		default:
1504			if cache.DebugTest {
1505				fmt.Fprintf(os.Stderr, "testcache: %s: input list malformed (%q)\n", a.Package.ImportPath, line)
1506			}
1507			return cache.ActionID{}, errBadTestInputs
1508		case "getenv":
1509			fmt.Fprintf(h, "env %s %x\n", name, hashGetenv(name))
1510		case "chdir":
1511			pwd = name // always absolute
1512			fmt.Fprintf(h, "chdir %s %x\n", name, hashStat(name))
1513		case "stat":
1514			if !filepath.IsAbs(name) {
1515				name = filepath.Join(pwd, name)
1516			}
1517			if a.Package.Root == "" || search.InDir(name, a.Package.Root) == "" {
1518				// Do not recheck files outside the module, GOPATH, or GOROOT root.
1519				break
1520			}
1521			fmt.Fprintf(h, "stat %s %x\n", name, hashStat(name))
1522		case "open":
1523			if !filepath.IsAbs(name) {
1524				name = filepath.Join(pwd, name)
1525			}
1526			if a.Package.Root == "" || search.InDir(name, a.Package.Root) == "" {
1527				// Do not recheck files outside the module, GOPATH, or GOROOT root.
1528				break
1529			}
1530			fh, err := hashOpen(name)
1531			if err != nil {
1532				if cache.DebugTest {
1533					fmt.Fprintf(os.Stderr, "testcache: %s: input file %s: %s\n", a.Package.ImportPath, name, err)
1534				}
1535				return cache.ActionID{}, err
1536			}
1537			fmt.Fprintf(h, "open %s %x\n", name, fh)
1538		}
1539	}
1540	sum := h.Sum()
1541	return sum, nil
1542}
1543
1544func hashGetenv(name string) cache.ActionID {
1545	h := cache.NewHash("getenv")
1546	v, ok := os.LookupEnv(name)
1547	if !ok {
1548		h.Write([]byte{0})
1549	} else {
1550		h.Write([]byte{1})
1551		h.Write([]byte(v))
1552	}
1553	return h.Sum()
1554}
1555
1556const modTimeCutoff = 2 * time.Second
1557
1558var errFileTooNew = errors.New("file used as input is too new")
1559
1560func hashOpen(name string) (cache.ActionID, error) {
1561	h := cache.NewHash("open")
1562	info, err := os.Stat(name)
1563	if err != nil {
1564		fmt.Fprintf(h, "err %v\n", err)
1565		return h.Sum(), nil
1566	}
1567	hashWriteStat(h, info)
1568	if info.IsDir() {
1569		files, err := os.ReadDir(name)
1570		if err != nil {
1571			fmt.Fprintf(h, "err %v\n", err)
1572		}
1573		for _, f := range files {
1574			fmt.Fprintf(h, "file %s ", f.Name())
1575			finfo, err := f.Info()
1576			if err != nil {
1577				fmt.Fprintf(h, "err %v\n", err)
1578			} else {
1579				hashWriteStat(h, finfo)
1580			}
1581		}
1582	} else if info.Mode().IsRegular() {
1583		// Because files might be very large, do not attempt
1584		// to hash the entirety of their content. Instead assume
1585		// the mtime and size recorded in hashWriteStat above
1586		// are good enough.
1587		//
1588		// To avoid problems for very recent files where a new
1589		// write might not change the mtime due to file system
1590		// mtime precision, reject caching if a file was read that
1591		// is less than modTimeCutoff old.
1592		if time.Since(info.ModTime()) < modTimeCutoff {
1593			return cache.ActionID{}, errFileTooNew
1594		}
1595	}
1596	return h.Sum(), nil
1597}
1598
1599func hashStat(name string) cache.ActionID {
1600	h := cache.NewHash("stat")
1601	if info, err := os.Stat(name); err != nil {
1602		fmt.Fprintf(h, "err %v\n", err)
1603	} else {
1604		hashWriteStat(h, info)
1605	}
1606	if info, err := os.Lstat(name); err != nil {
1607		fmt.Fprintf(h, "err %v\n", err)
1608	} else {
1609		hashWriteStat(h, info)
1610	}
1611	return h.Sum()
1612}
1613
1614func hashWriteStat(h io.Writer, info fs.FileInfo) {
1615	fmt.Fprintf(h, "stat %d %x %v %v\n", info.Size(), uint64(info.Mode()), info.ModTime(), info.IsDir())
1616}
1617
1618// testAndInputKey returns the actual cache key for the pair (testID, testInputsID).
1619func testAndInputKey(testID, testInputsID cache.ActionID) cache.ActionID {
1620	return cache.Subkey(testID, fmt.Sprintf("inputs:%x", testInputsID))
1621}
1622
1623func (c *runCache) saveOutput(a *work.Action) {
1624	if c.id1 == (cache.ActionID{}) && c.id2 == (cache.ActionID{}) {
1625		return
1626	}
1627
1628	// See comment about two-level lookup in tryCacheWithID above.
1629	testlog, err := os.ReadFile(a.Objdir + "testlog.txt")
1630	if err != nil || !bytes.HasPrefix(testlog, testlogMagic) || testlog[len(testlog)-1] != '\n' {
1631		if cache.DebugTest {
1632			if err != nil {
1633				fmt.Fprintf(os.Stderr, "testcache: %s: reading testlog: %v\n", a.Package.ImportPath, err)
1634			} else {
1635				fmt.Fprintf(os.Stderr, "testcache: %s: reading testlog: malformed\n", a.Package.ImportPath)
1636			}
1637		}
1638		return
1639	}
1640	testInputsID, err := computeTestInputsID(a, testlog)
1641	if err != nil {
1642		return
1643	}
1644	if c.id1 != (cache.ActionID{}) {
1645		if cache.DebugTest {
1646			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))
1647		}
1648		cache.Default().PutNoVerify(c.id1, bytes.NewReader(testlog))
1649		cache.Default().PutNoVerify(testAndInputKey(c.id1, testInputsID), bytes.NewReader(a.TestOutput.Bytes()))
1650	}
1651	if c.id2 != (cache.ActionID{}) {
1652		if cache.DebugTest {
1653			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))
1654		}
1655		cache.Default().PutNoVerify(c.id2, bytes.NewReader(testlog))
1656		cache.Default().PutNoVerify(testAndInputKey(c.id2, testInputsID), bytes.NewReader(a.TestOutput.Bytes()))
1657	}
1658}
1659
1660// coveragePercentage returns the coverage results (if enabled) for the
1661// test. It uncovers the data by scanning the output from the test run.
1662func coveragePercentage(out []byte) string {
1663	if !testCover {
1664		return ""
1665	}
1666	// The string looks like
1667	//	test coverage for encoding/binary: 79.9% of statements
1668	// Extract the piece from the percentage to the end of the line.
1669	re := regexp.MustCompile(`coverage: (.*)\n`)
1670	matches := re.FindSubmatch(out)
1671	if matches == nil {
1672		// Probably running "go test -cover" not "go test -cover fmt".
1673		// The coverage output will appear in the output directly.
1674		return ""
1675	}
1676	return fmt.Sprintf("\tcoverage: %s", matches[1])
1677}
1678
1679// builderCleanTest is the action for cleaning up after a test.
1680func builderCleanTest(b *work.Builder, ctx context.Context, a *work.Action) error {
1681	if cfg.BuildWork {
1682		return nil
1683	}
1684	if cfg.BuildX {
1685		b.Showcmd("", "rm -r %s", a.Objdir)
1686	}
1687	os.RemoveAll(a.Objdir)
1688	return nil
1689}
1690
1691// builderPrintTest is the action for printing a test result.
1692func builderPrintTest(b *work.Builder, ctx context.Context, a *work.Action) error {
1693	clean := a.Deps[0]
1694	run := clean.Deps[0]
1695	if run.TestOutput != nil {
1696		os.Stdout.Write(run.TestOutput.Bytes())
1697		run.TestOutput = nil
1698	}
1699	return nil
1700}
1701
1702// builderNoTest is the action for testing a package with no test files.
1703func builderNoTest(b *work.Builder, ctx context.Context, a *work.Action) error {
1704	var stdout io.Writer = os.Stdout
1705	if testJSON {
1706		json := test2json.NewConverter(lockedStdout{}, a.Package.ImportPath, test2json.Timestamp)
1707		defer json.Close()
1708		stdout = json
1709	}
1710	fmt.Fprintf(stdout, "?   \t%s\t[no test files]\n", a.Package.ImportPath)
1711	return nil
1712}
1713
1714// printExitStatus is the action for printing the exit status
1715func printExitStatus(b *work.Builder, ctx context.Context, a *work.Action) error {
1716	if !testJSON && len(pkgArgs) != 0 {
1717		if base.GetExitStatus() != 0 {
1718			fmt.Println("FAIL")
1719			return nil
1720		}
1721	}
1722	return nil
1723}
1724