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