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