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