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