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