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