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 "errors" 11 "fmt" 12 "internal/coverage" 13 "internal/platform" 14 "io" 15 "io/fs" 16 "os" 17 "os/exec" 18 "path/filepath" 19 "regexp" 20 "slices" 21 "strconv" 22 "strings" 23 "sync" 24 "sync/atomic" 25 "time" 26 27 "cmd/go/internal/base" 28 "cmd/go/internal/cache" 29 "cmd/go/internal/cfg" 30 "cmd/go/internal/load" 31 "cmd/go/internal/lockedfile" 32 "cmd/go/internal/modload" 33 "cmd/go/internal/search" 34 "cmd/go/internal/str" 35 "cmd/go/internal/trace" 36 "cmd/go/internal/work" 37 "cmd/internal/test2json" 38 39 "golang.org/x/mod/module" 40) 41 42// Break init loop. 43func init() { 44 CmdTest.Run = runTest 45} 46 47const testUsage = "go test [build/test flags] [packages] [build/test flags & test binary flags]" 48 49var CmdTest = &base.Command{ 50 CustomFlags: true, 51 UsageLine: testUsage, 52 Short: "test packages", 53 Long: ` 54'Go test' automates testing the packages named by the import paths. 55It prints a summary of the test results in the format: 56 57 ok archive/tar 0.011s 58 FAIL archive/zip 0.022s 59 ok compress/gzip 0.033s 60 ... 61 62followed by detailed output for each failed package. 63 64'Go test' recompiles each package along with any files with names matching 65the file pattern "*_test.go". 66These additional files can contain test functions, benchmark functions, fuzz 67tests and example functions. See 'go help testfunc' for more. 68Each listed package causes the execution of a separate test binary. 69Files whose names begin with "_" (including "_test.go") or "." are ignored. 70 71Test files that declare a package with the suffix "_test" will be compiled as a 72separate package, and then linked and run with the main test binary. 73 74The go tool will ignore a directory named "testdata", making it available 75to hold ancillary data needed by the tests. 76 77As part of building a test binary, go test runs go vet on the package 78and its test source files to identify significant problems. If go vet 79finds any problems, go test reports those and does not run the test 80binary. Only a high-confidence subset of the default go vet checks are 81used. That subset is: atomic, bool, buildtags, directive, errorsas, 82ifaceassert, nilfunc, printf, and stringintconv. You can see 83the documentation for these and other vet tests via "go doc cmd/vet". 84To disable the running of go vet, use the -vet=off flag. To run all 85checks, use the -vet=all flag. 86 87All test output and summary lines are printed to the go command's 88standard output, even if the test printed them to its own standard 89error. (The go command's standard error is reserved for printing 90errors building the tests.) 91 92The go command places $GOROOT/bin at the beginning of $PATH 93in the test's environment, so that tests that execute 94'go' commands use the same 'go' as the parent 'go test' command. 95 96Go test runs in two different modes: 97 98The first, called local directory mode, occurs when go test is 99invoked with no package arguments (for example, 'go test' or 'go 100test -v'). In this mode, go test compiles the package sources and 101tests found in the current directory and then runs the resulting 102test binary. In this mode, caching (discussed below) is disabled. 103After the package test finishes, go test prints a summary line 104showing the test status ('ok' or 'FAIL'), package name, and elapsed 105time. 106 107The second, called package list mode, occurs when go test is invoked 108with explicit package arguments (for example 'go test math', 'go 109test ./...', and even 'go test .'). In this mode, go test compiles 110and tests each of the packages listed on the command line. If a 111package test passes, go test prints only the final 'ok' summary 112line. If a package test fails, go test prints the full test output. 113If invoked with the -bench or -v flag, go test prints the full 114output even for passing package tests, in order to display the 115requested benchmark results or verbose logging. After the package 116tests for all of the listed packages finish, and their output is 117printed, go test prints a final 'FAIL' status if any package test 118has failed. 119 120In package list mode only, go test caches successful package test 121results to avoid unnecessary repeated running of tests. When the 122result of a test can be recovered from the cache, go test will 123redisplay the previous output instead of running the test binary 124again. When this happens, go test prints '(cached)' in place of the 125elapsed time in the summary line. 126 127The rule for a match in the cache is that the run involves the same 128test binary and the flags on the command line come entirely from a 129restricted set of 'cacheable' test flags, defined as -benchtime, -cpu, 130-list, -parallel, -run, -short, -timeout, -failfast, -fullpath and -v. 131If a run of go test has any test or non-test flags outside this set, 132the result is not cached. To disable test caching, use any test flag 133or argument other than the cacheable flags. The idiomatic way to disable 134test caching explicitly is to use -count=1. Tests that open files within 135the package's source root (usually $GOPATH) or that consult environment 136variables only match future runs in which the files and environment 137variables are unchanged. A cached test result is treated as executing 138in no time at all, so a successful package test result will be cached and 139reused regardless of -timeout setting. 140 141In addition to the build flags, the flags handled by 'go test' itself are: 142 143 -args 144 Pass the remainder of the command line (everything after -args) 145 to the test binary, uninterpreted and unchanged. 146 Because this flag consumes the remainder of the command line, 147 the package list (if present) must appear before this flag. 148 149 -c 150 Compile the test binary to pkg.test in the current directory but do not run it 151 (where pkg is the last element of the package's import path). 152 The file name or target directory can be changed with the -o flag. 153 154 -exec xprog 155 Run the test binary using xprog. The behavior is the same as 156 in 'go run'. See 'go help run' for details. 157 158 -json 159 Convert test output to JSON suitable for automated processing. 160 See 'go doc test2json' for the encoding details. 161 162 -o file 163 Compile the test binary to the named file. 164 The test still runs (unless -c or -i is specified). 165 If file ends in a slash or names an existing directory, 166 the test is written to pkg.test in that directory. 167 168The test binary also accepts flags that control execution of the test; these 169flags are also accessible by 'go test'. See 'go help testflag' for details. 170 171For more about build flags, see 'go help build'. 172For more about specifying packages, see 'go help packages'. 173 174See also: go build, go vet. 175`, 176} 177 178var HelpTestflag = &base.Command{ 179 UsageLine: "testflag", 180 Short: "testing flags", 181 Long: ` 182The 'go test' command takes both flags that apply to 'go test' itself 183and flags that apply to the resulting test binary. 184 185Several of the flags control profiling and write an execution profile 186suitable for "go tool pprof"; run "go tool pprof -h" for more 187information. The --alloc_space, --alloc_objects, and --show_bytes 188options of pprof control how the information is presented. 189 190The following flags are recognized by the 'go test' command and 191control the execution of any test: 192 193 -bench regexp 194 Run only those benchmarks matching a regular expression. 195 By default, no benchmarks are run. 196 To run all benchmarks, use '-bench .' or '-bench=.'. 197 The regular expression is split by unbracketed slash (/) 198 characters into a sequence of regular expressions, and each 199 part of a benchmark's identifier must match the corresponding 200 element in the sequence, if any. Possible parents of matches 201 are run with b.N=1 to identify sub-benchmarks. For example, 202 given -bench=X/Y, top-level benchmarks matching X are run 203 with b.N=1 to find any sub-benchmarks matching Y, which are 204 then run in full. 205 206 -benchtime t 207 Run enough iterations of each benchmark to take t, specified 208 as a time.Duration (for example, -benchtime 1h30s). 209 The default is 1 second (1s). 210 The special syntax Nx means to run the benchmark N times 211 (for example, -benchtime 100x). 212 213 -count n 214 Run each test, benchmark, and fuzz seed n times (default 1). 215 If -cpu is set, run n times for each GOMAXPROCS value. 216 Examples are always run once. -count does not apply to 217 fuzz tests matched by -fuzz. 218 219 -cover 220 Enable coverage analysis. 221 Note that because coverage works by annotating the source 222 code before compilation, compilation and test failures with 223 coverage enabled may report line numbers that don't correspond 224 to the original sources. 225 226 -covermode set,count,atomic 227 Set the mode for coverage analysis for the package[s] 228 being tested. The default is "set" unless -race is enabled, 229 in which case it is "atomic". 230 The values: 231 set: bool: does this statement run? 232 count: int: how many times does this statement run? 233 atomic: int: count, but correct in multithreaded tests; 234 significantly more expensive. 235 Sets -cover. 236 237 -coverpkg pattern1,pattern2,pattern3 238 Apply coverage analysis in each test to packages matching the patterns. 239 The default is for each test to analyze only the package being tested. 240 See 'go help packages' for a description of package patterns. 241 Sets -cover. 242 243 -cpu 1,2,4 244 Specify a list of GOMAXPROCS values for which the tests, benchmarks or 245 fuzz tests should be executed. The default is the current value 246 of GOMAXPROCS. -cpu does not apply to fuzz tests matched by -fuzz. 247 248 -failfast 249 Do not start new tests after the first test failure. 250 251 -fullpath 252 Show full file names in the error messages. 253 254 -fuzz regexp 255 Run the fuzz test matching the regular expression. When specified, 256 the command line argument must match exactly one package within the 257 main module, and regexp must match exactly one fuzz test within 258 that package. Fuzzing will occur after tests, benchmarks, seed corpora 259 of other fuzz tests, and examples have completed. See the Fuzzing 260 section of the testing package documentation for details. 261 262 -fuzztime t 263 Run enough iterations of the fuzz target during fuzzing to take t, 264 specified as a time.Duration (for example, -fuzztime 1h30s). 265 The default is to run forever. 266 The special syntax Nx means to run the fuzz target N times 267 (for example, -fuzztime 1000x). 268 269 -fuzzminimizetime t 270 Run enough iterations of the fuzz target during each minimization 271 attempt to take t, as specified as a time.Duration (for example, 272 -fuzzminimizetime 30s). 273 The default is 60s. 274 The special syntax Nx means to run the fuzz target N times 275 (for example, -fuzzminimizetime 100x). 276 277 -json 278 Log verbose output and test results in JSON. This presents the 279 same information as the -v flag in a machine-readable format. 280 281 -list regexp 282 List tests, benchmarks, fuzz tests, or examples matching the regular 283 expression. No tests, benchmarks, fuzz tests, or examples will be run. 284 This will only list top-level tests. No subtest or subbenchmarks will be 285 shown. 286 287 -parallel n 288 Allow parallel execution of test functions that call t.Parallel, and 289 fuzz targets that call t.Parallel when running the seed corpus. 290 The value of this flag is the maximum number of tests to run 291 simultaneously. 292 While fuzzing, the value of this flag is the maximum number of 293 subprocesses that may call the fuzz function simultaneously, regardless of 294 whether T.Parallel is called. 295 By default, -parallel is set to the value of GOMAXPROCS. 296 Setting -parallel to values higher than GOMAXPROCS may cause degraded 297 performance due to CPU contention, especially when fuzzing. 298 Note that -parallel only applies within a single test binary. 299 The 'go test' command may run tests for different packages 300 in parallel as well, according to the setting of the -p flag 301 (see 'go help build'). 302 303 -run regexp 304 Run only those tests, examples, and fuzz tests matching the regular 305 expression. For tests, the regular expression is split by unbracketed 306 slash (/) characters into a sequence of regular expressions, and each 307 part of a test's identifier must match the corresponding element in 308 the sequence, if any. Note that possible parents of matches are 309 run too, so that -run=X/Y matches and runs and reports the result 310 of all tests matching X, even those without sub-tests matching Y, 311 because it must run them to look for those sub-tests. 312 See also -skip. 313 314 -short 315 Tell long-running tests to shorten their run time. 316 It is off by default but set during all.bash so that installing 317 the Go tree can run a sanity check but not spend time running 318 exhaustive tests. 319 320 -shuffle off,on,N 321 Randomize the execution order of tests and benchmarks. 322 It is off by default. If -shuffle is set to on, then it will seed 323 the randomizer using the system clock. If -shuffle is set to an 324 integer N, then N will be used as the seed value. In both cases, 325 the seed will be reported for reproducibility. 326 327 -skip regexp 328 Run only those tests, examples, fuzz tests, and benchmarks that 329 do not match the regular expression. Like for -run and -bench, 330 for tests and benchmarks, the regular expression is split by unbracketed 331 slash (/) characters into a sequence of regular expressions, and each 332 part of a test's identifier must match the corresponding element in 333 the sequence, if any. 334 335 -timeout d 336 If a test binary runs longer than duration d, panic. 337 If d is 0, the timeout is disabled. 338 The default is 10 minutes (10m). 339 340 -v 341 Verbose output: log all tests as they are run. Also print all 342 text from Log and Logf calls even if the test succeeds. 343 344 -vet list 345 Configure the invocation of "go vet" during "go test" 346 to use the comma-separated list of vet checks. 347 If list is empty, "go test" runs "go vet" with a curated list of 348 checks believed to be always worth addressing. 349 If list is "off", "go test" does not run "go vet" at all. 350 351The following flags are also recognized by 'go test' and can be used to 352profile the tests during execution: 353 354 -benchmem 355 Print memory allocation statistics for benchmarks. 356 Allocations made in C or using C.malloc are not counted. 357 358 -blockprofile block.out 359 Write a goroutine blocking profile to the specified file 360 when all tests are complete. 361 Writes test binary as -c would. 362 363 -blockprofilerate n 364 Control the detail provided in goroutine blocking profiles by 365 calling runtime.SetBlockProfileRate with n. 366 See 'go doc runtime.SetBlockProfileRate'. 367 The profiler aims to sample, on average, one blocking event every 368 n nanoseconds the program spends blocked. By default, 369 if -test.blockprofile is set without this flag, all blocking events 370 are recorded, equivalent to -test.blockprofilerate=1. 371 372 -coverprofile cover.out 373 Write a coverage profile to the file after all tests have passed. 374 Sets -cover. 375 376 -cpuprofile cpu.out 377 Write a CPU profile to the specified file before exiting. 378 Writes test binary as -c would. 379 380 -memprofile mem.out 381 Write an allocation profile to the file after all tests have passed. 382 Writes test binary as -c would. 383 384 -memprofilerate n 385 Enable more precise (and expensive) memory allocation profiles by 386 setting runtime.MemProfileRate. See 'go doc runtime.MemProfileRate'. 387 To profile all memory allocations, use -test.memprofilerate=1. 388 389 -mutexprofile mutex.out 390 Write a mutex contention profile to the specified file 391 when all tests are complete. 392 Writes test binary as -c would. 393 394 -mutexprofilefraction n 395 Sample 1 in n stack traces of goroutines holding a 396 contended mutex. 397 398 -outputdir directory 399 Place output files from profiling in the specified directory, 400 by default the directory in which "go test" is running. 401 402 -trace trace.out 403 Write an execution trace to the specified file before exiting. 404 405Each of these flags is also recognized with an optional 'test.' prefix, 406as in -test.v. When invoking the generated test binary (the result of 407'go test -c') directly, however, the prefix is mandatory. 408 409The 'go test' command rewrites or removes recognized flags, 410as appropriate, both before and after the optional package list, 411before invoking the test binary. 412 413For instance, the command 414 415 go test -v -myflag testdata -cpuprofile=prof.out -x 416 417will compile the test binary and then run it as 418 419 pkg.test -test.v -myflag testdata -test.cpuprofile=prof.out 420 421(The -x flag is removed because it applies only to the go command's 422execution, not to the test itself.) 423 424The test flags that generate profiles (other than for coverage) also 425leave the test binary in pkg.test for use when analyzing the profiles. 426 427When 'go test' runs a test binary, it does so from within the 428corresponding package's source code directory. Depending on the test, 429it may be necessary to do the same when invoking a generated test 430binary directly. Because that directory may be located within the 431module cache, which may be read-only and is verified by checksums, the 432test must not write to it or any other directory within the module 433unless explicitly requested by the user (such as with the -fuzz flag, 434which writes failures to testdata/fuzz). 435 436The command-line package list, if present, must appear before any 437flag not known to the go test command. Continuing the example above, 438the package list would have to appear before -myflag, but could appear 439on either side of -v. 440 441When 'go test' runs in package list mode, 'go test' caches successful 442package test results to avoid unnecessary repeated running of tests. To 443disable test caching, use any test flag or argument other than the 444cacheable flags. The idiomatic way to disable test caching explicitly 445is to use -count=1. 446 447To keep an argument for a test binary from being interpreted as a 448known flag or a package name, use -args (see 'go help test') which 449passes the remainder of the command line through to the test binary 450uninterpreted and unaltered. 451 452For instance, the command 453 454 go test -v -args -x -v 455 456will compile the test binary and then run it as 457 458 pkg.test -test.v -x -v 459 460Similarly, 461 462 go test -args math 463 464will compile the test binary and then run it as 465 466 pkg.test math 467 468In the first example, the -x and the second -v are passed through to the 469test binary unchanged and with no effect on the go command itself. 470In the second example, the argument math is passed through to the test 471binary, instead of being interpreted as the package list. 472`, 473} 474 475var HelpTestfunc = &base.Command{ 476 UsageLine: "testfunc", 477 Short: "testing functions", 478 Long: ` 479The 'go test' command expects to find test, benchmark, and example functions 480in the "*_test.go" files corresponding to the package under test. 481 482A test function is one named TestXxx (where Xxx does not start with a 483lower case letter) and should have the signature, 484 485 func TestXxx(t *testing.T) { ... } 486 487A benchmark function is one named BenchmarkXxx and should have the signature, 488 489 func BenchmarkXxx(b *testing.B) { ... } 490 491A fuzz test is one named FuzzXxx and should have the signature, 492 493 func FuzzXxx(f *testing.F) { ... } 494 495An example function is similar to a test function but, instead of using 496*testing.T to report success or failure, prints output to os.Stdout. 497If the last comment in the function starts with "Output:" then the output 498is compared exactly against the comment (see examples below). If the last 499comment begins with "Unordered output:" then the output is compared to the 500comment, however the order of the lines is ignored. An example with no such 501comment is compiled but not executed. An example with no text after 502"Output:" is compiled, executed, and expected to produce no output. 503 504Godoc displays the body of ExampleXxx to demonstrate the use 505of the function, constant, or variable Xxx. An example of a method M with 506receiver type T or *T is named ExampleT_M. There may be multiple examples 507for a given function, constant, or variable, distinguished by a trailing _xxx, 508where xxx is a suffix not beginning with an upper case letter. 509 510Here is an example of an example: 511 512 func ExamplePrintln() { 513 Println("The output of\nthis example.") 514 // Output: The output of 515 // this example. 516 } 517 518Here is another example where the ordering of the output is ignored: 519 520 func ExamplePerm() { 521 for _, value := range Perm(4) { 522 fmt.Println(value) 523 } 524 525 // Unordered output: 4 526 // 2 527 // 1 528 // 3 529 // 0 530 } 531 532The entire test file is presented as the example when it contains a single 533example function, at least one other function, type, variable, or constant 534declaration, and no tests, benchmarks, or fuzz tests. 535 536See the documentation of the testing package for more information. 537`, 538} 539 540var ( 541 testBench string // -bench flag 542 testC bool // -c flag 543 testCoverPkgs []*load.Package // -coverpkg flag 544 testCoverProfile string // -coverprofile flag 545 testFailFast bool // -failfast flag 546 testFuzz string // -fuzz flag 547 testJSON bool // -json flag 548 testList string // -list flag 549 testO string // -o flag 550 testOutputDir outputdirFlag // -outputdir flag 551 testShuffle shuffleFlag // -shuffle flag 552 testTimeout time.Duration // -timeout flag 553 testV testVFlag // -v flag 554 testVet = vetFlag{flags: defaultVetFlags} // -vet flag 555) 556 557type testVFlag struct { 558 on bool // -v is set in some form 559 json bool // -v=test2json is set, to make output better for test2json 560} 561 562func (*testVFlag) IsBoolFlag() bool { return true } 563 564func (f *testVFlag) Set(arg string) error { 565 if v, err := strconv.ParseBool(arg); err == nil { 566 f.on = v 567 f.json = false 568 return nil 569 } 570 if arg == "test2json" { 571 f.on = true 572 f.json = arg == "test2json" 573 return nil 574 } 575 return fmt.Errorf("invalid flag -test.v=%s", arg) 576} 577 578func (f *testVFlag) String() string { 579 if f.json { 580 return "test2json" 581 } 582 if f.on { 583 return "true" 584 } 585 return "false" 586} 587 588var ( 589 testArgs []string 590 pkgArgs []string 591 pkgs []*load.Package 592 593 testHelp bool // -help option passed to test via -args 594 595 testKillTimeout = 100 * 365 * 24 * time.Hour // backup alarm; defaults to about a century if no timeout is set 596 testWaitDelay time.Duration // how long to wait for output to close after a test binary exits; zero means unlimited 597 testCacheExpire time.Time // ignore cached test results before this time 598 testShouldFailFast atomic.Bool // signals pending tests to fail fast 599 600 testBlockProfile, testCPUProfile, testMemProfile, testMutexProfile, testTrace string // profiling flag that limits test to one package 601 602 testODir = false 603) 604 605// testProfile returns the name of an arbitrary single-package profiling flag 606// that is set, if any. 607func testProfile() string { 608 switch { 609 case testBlockProfile != "": 610 return "-blockprofile" 611 case testCPUProfile != "": 612 return "-cpuprofile" 613 case testMemProfile != "": 614 return "-memprofile" 615 case testMutexProfile != "": 616 return "-mutexprofile" 617 case testTrace != "": 618 return "-trace" 619 default: 620 return "" 621 } 622} 623 624// testNeedBinary reports whether the test needs to keep the binary around. 625func testNeedBinary() bool { 626 switch { 627 case testBlockProfile != "": 628 return true 629 case testCPUProfile != "": 630 return true 631 case testMemProfile != "": 632 return true 633 case testMutexProfile != "": 634 return true 635 case testO != "": 636 return true 637 default: 638 return false 639 } 640} 641 642// testShowPass reports whether the output for a passing test should be shown. 643func testShowPass() bool { 644 return testV.on || testList != "" || testHelp 645} 646 647var defaultVetFlags = []string{ 648 // TODO(rsc): Decide which tests are enabled by default. 649 // See golang.org/issue/18085. 650 // "-asmdecl", 651 // "-assign", 652 "-atomic", 653 "-bool", 654 "-buildtags", 655 // "-cgocall", 656 // "-composites", 657 // "-copylocks", 658 "-directive", 659 "-errorsas", 660 // "-httpresponse", 661 "-ifaceassert", 662 // "-lostcancel", 663 // "-methods", 664 "-nilfunc", 665 "-printf", 666 // "-rangeloops", 667 // "-shift", 668 "-slog", 669 "-stringintconv", 670 // "-structtags", 671 // "-tests", 672 // "-unreachable", 673 // "-unsafeptr", 674 // "-unusedresult", 675} 676 677func runTest(ctx context.Context, cmd *base.Command, args []string) { 678 pkgArgs, testArgs = testFlags(args) 679 modload.InitWorkfile() // The test command does custom flag processing; initialize workspaces after that. 680 681 if cfg.DebugTrace != "" { 682 var close func() error 683 var err error 684 ctx, close, err = trace.Start(ctx, cfg.DebugTrace) 685 if err != nil { 686 base.Fatalf("failed to start trace: %v", err) 687 } 688 defer func() { 689 if err := close(); err != nil { 690 base.Fatalf("failed to stop trace: %v", err) 691 } 692 }() 693 } 694 695 ctx, span := trace.StartSpan(ctx, fmt.Sprint("Running ", cmd.Name(), " command")) 696 defer span.Done() 697 698 work.FindExecCmd() // initialize cached result 699 700 work.BuildInit() 701 work.VetFlags = testVet.flags 702 work.VetExplicit = testVet.explicit 703 704 pkgOpts := load.PackageOpts{ModResolveTests: true} 705 pkgs = load.PackagesAndErrors(ctx, pkgOpts, pkgArgs) 706 load.CheckPackageErrors(pkgs) 707 if len(pkgs) == 0 { 708 base.Fatalf("no packages to test") 709 } 710 711 if testFuzz != "" { 712 if !platform.FuzzSupported(cfg.Goos, cfg.Goarch) { 713 base.Fatalf("-fuzz flag is not supported on %s/%s", cfg.Goos, cfg.Goarch) 714 } 715 if len(pkgs) != 1 { 716 base.Fatalf("cannot use -fuzz flag with multiple packages") 717 } 718 if testCoverProfile != "" { 719 base.Fatalf("cannot use -coverprofile flag with -fuzz flag") 720 } 721 if profileFlag := testProfile(); profileFlag != "" { 722 base.Fatalf("cannot use %s flag with -fuzz flag", profileFlag) 723 } 724 725 // Reject the '-fuzz' flag if the package is outside the main module. 726 // Otherwise, if fuzzing identifies a failure it could corrupt checksums in 727 // the module cache (or permanently alter the behavior of std tests for all 728 // users) by writing the failing input to the package's testdata directory. 729 // (See https://golang.org/issue/48495 and test_fuzz_modcache.txt.) 730 mainMods := modload.MainModules 731 if m := pkgs[0].Module; m != nil && m.Path != "" { 732 if !mainMods.Contains(m.Path) { 733 base.Fatalf("cannot use -fuzz flag on package outside the main module") 734 } 735 } else if pkgs[0].Standard && modload.Enabled() { 736 // Because packages in 'std' and 'cmd' are part of the standard library, 737 // they are only treated as part of a module in 'go mod' subcommands and 738 // 'go get'. However, we still don't want to accidentally corrupt their 739 // testdata during fuzzing, nor do we want to fail with surprising errors 740 // if GOROOT isn't writable (as is often the case for Go toolchains 741 // installed through package managers). 742 // 743 // If the user is requesting to fuzz a standard-library package, ensure 744 // that they are in the same module as that package (just like when 745 // fuzzing any other package). 746 if strings.HasPrefix(pkgs[0].ImportPath, "cmd/") { 747 if !mainMods.Contains("cmd") || !mainMods.InGorootSrc(module.Version{Path: "cmd"}) { 748 base.Fatalf("cannot use -fuzz flag on package outside the main module") 749 } 750 } else { 751 if !mainMods.Contains("std") || !mainMods.InGorootSrc(module.Version{Path: "std"}) { 752 base.Fatalf("cannot use -fuzz flag on package outside the main module") 753 } 754 } 755 } 756 } 757 if testProfile() != "" && len(pkgs) != 1 { 758 base.Fatalf("cannot use %s flag with multiple packages", testProfile()) 759 } 760 761 if testO != "" { 762 if strings.HasSuffix(testO, "/") || strings.HasSuffix(testO, string(os.PathSeparator)) { 763 testODir = true 764 } else if fi, err := os.Stat(testO); err == nil && fi.IsDir() { 765 testODir = true 766 } 767 } 768 769 if len(pkgs) > 1 && (testC || testO != "") && !base.IsNull(testO) { 770 if testO != "" && !testODir { 771 base.Fatalf("with multiple packages, -o must refer to a directory or %s", os.DevNull) 772 } 773 774 pkgsForBinary := map[string][]*load.Package{} 775 776 for _, p := range pkgs { 777 testBinary := testBinaryName(p) 778 pkgsForBinary[testBinary] = append(pkgsForBinary[testBinary], p) 779 } 780 781 for testBinary, pkgs := range pkgsForBinary { 782 if len(pkgs) > 1 { 783 var buf strings.Builder 784 for _, pkg := range pkgs { 785 buf.WriteString(pkg.ImportPath) 786 buf.WriteString("\n") 787 } 788 789 base.Errorf("cannot write test binary %s for multiple packages:\n%s", testBinary, buf.String()) 790 } 791 } 792 793 base.ExitIfErrors() 794 } 795 796 initCoverProfile() 797 defer closeCoverProfile() 798 799 // If a test timeout is finite, set our kill timeout 800 // to that timeout plus one minute. This is a backup alarm in case 801 // the test wedges with a goroutine spinning and its background 802 // timer does not get a chance to fire. 803 // Don't set this if fuzzing, since it should be able to run 804 // indefinitely. 805 if testTimeout > 0 && testFuzz == "" { 806 // The WaitDelay for the test process depends on both the OS I/O and 807 // scheduling overhead and the amount of I/O generated by the test just 808 // before it exits. We set the minimum at 5 seconds to account for the OS 809 // overhead, and scale it up from there proportional to the overall test 810 // timeout on the assumption that the time to write and read a goroutine 811 // dump from a timed-out test process scales roughly with the overall 812 // running time of the test. 813 // 814 // This is probably too generous when the timeout is very long, but it seems 815 // better to hard-code a scale factor than to hard-code a constant delay. 816 if wd := testTimeout / 10; wd < 5*time.Second { 817 testWaitDelay = 5 * time.Second 818 } else { 819 testWaitDelay = wd 820 } 821 822 // We expect the test binary to terminate itself (and dump stacks) after 823 // exactly testTimeout. We give it up to one WaitDelay or one minute, 824 // whichever is longer, to finish dumping stacks before we send it an 825 // external signal: if the process has a lot of goroutines, dumping stacks 826 // after the timeout can take a while. 827 // 828 // After the signal is delivered, the test process may have up to one 829 // additional WaitDelay to finish writing its output streams. 830 if testWaitDelay < 1*time.Minute { 831 testKillTimeout = testTimeout + 1*time.Minute 832 } else { 833 testKillTimeout = testTimeout + testWaitDelay 834 } 835 } 836 837 // Read testcache expiration time, if present. 838 // (We implement go clean -testcache by writing an expiration date 839 // instead of searching out and deleting test result cache entries.) 840 if dir, _ := cache.DefaultDir(); dir != "off" { 841 if data, _ := lockedfile.Read(filepath.Join(dir, "testexpire.txt")); len(data) > 0 && data[len(data)-1] == '\n' { 842 if t, err := strconv.ParseInt(string(data[:len(data)-1]), 10, 64); err == nil { 843 testCacheExpire = time.Unix(0, t) 844 } 845 } 846 } 847 848 b := work.NewBuilder("") 849 defer func() { 850 if err := b.Close(); err != nil { 851 base.Fatal(err) 852 } 853 }() 854 855 var builds, runs, prints []*work.Action 856 var writeCoverMetaAct *work.Action 857 858 if cfg.BuildCoverPkg != nil { 859 match := make([]func(*load.Package) bool, len(cfg.BuildCoverPkg)) 860 for i := range cfg.BuildCoverPkg { 861 match[i] = load.MatchPackage(cfg.BuildCoverPkg[i], base.Cwd()) 862 } 863 864 // Select for coverage all dependencies matching the -coverpkg 865 // patterns. 866 plist := load.TestPackageList(ctx, pkgOpts, pkgs) 867 testCoverPkgs = load.SelectCoverPackages(plist, match, "test") 868 if cfg.Experiment.CoverageRedesign && len(testCoverPkgs) > 0 { 869 // create a new singleton action that will collect up the 870 // meta-data files from all of the packages mentioned in 871 // "-coverpkg" and write them to a summary file. This new 872 // action will depend on all the build actions for the 873 // test packages, and all the run actions for these 874 // packages will depend on it. Motivating example: 875 // supposed we have a top level directory with three 876 // package subdirs, "a", "b", and "c", and 877 // from the top level, a user runs "go test -coverpkg=./... ./...". 878 // This will result in (roughly) the following action graph: 879 // 880 // build("a") build("b") build("c") 881 // | | | 882 // link("a.test") link("b.test") link("c.test") 883 // | | | 884 // run("a.test") run("b.test") run("c.test") 885 // | | | 886 // print print print 887 // 888 // When -coverpkg=<pattern> is in effect, we want to 889 // express the coverage percentage for each package as a 890 // fraction of *all* the statements that match the 891 // pattern, hence if "c" doesn't import "a", we need to 892 // pass as meta-data file for "a" (emitted during the 893 // package "a" build) to the package "c" run action, so 894 // that it can be incorporated with "c"'s regular 895 // metadata. To do this, we add edges from each compile 896 // action to a "writeCoverMeta" action, then from the 897 // writeCoverMeta action to each run action. Updated 898 // graph: 899 // 900 // build("a") build("b") build("c") 901 // | \ / | / | 902 // | v v | / | 903 // | writemeta <-|-------------+ | 904 // | ||| | | 905 // | ||\ | | 906 // link("a.test")/\ \ link("b.test") link("c.test") 907 // | / \ +-|--------------+ | 908 // | / \ | \ | 909 // | v v | v | 910 // run("a.test") run("b.test") run("c.test") 911 // | | | 912 // print print print 913 // 914 writeCoverMetaAct = &work.Action{ 915 Mode: "write coverage meta-data file", 916 Actor: work.ActorFunc(work.WriteCoverMetaFilesFile), 917 Objdir: b.NewObjdir(), 918 } 919 for _, p := range testCoverPkgs { 920 p.Internal.Cover.GenMeta = true 921 } 922 } 923 } 924 925 // Inform the compiler that it should instrument the binary at 926 // build-time when fuzzing is enabled. 927 if testFuzz != "" { 928 // Don't instrument packages which may affect coverage guidance but are 929 // unlikely to be useful. Most of these are used by the testing or 930 // internal/fuzz packages concurrently with fuzzing. 931 var skipInstrumentation = map[string]bool{ 932 "context": true, 933 "internal/fuzz": true, 934 "reflect": true, 935 "runtime": true, 936 "sync": true, 937 "sync/atomic": true, 938 "syscall": true, 939 "testing": true, 940 "time": true, 941 } 942 for _, p := range load.TestPackageList(ctx, pkgOpts, pkgs) { 943 if !skipInstrumentation[p.ImportPath] { 944 p.Internal.FuzzInstrument = true 945 } 946 } 947 } 948 949 // Collect all the packages imported by the packages being tested. 950 allImports := make(map[*load.Package]bool) 951 for _, p := range pkgs { 952 if p.Error != nil && p.Error.IsImportCycle { 953 continue 954 } 955 for _, p1 := range p.Internal.Imports { 956 allImports[p1] = true 957 } 958 } 959 960 if cfg.BuildCover { 961 for _, p := range pkgs { 962 // sync/atomic import is inserted by the cover tool if 963 // we're using atomic mode (and not compiling 964 // sync/atomic package itself). See #18486 and #57445. 965 // Note that this needs to be done prior to any of the 966 // builderTest invocations below, due to the fact that 967 // a given package in the 'pkgs' list may import 968 // package Q which appears later in the list (if this 969 // happens we'll wind up building the Q compile action 970 // before updating its deps to include sync/atomic). 971 if cfg.BuildCoverMode == "atomic" && p.ImportPath != "sync/atomic" { 972 load.EnsureImport(p, "sync/atomic") 973 } 974 // Tag the package for static meta-data generation if no 975 // test files (this works only with the new coverage 976 // design). Do this here (as opposed to in builderTest) so 977 // as to handle the case where we're testing multiple 978 // packages and one of the earlier packages imports a 979 // later package. Note that if -coverpkg is in effect 980 // p.Internal.Cover.GenMeta will wind up being set for 981 // all matching packages. 982 if len(p.TestGoFiles)+len(p.XTestGoFiles) == 0 && 983 cfg.BuildCoverPkg == nil && 984 cfg.Experiment.CoverageRedesign { 985 p.Internal.Cover.GenMeta = true 986 } 987 } 988 } 989 990 // Prepare build + run + print actions for all packages being tested. 991 for _, p := range pkgs { 992 buildTest, runTest, printTest, err := builderTest(b, ctx, pkgOpts, p, allImports[p], writeCoverMetaAct) 993 if err != nil { 994 str := err.Error() 995 str = strings.TrimPrefix(str, "\n") 996 if p.ImportPath != "" { 997 base.Errorf("# %s\n%s", p.ImportPath, str) 998 } else { 999 base.Errorf("%s", str) 1000 } 1001 fmt.Printf("FAIL\t%s [setup failed]\n", p.ImportPath) 1002 continue 1003 } 1004 builds = append(builds, buildTest) 1005 runs = append(runs, runTest) 1006 prints = append(prints, printTest) 1007 } 1008 1009 // Order runs for coordinating start JSON prints. 1010 ch := make(chan struct{}) 1011 close(ch) 1012 for _, a := range runs { 1013 if r, ok := a.Actor.(*runTestActor); ok { 1014 r.prev = ch 1015 ch = make(chan struct{}) 1016 r.next = ch 1017 } 1018 } 1019 1020 // Ultimately the goal is to print the output. 1021 root := &work.Action{Mode: "go test", Actor: work.ActorFunc(printExitStatus), Deps: prints} 1022 1023 // Force the printing of results to happen in order, 1024 // one at a time. 1025 for i, a := range prints { 1026 if i > 0 { 1027 a.Deps = append(a.Deps, prints[i-1]) 1028 } 1029 } 1030 1031 // Force benchmarks to run in serial. 1032 if !testC && (testBench != "") { 1033 // The first run must wait for all builds. 1034 // Later runs must wait for the previous run's print. 1035 for i, run := range runs { 1036 if i == 0 { 1037 run.Deps = append(run.Deps, builds...) 1038 } else { 1039 run.Deps = append(run.Deps, prints[i-1]) 1040 } 1041 } 1042 } 1043 1044 b.Do(ctx, root) 1045} 1046 1047var windowsBadWords = []string{ 1048 "install", 1049 "patch", 1050 "setup", 1051 "update", 1052} 1053 1054func builderTest(b *work.Builder, ctx context.Context, pkgOpts load.PackageOpts, p *load.Package, imported bool, writeCoverMetaAct *work.Action) (buildAction, runAction, printAction *work.Action, err error) { 1055 if len(p.TestGoFiles)+len(p.XTestGoFiles) == 0 { 1056 if cfg.BuildCover && cfg.Experiment.CoverageRedesign { 1057 if p.Internal.Cover.GenMeta { 1058 p.Internal.Cover.Mode = cfg.BuildCoverMode 1059 } 1060 } 1061 build := b.CompileAction(work.ModeBuild, work.ModeBuild, p) 1062 run := &work.Action{ 1063 Mode: "test run", 1064 Actor: new(runTestActor), 1065 Deps: []*work.Action{build}, 1066 Objdir: b.NewObjdir(), 1067 Package: p, 1068 IgnoreFail: true, // run (prepare output) even if build failed 1069 } 1070 if writeCoverMetaAct != nil && build.Actor != nil { 1071 // There is no real "run" for this package (since there 1072 // are no tests), but if coverage is turned on, we can 1073 // collect coverage data for the code in the package by 1074 // asking cmd/cover for a static meta-data file as part of 1075 // the package build. This static meta-data file is then 1076 // consumed by a pseudo-action (writeCoverMetaAct) that 1077 // adds it to a summary file, then this summary file is 1078 // consumed by the various "run test" actions. Below we 1079 // add a dependence edge between the build action and the 1080 // "write meta files" pseudo-action, and then another dep 1081 // from writeCoverMetaAct to the run action. See the 1082 // comment in runTest() at the definition of 1083 // writeCoverMetaAct for more details. 1084 run.Deps = append(run.Deps, writeCoverMetaAct) 1085 writeCoverMetaAct.Deps = append(writeCoverMetaAct.Deps, build) 1086 } 1087 addTestVet(b, p, run, nil) 1088 print := &work.Action{ 1089 Mode: "test print", 1090 Actor: work.ActorFunc(builderPrintTest), 1091 Deps: []*work.Action{run}, 1092 Package: p, 1093 IgnoreFail: true, // print even if test failed 1094 } 1095 return build, run, print, nil 1096 } 1097 1098 // Build Package structs describing: 1099 // pmain - pkg.test binary 1100 // ptest - package + test files 1101 // pxtest - package of external test files 1102 var cover *load.TestCover 1103 if cfg.BuildCover { 1104 cover = &load.TestCover{ 1105 Mode: cfg.BuildCoverMode, 1106 Local: cfg.BuildCoverPkg == nil, 1107 Pkgs: testCoverPkgs, 1108 Paths: cfg.BuildCoverPkg, 1109 } 1110 } 1111 pmain, ptest, pxtest, err := load.TestPackagesFor(ctx, pkgOpts, p, cover) 1112 if err != nil { 1113 return nil, nil, nil, err 1114 } 1115 1116 // If imported is true then this package is imported by some 1117 // package being tested. Make building the test version of the 1118 // package depend on building the non-test version, so that we 1119 // only report build errors once. Issue #44624. 1120 if imported && ptest != p { 1121 buildTest := b.CompileAction(work.ModeBuild, work.ModeBuild, ptest) 1122 buildP := b.CompileAction(work.ModeBuild, work.ModeBuild, p) 1123 buildTest.Deps = append(buildTest.Deps, buildP) 1124 } 1125 1126 testBinary := testBinaryName(p) 1127 1128 testDir := b.NewObjdir() 1129 if err := b.BackgroundShell().Mkdir(testDir); err != nil { 1130 return nil, nil, nil, err 1131 } 1132 1133 pmain.Dir = testDir 1134 pmain.Internal.OmitDebug = !testC && !testNeedBinary() 1135 if pmain.ImportPath == "runtime.test" { 1136 // The runtime package needs a symbolized binary for its tests. 1137 // See runtime/unsafepoint_test.go. 1138 pmain.Internal.OmitDebug = false 1139 } 1140 1141 if !cfg.BuildN { 1142 // writeTestmain writes _testmain.go, 1143 // using the test description gathered in t. 1144 if err := os.WriteFile(testDir+"_testmain.go", *pmain.Internal.TestmainGo, 0666); err != nil { 1145 return nil, nil, nil, err 1146 } 1147 } 1148 1149 // Set compile objdir to testDir we've already created, 1150 // so that the default file path stripping applies to _testmain.go. 1151 b.CompileAction(work.ModeBuild, work.ModeBuild, pmain).Objdir = testDir 1152 1153 a := b.LinkAction(work.ModeBuild, work.ModeBuild, pmain) 1154 a.Target = testDir + testBinary + cfg.ExeSuffix 1155 if cfg.Goos == "windows" { 1156 // There are many reserved words on Windows that, 1157 // if used in the name of an executable, cause Windows 1158 // to try to ask for extra permissions. 1159 // The word list includes setup, install, update, and patch, 1160 // but it does not appear to be defined anywhere. 1161 // We have run into this trying to run the 1162 // go.codereview/patch tests. 1163 // For package names containing those words, use test.test.exe 1164 // instead of pkgname.test.exe. 1165 // Note that this file name is only used in the Go command's 1166 // temporary directory. If the -c or other flags are 1167 // given, the code below will still use pkgname.test.exe. 1168 // There are two user-visible effects of this change. 1169 // First, you can actually run 'go test' in directories that 1170 // have names that Windows thinks are installer-like, 1171 // without getting a dialog box asking for more permissions. 1172 // Second, in the Windows process listing during go test, 1173 // the test shows up as test.test.exe, not pkgname.test.exe. 1174 // That second one is a drawback, but it seems a small 1175 // price to pay for the test running at all. 1176 // If maintaining the list of bad words is too onerous, 1177 // we could just do this always on Windows. 1178 for _, bad := range windowsBadWords { 1179 if strings.Contains(testBinary, bad) { 1180 a.Target = testDir + "test.test" + cfg.ExeSuffix 1181 break 1182 } 1183 } 1184 } 1185 buildAction = a 1186 var installAction, cleanAction *work.Action 1187 if testC || testNeedBinary() { 1188 // -c or profiling flag: create action to copy binary to ./test.out. 1189 target := filepath.Join(base.Cwd(), testBinary+cfg.ExeSuffix) 1190 isNull := false 1191 1192 if testO != "" { 1193 target = testO 1194 1195 if testODir { 1196 if filepath.IsAbs(target) { 1197 target = filepath.Join(target, testBinary+cfg.ExeSuffix) 1198 } else { 1199 target = filepath.Join(base.Cwd(), target, testBinary+cfg.ExeSuffix) 1200 } 1201 } else { 1202 if base.IsNull(target) { 1203 isNull = true 1204 } else if !filepath.IsAbs(target) { 1205 target = filepath.Join(base.Cwd(), target) 1206 } 1207 } 1208 } 1209 1210 if isNull { 1211 runAction = buildAction 1212 } else { 1213 pmain.Target = target 1214 installAction = &work.Action{ 1215 Mode: "test build", 1216 Actor: work.ActorFunc(work.BuildInstallFunc), 1217 Deps: []*work.Action{buildAction}, 1218 Package: pmain, 1219 Target: target, 1220 } 1221 runAction = installAction // make sure runAction != nil even if not running test 1222 } 1223 } 1224 1225 var vetRunAction *work.Action 1226 if testC { 1227 printAction = &work.Action{Mode: "test print (nop)", Package: p, Deps: []*work.Action{runAction}} // nop 1228 vetRunAction = printAction 1229 } else { 1230 // run test 1231 rta := &runTestActor{ 1232 writeCoverMetaAct: writeCoverMetaAct, 1233 } 1234 runAction = &work.Action{ 1235 Mode: "test run", 1236 Actor: rta, 1237 Deps: []*work.Action{buildAction}, 1238 Package: p, 1239 IgnoreFail: true, // run (prepare output) even if build failed 1240 TryCache: rta.c.tryCache, 1241 } 1242 if writeCoverMetaAct != nil { 1243 // If writeCoverMetaAct != nil, this indicates that our 1244 // "go test -coverpkg" run actions will need to read the 1245 // meta-files summary file written by writeCoverMetaAct, 1246 // so add a dependence edge from writeCoverMetaAct to the 1247 // run action. 1248 runAction.Deps = append(runAction.Deps, writeCoverMetaAct) 1249 if !p.IsTestOnly() { 1250 // Package p is not test only, meaning that the build 1251 // action for p may generate a static meta-data file. 1252 // Add a dependence edge from p to writeCoverMetaAct, 1253 // which needs to know the name of that meta-data 1254 // file. 1255 compileAction := b.CompileAction(work.ModeBuild, work.ModeBuild, p) 1256 writeCoverMetaAct.Deps = append(writeCoverMetaAct.Deps, compileAction) 1257 } 1258 } 1259 runAction.Objdir = testDir 1260 vetRunAction = runAction 1261 cleanAction = &work.Action{ 1262 Mode: "test clean", 1263 Actor: work.ActorFunc(builderCleanTest), 1264 Deps: []*work.Action{runAction}, 1265 Package: p, 1266 IgnoreFail: true, // clean even if test failed 1267 Objdir: testDir, 1268 } 1269 printAction = &work.Action{ 1270 Mode: "test print", 1271 Actor: work.ActorFunc(builderPrintTest), 1272 Deps: []*work.Action{cleanAction}, 1273 Package: p, 1274 IgnoreFail: true, // print even if test failed 1275 } 1276 } 1277 1278 if len(ptest.GoFiles)+len(ptest.CgoFiles) > 0 { 1279 addTestVet(b, ptest, vetRunAction, installAction) 1280 } 1281 if pxtest != nil { 1282 addTestVet(b, pxtest, vetRunAction, installAction) 1283 } 1284 1285 if installAction != nil { 1286 if runAction != installAction { 1287 installAction.Deps = append(installAction.Deps, runAction) 1288 } 1289 if cleanAction != nil { 1290 cleanAction.Deps = append(cleanAction.Deps, installAction) 1291 } 1292 } 1293 1294 return buildAction, runAction, printAction, nil 1295} 1296 1297func addTestVet(b *work.Builder, p *load.Package, runAction, installAction *work.Action) { 1298 if testVet.off { 1299 return 1300 } 1301 1302 vet := b.VetAction(work.ModeBuild, work.ModeBuild, p) 1303 runAction.Deps = append(runAction.Deps, vet) 1304 // Install will clean the build directory. 1305 // Make sure vet runs first. 1306 // The install ordering in b.VetAction does not apply here 1307 // because we are using a custom installAction (created above). 1308 if installAction != nil { 1309 installAction.Deps = append(installAction.Deps, vet) 1310 } 1311} 1312 1313var noTestsToRun = []byte("\ntesting: warning: no tests to run\n") 1314var noFuzzTestsToFuzz = []byte("\ntesting: warning: no fuzz tests to fuzz\n") 1315var tooManyFuzzTestsToFuzz = []byte("\ntesting: warning: -fuzz matches more than one fuzz test, won't fuzz\n") 1316 1317// runTestActor is the actor for running a test. 1318type runTestActor struct { 1319 c runCache 1320 1321 // writeCoverMetaAct points to the pseudo-action for collecting 1322 // coverage meta-data files for selected -cover test runs. See the 1323 // comment in runTest at the definition of writeCoverMetaAct for 1324 // more details. 1325 writeCoverMetaAct *work.Action 1326 1327 // sequencing of json start messages, to preserve test order 1328 prev <-chan struct{} // wait to start until prev is closed 1329 next chan<- struct{} // close next once the next test can start. 1330} 1331 1332// runCache is the cache for running a single test. 1333type runCache struct { 1334 disableCache bool // cache should be disabled for this run 1335 1336 buf *bytes.Buffer 1337 id1 cache.ActionID 1338 id2 cache.ActionID 1339} 1340 1341// stdoutMu and lockedStdout provide a locked standard output 1342// that guarantees never to interlace writes from multiple 1343// goroutines, so that we can have multiple JSON streams writing 1344// to a lockedStdout simultaneously and know that events will 1345// still be intelligible. 1346var stdoutMu sync.Mutex 1347 1348type lockedStdout struct{} 1349 1350func (lockedStdout) Write(b []byte) (int, error) { 1351 stdoutMu.Lock() 1352 defer stdoutMu.Unlock() 1353 return os.Stdout.Write(b) 1354} 1355 1356func (r *runTestActor) Act(b *work.Builder, ctx context.Context, a *work.Action) error { 1357 sh := b.Shell(a) 1358 1359 // Wait for previous test to get started and print its first json line. 1360 select { 1361 case <-r.prev: 1362 // If should fail fast then release next test and exit. 1363 if testShouldFailFast.Load() { 1364 close(r.next) 1365 return nil 1366 } 1367 case <-base.Interrupted: 1368 // We can't wait for the previous test action to complete: we don't start 1369 // new actions after an interrupt, so if that action wasn't already running 1370 // it might never happen. Instead, just don't log anything for this action. 1371 base.SetExitStatus(1) 1372 return nil 1373 } 1374 1375 var stdout io.Writer = os.Stdout 1376 var err error 1377 if testJSON { 1378 json := test2json.NewConverter(lockedStdout{}, a.Package.ImportPath, test2json.Timestamp) 1379 defer func() { 1380 json.Exited(err) 1381 json.Close() 1382 }() 1383 stdout = json 1384 } 1385 1386 // Release next test to start (test2json.NewConverter writes the start event). 1387 close(r.next) 1388 1389 if a.Failed { 1390 // We were unable to build the binary. 1391 a.Failed = false 1392 fmt.Fprintf(stdout, "FAIL\t%s [build failed]\n", a.Package.ImportPath) 1393 // Tell the JSON converter that this was a failure, not a passing run. 1394 err = errors.New("build failed") 1395 base.SetExitStatus(1) 1396 return nil 1397 } 1398 1399 coverProfTempFile := func(a *work.Action) string { 1400 if a.Objdir == "" { 1401 panic("internal error: objdir not set in coverProfTempFile") 1402 } 1403 return a.Objdir + "_cover_.out" 1404 } 1405 1406 if p := a.Package; len(p.TestGoFiles)+len(p.XTestGoFiles) == 0 { 1407 reportNoTestFiles := true 1408 if cfg.BuildCover && cfg.Experiment.CoverageRedesign && p.Internal.Cover.GenMeta { 1409 if err := sh.Mkdir(a.Objdir); err != nil { 1410 return err 1411 } 1412 mf, err := work.BuildActionCoverMetaFile(a) 1413 if err != nil { 1414 return err 1415 } else if mf != "" { 1416 reportNoTestFiles = false 1417 // Write out "percent statements covered". 1418 if err := work.WriteCoveragePercent(b, a, mf, stdout); err != nil { 1419 return err 1420 } 1421 // If -coverprofile is in effect, then generate a 1422 // coverage profile fragment for this package and 1423 // merge it with the final -coverprofile output file. 1424 if coverMerge.f != nil { 1425 cp := coverProfTempFile(a) 1426 if err := work.WriteCoverageProfile(b, a, mf, cp, stdout); err != nil { 1427 return err 1428 } 1429 mergeCoverProfile(stdout, cp) 1430 } 1431 } 1432 } 1433 if reportNoTestFiles { 1434 fmt.Fprintf(stdout, "? \t%s\t[no test files]\n", p.ImportPath) 1435 } 1436 return nil 1437 } 1438 1439 var buf bytes.Buffer 1440 if len(pkgArgs) == 0 || testBench != "" || testFuzz != "" { 1441 // Stream test output (no buffering) when no package has 1442 // been given on the command line (implicit current directory) 1443 // or when benchmarking or fuzzing. 1444 // No change to stdout. 1445 } else { 1446 // If we're only running a single package under test or if parallelism is 1447 // set to 1, and if we're displaying all output (testShowPass), we can 1448 // hurry the output along, echoing it as soon as it comes in. 1449 // We still have to copy to &buf for caching the result. This special 1450 // case was introduced in Go 1.5 and is intentionally undocumented: 1451 // the exact details of output buffering are up to the go command and 1452 // subject to change. It would be nice to remove this special case 1453 // entirely, but it is surely very helpful to see progress being made 1454 // when tests are run on slow single-CPU ARM systems. 1455 // 1456 // If we're showing JSON output, then display output as soon as 1457 // possible even when multiple tests are being run: the JSON output 1458 // events are attributed to specific package tests, so interlacing them 1459 // is OK. 1460 if testShowPass() && (len(pkgs) == 1 || cfg.BuildP == 1) || testJSON { 1461 // Write both to stdout and buf, for possible saving 1462 // to cache, and for looking for the "no tests to run" message. 1463 stdout = io.MultiWriter(stdout, &buf) 1464 } else { 1465 stdout = &buf 1466 } 1467 } 1468 1469 if r.c.buf == nil { 1470 // We did not find a cached result using the link step action ID, 1471 // so we ran the link step. Try again now with the link output 1472 // content ID. The attempt using the action ID makes sure that 1473 // if the link inputs don't change, we reuse the cached test 1474 // result without even rerunning the linker. The attempt using 1475 // the link output (test binary) content ID makes sure that if 1476 // we have different link inputs but the same final binary, 1477 // we still reuse the cached test result. 1478 // c.saveOutput will store the result under both IDs. 1479 r.c.tryCacheWithID(b, a, a.Deps[0].BuildContentID()) 1480 } 1481 if r.c.buf != nil { 1482 if stdout != &buf { 1483 stdout.Write(r.c.buf.Bytes()) 1484 r.c.buf.Reset() 1485 } 1486 a.TestOutput = r.c.buf 1487 return nil 1488 } 1489 1490 execCmd := work.FindExecCmd() 1491 testlogArg := []string{} 1492 if !r.c.disableCache && len(execCmd) == 0 { 1493 testlogArg = []string{"-test.testlogfile=" + a.Objdir + "testlog.txt"} 1494 } 1495 panicArg := "-test.paniconexit0" 1496 fuzzArg := []string{} 1497 if testFuzz != "" { 1498 fuzzCacheDir := filepath.Join(cache.Default().FuzzDir(), a.Package.ImportPath) 1499 fuzzArg = []string{"-test.fuzzcachedir=" + fuzzCacheDir} 1500 } 1501 coverdirArg := []string{} 1502 addToEnv := "" 1503 if cfg.BuildCover { 1504 gcd := filepath.Join(a.Objdir, "gocoverdir") 1505 if err := sh.Mkdir(gcd); err != nil { 1506 // If we can't create a temp dir, terminate immediately 1507 // with an error as opposed to returning an error to the 1508 // caller; failed MkDir most likely indicates that we're 1509 // out of disk space or there is some other systemic error 1510 // that will make forward progress unlikely. 1511 base.Fatalf("failed to create temporary dir: %v", err) 1512 } 1513 coverdirArg = append(coverdirArg, "-test.gocoverdir="+gcd) 1514 if r.writeCoverMetaAct != nil { 1515 // Copy the meta-files file over into the test's coverdir 1516 // directory so that the coverage runtime support will be 1517 // able to find it. 1518 src := r.writeCoverMetaAct.Objdir + coverage.MetaFilesFileName 1519 dst := filepath.Join(gcd, coverage.MetaFilesFileName) 1520 if err := sh.CopyFile(dst, src, 0666, false); err != nil { 1521 return err 1522 } 1523 } 1524 // Even though we are passing the -test.gocoverdir option to 1525 // the test binary, also set GOCOVERDIR as well. This is 1526 // intended to help with tests that run "go build" to build 1527 // fresh copies of tools to test as part of the testing. 1528 addToEnv = "GOCOVERDIR=" + gcd 1529 } 1530 args := str.StringList(execCmd, a.Deps[0].BuiltTarget(), testlogArg, panicArg, fuzzArg, coverdirArg, testArgs) 1531 1532 if testCoverProfile != "" { 1533 // Write coverage to temporary profile, for merging later. 1534 for i, arg := range args { 1535 if strings.HasPrefix(arg, "-test.coverprofile=") { 1536 args[i] = "-test.coverprofile=" + coverProfTempFile(a) 1537 } 1538 } 1539 } 1540 1541 if cfg.BuildN || cfg.BuildX { 1542 sh.ShowCmd("", "%s", strings.Join(args, " ")) 1543 if cfg.BuildN { 1544 return nil 1545 } 1546 } 1547 1548 // Normally, the test will terminate itself when the timeout expires, 1549 // but add a last-ditch deadline to detect and stop wedged binaries. 1550 ctx, cancel := context.WithTimeout(ctx, testKillTimeout) 1551 defer cancel() 1552 1553 // Now we're ready to actually run the command. 1554 // 1555 // If the -o flag is set, or if at some point we change cmd/go to start 1556 // copying test executables into the build cache, we may run into spurious 1557 // ETXTBSY errors on Unix platforms (see https://go.dev/issue/22315). 1558 // 1559 // Since we know what causes those, and we know that they should resolve 1560 // quickly (the ETXTBSY error will resolve as soon as the subprocess 1561 // holding the descriptor open reaches its 'exec' call), we retry them 1562 // in a loop. 1563 1564 var ( 1565 cmd *exec.Cmd 1566 t0 time.Time 1567 cancelKilled = false 1568 cancelSignaled = false 1569 ) 1570 for { 1571 cmd = exec.CommandContext(ctx, args[0], args[1:]...) 1572 cmd.Dir = a.Package.Dir 1573 1574 env := slices.Clip(cfg.OrigEnv) 1575 env = base.AppendPATH(env) 1576 env = base.AppendPWD(env, cmd.Dir) 1577 cmd.Env = env 1578 if addToEnv != "" { 1579 cmd.Env = append(cmd.Env, addToEnv) 1580 } 1581 1582 cmd.Stdout = stdout 1583 cmd.Stderr = stdout 1584 1585 cmd.Cancel = func() error { 1586 if base.SignalTrace == nil { 1587 err := cmd.Process.Kill() 1588 if err == nil { 1589 cancelKilled = true 1590 } 1591 return err 1592 } 1593 1594 // Send a quit signal in the hope that the program will print 1595 // a stack trace and exit. 1596 err := cmd.Process.Signal(base.SignalTrace) 1597 if err == nil { 1598 cancelSignaled = true 1599 } 1600 return err 1601 } 1602 cmd.WaitDelay = testWaitDelay 1603 1604 base.StartSigHandlers() 1605 t0 = time.Now() 1606 err = cmd.Run() 1607 1608 if !isETXTBSY(err) { 1609 // We didn't hit the race in #22315, so there is no reason to retry the 1610 // command. 1611 break 1612 } 1613 } 1614 1615 out := buf.Bytes() 1616 a.TestOutput = &buf 1617 t := fmt.Sprintf("%.3fs", time.Since(t0).Seconds()) 1618 1619 mergeCoverProfile(cmd.Stdout, a.Objdir+"_cover_.out") 1620 1621 if err == nil { 1622 norun := "" 1623 if !testShowPass() && !testJSON { 1624 buf.Reset() 1625 } 1626 if bytes.HasPrefix(out, noTestsToRun[1:]) || bytes.Contains(out, noTestsToRun) { 1627 norun = " [no tests to run]" 1628 } 1629 if bytes.HasPrefix(out, noFuzzTestsToFuzz[1:]) || bytes.Contains(out, noFuzzTestsToFuzz) { 1630 norun = " [no fuzz tests to fuzz]" 1631 } 1632 if bytes.HasPrefix(out, tooManyFuzzTestsToFuzz[1:]) || bytes.Contains(out, tooManyFuzzTestsToFuzz) { 1633 norun = "[-fuzz matches more than one fuzz test, won't fuzz]" 1634 } 1635 if len(out) > 0 && !bytes.HasSuffix(out, []byte("\n")) { 1636 // Ensure that the output ends with a newline before the "ok" 1637 // line we're about to print (https://golang.org/issue/49317). 1638 cmd.Stdout.Write([]byte("\n")) 1639 } 1640 fmt.Fprintf(cmd.Stdout, "ok \t%s\t%s%s%s\n", a.Package.ImportPath, t, coveragePercentage(out), norun) 1641 r.c.saveOutput(a) 1642 } else { 1643 if testFailFast { 1644 testShouldFailFast.Store(true) 1645 } 1646 1647 base.SetExitStatus(1) 1648 if cancelSignaled { 1649 fmt.Fprintf(cmd.Stdout, "*** Test killed with %v: ran too long (%v).\n", base.SignalTrace, testKillTimeout) 1650 } else if cancelKilled { 1651 fmt.Fprintf(cmd.Stdout, "*** Test killed: ran too long (%v).\n", testKillTimeout) 1652 } else if errors.Is(err, exec.ErrWaitDelay) { 1653 fmt.Fprintf(cmd.Stdout, "*** Test I/O incomplete %v after exiting.\n", cmd.WaitDelay) 1654 } 1655 var ee *exec.ExitError 1656 if len(out) == 0 || !errors.As(err, &ee) || !ee.Exited() { 1657 // If there was no test output, print the exit status so that the reason 1658 // for failure is clear. 1659 fmt.Fprintf(cmd.Stdout, "%s\n", err) 1660 } else if !bytes.HasSuffix(out, []byte("\n")) { 1661 // Otherwise, ensure that the output ends with a newline before the FAIL 1662 // line we're about to print (https://golang.org/issue/49317). 1663 cmd.Stdout.Write([]byte("\n")) 1664 } 1665 1666 // NOTE(golang.org/issue/37555): test2json reports that a test passes 1667 // unless "FAIL" is printed at the beginning of a line. The test may not 1668 // actually print that if it panics, exits, or terminates abnormally, 1669 // so we print it here. We can't always check whether it was printed 1670 // because some tests need stdout to be a terminal (golang.org/issue/34791), 1671 // not a pipe. 1672 // TODO(golang.org/issue/29062): tests that exit with status 0 without 1673 // printing a final result should fail. 1674 prefix := "" 1675 if testJSON || testV.json { 1676 prefix = "\x16" 1677 } 1678 fmt.Fprintf(cmd.Stdout, "%sFAIL\t%s\t%s\n", prefix, a.Package.ImportPath, t) 1679 } 1680 1681 if cmd.Stdout != &buf { 1682 buf.Reset() // cmd.Stdout was going to os.Stdout already 1683 } 1684 return nil 1685} 1686 1687// tryCache is called just before the link attempt, 1688// to see if the test result is cached and therefore the link is unneeded. 1689// It reports whether the result can be satisfied from cache. 1690func (c *runCache) tryCache(b *work.Builder, a *work.Action) bool { 1691 return c.tryCacheWithID(b, a, a.Deps[0].BuildActionID()) 1692} 1693 1694func (c *runCache) tryCacheWithID(b *work.Builder, a *work.Action, id string) bool { 1695 if len(pkgArgs) == 0 { 1696 // Caching does not apply to "go test", 1697 // only to "go test foo" (including "go test ."). 1698 if cache.DebugTest { 1699 fmt.Fprintf(os.Stderr, "testcache: caching disabled in local directory mode\n") 1700 } 1701 c.disableCache = true 1702 return false 1703 } 1704 1705 if a.Package.Root == "" { 1706 // Caching does not apply to tests outside of any module, GOPATH, or GOROOT. 1707 if cache.DebugTest { 1708 fmt.Fprintf(os.Stderr, "testcache: caching disabled for package outside of module root, GOPATH, or GOROOT: %s\n", a.Package.ImportPath) 1709 } 1710 c.disableCache = true 1711 return false 1712 } 1713 1714 var cacheArgs []string 1715 for _, arg := range testArgs { 1716 i := strings.Index(arg, "=") 1717 if i < 0 || !strings.HasPrefix(arg, "-test.") { 1718 if cache.DebugTest { 1719 fmt.Fprintf(os.Stderr, "testcache: caching disabled for test argument: %s\n", arg) 1720 } 1721 c.disableCache = true 1722 return false 1723 } 1724 switch arg[:i] { 1725 case "-test.benchtime", 1726 "-test.cpu", 1727 "-test.list", 1728 "-test.parallel", 1729 "-test.run", 1730 "-test.short", 1731 "-test.timeout", 1732 "-test.failfast", 1733 "-test.v", 1734 "-test.fullpath": 1735 // These are cacheable. 1736 // Note that this list is documented above, 1737 // so if you add to this list, update the docs too. 1738 cacheArgs = append(cacheArgs, arg) 1739 1740 default: 1741 // nothing else is cacheable 1742 if cache.DebugTest { 1743 fmt.Fprintf(os.Stderr, "testcache: caching disabled for test argument: %s\n", arg) 1744 } 1745 c.disableCache = true 1746 return false 1747 } 1748 } 1749 1750 // The test cache result fetch is a two-level lookup. 1751 // 1752 // First, we use the content hash of the test binary 1753 // and its command-line arguments to find the 1754 // list of environment variables and files consulted 1755 // the last time the test was run with those arguments. 1756 // (To avoid unnecessary links, we store this entry 1757 // under two hashes: id1 uses the linker inputs as a 1758 // proxy for the test binary, and id2 uses the actual 1759 // test binary. If the linker inputs are unchanged, 1760 // this way we avoid the link step, even though we 1761 // do not cache link outputs.) 1762 // 1763 // Second, we compute a hash of the values of the 1764 // environment variables and the content of the files 1765 // listed in the log from the previous run. 1766 // Then we look up test output using a combination of 1767 // the hash from the first part (testID) and the hash of the 1768 // test inputs (testInputsID). 1769 // 1770 // In order to store a new test result, we must redo the 1771 // testInputsID computation using the log from the run 1772 // we want to cache, and then we store that new log and 1773 // the new outputs. 1774 1775 h := cache.NewHash("testResult") 1776 fmt.Fprintf(h, "test binary %s args %q execcmd %q", id, cacheArgs, work.ExecCmd) 1777 testID := h.Sum() 1778 if c.id1 == (cache.ActionID{}) { 1779 c.id1 = testID 1780 } else { 1781 c.id2 = testID 1782 } 1783 if cache.DebugTest { 1784 fmt.Fprintf(os.Stderr, "testcache: %s: test ID %x => %x\n", a.Package.ImportPath, id, testID) 1785 } 1786 1787 // Load list of referenced environment variables and files 1788 // from last run of testID, and compute hash of that content. 1789 data, entry, err := cache.GetBytes(cache.Default(), testID) 1790 if !bytes.HasPrefix(data, testlogMagic) || data[len(data)-1] != '\n' { 1791 if cache.DebugTest { 1792 if err != nil { 1793 fmt.Fprintf(os.Stderr, "testcache: %s: input list not found: %v\n", a.Package.ImportPath, err) 1794 } else { 1795 fmt.Fprintf(os.Stderr, "testcache: %s: input list malformed\n", a.Package.ImportPath) 1796 } 1797 } 1798 return false 1799 } 1800 testInputsID, err := computeTestInputsID(a, data) 1801 if err != nil { 1802 return false 1803 } 1804 if cache.DebugTest { 1805 fmt.Fprintf(os.Stderr, "testcache: %s: test ID %x => input ID %x => %x\n", a.Package.ImportPath, testID, testInputsID, testAndInputKey(testID, testInputsID)) 1806 } 1807 1808 // Parse cached result in preparation for changing run time to "(cached)". 1809 // If we can't parse the cached result, don't use it. 1810 data, entry, err = cache.GetBytes(cache.Default(), testAndInputKey(testID, testInputsID)) 1811 if len(data) == 0 || data[len(data)-1] != '\n' { 1812 if cache.DebugTest { 1813 if err != nil { 1814 fmt.Fprintf(os.Stderr, "testcache: %s: test output not found: %v\n", a.Package.ImportPath, err) 1815 } else { 1816 fmt.Fprintf(os.Stderr, "testcache: %s: test output malformed\n", a.Package.ImportPath) 1817 } 1818 } 1819 return false 1820 } 1821 if entry.Time.Before(testCacheExpire) { 1822 if cache.DebugTest { 1823 fmt.Fprintf(os.Stderr, "testcache: %s: test output expired due to go clean -testcache\n", a.Package.ImportPath) 1824 } 1825 return false 1826 } 1827 i := bytes.LastIndexByte(data[:len(data)-1], '\n') + 1 1828 if !bytes.HasPrefix(data[i:], []byte("ok \t")) { 1829 if cache.DebugTest { 1830 fmt.Fprintf(os.Stderr, "testcache: %s: test output malformed\n", a.Package.ImportPath) 1831 } 1832 return false 1833 } 1834 j := bytes.IndexByte(data[i+len("ok \t"):], '\t') 1835 if j < 0 { 1836 if cache.DebugTest { 1837 fmt.Fprintf(os.Stderr, "testcache: %s: test output malformed\n", a.Package.ImportPath) 1838 } 1839 return false 1840 } 1841 j += i + len("ok \t") + 1 1842 1843 // Committed to printing. 1844 c.buf = new(bytes.Buffer) 1845 c.buf.Write(data[:j]) 1846 c.buf.WriteString("(cached)") 1847 for j < len(data) && ('0' <= data[j] && data[j] <= '9' || data[j] == '.' || data[j] == 's') { 1848 j++ 1849 } 1850 c.buf.Write(data[j:]) 1851 return true 1852} 1853 1854var errBadTestInputs = errors.New("error parsing test inputs") 1855var testlogMagic = []byte("# test log\n") // known to testing/internal/testdeps/deps.go 1856 1857// computeTestInputsID computes the "test inputs ID" 1858// (see comment in tryCacheWithID above) for the 1859// test log. 1860func computeTestInputsID(a *work.Action, testlog []byte) (cache.ActionID, error) { 1861 testlog = bytes.TrimPrefix(testlog, testlogMagic) 1862 h := cache.NewHash("testInputs") 1863 // The runtime always looks at GODEBUG, without telling us in the testlog. 1864 fmt.Fprintf(h, "env GODEBUG %x\n", hashGetenv("GODEBUG")) 1865 pwd := a.Package.Dir 1866 for _, line := range bytes.Split(testlog, []byte("\n")) { 1867 if len(line) == 0 { 1868 continue 1869 } 1870 s := string(line) 1871 op, name, found := strings.Cut(s, " ") 1872 if !found { 1873 if cache.DebugTest { 1874 fmt.Fprintf(os.Stderr, "testcache: %s: input list malformed (%q)\n", a.Package.ImportPath, line) 1875 } 1876 return cache.ActionID{}, errBadTestInputs 1877 } 1878 switch op { 1879 default: 1880 if cache.DebugTest { 1881 fmt.Fprintf(os.Stderr, "testcache: %s: input list malformed (%q)\n", a.Package.ImportPath, line) 1882 } 1883 return cache.ActionID{}, errBadTestInputs 1884 case "getenv": 1885 fmt.Fprintf(h, "env %s %x\n", name, hashGetenv(name)) 1886 case "chdir": 1887 pwd = name // always absolute 1888 fmt.Fprintf(h, "chdir %s %x\n", name, hashStat(name)) 1889 case "stat": 1890 if !filepath.IsAbs(name) { 1891 name = filepath.Join(pwd, name) 1892 } 1893 if a.Package.Root == "" || search.InDir(name, a.Package.Root) == "" { 1894 // Do not recheck files outside the module, GOPATH, or GOROOT root. 1895 break 1896 } 1897 fmt.Fprintf(h, "stat %s %x\n", name, hashStat(name)) 1898 case "open": 1899 if !filepath.IsAbs(name) { 1900 name = filepath.Join(pwd, name) 1901 } 1902 if a.Package.Root == "" || search.InDir(name, a.Package.Root) == "" { 1903 // Do not recheck files outside the module, GOPATH, or GOROOT root. 1904 break 1905 } 1906 fh, err := hashOpen(name) 1907 if err != nil { 1908 if cache.DebugTest { 1909 fmt.Fprintf(os.Stderr, "testcache: %s: input file %s: %s\n", a.Package.ImportPath, name, err) 1910 } 1911 return cache.ActionID{}, err 1912 } 1913 fmt.Fprintf(h, "open %s %x\n", name, fh) 1914 } 1915 } 1916 sum := h.Sum() 1917 return sum, nil 1918} 1919 1920func hashGetenv(name string) cache.ActionID { 1921 h := cache.NewHash("getenv") 1922 v, ok := os.LookupEnv(name) 1923 if !ok { 1924 h.Write([]byte{0}) 1925 } else { 1926 h.Write([]byte{1}) 1927 h.Write([]byte(v)) 1928 } 1929 return h.Sum() 1930} 1931 1932const modTimeCutoff = 2 * time.Second 1933 1934var errFileTooNew = errors.New("file used as input is too new") 1935 1936func hashOpen(name string) (cache.ActionID, error) { 1937 h := cache.NewHash("open") 1938 info, err := os.Stat(name) 1939 if err != nil { 1940 fmt.Fprintf(h, "err %v\n", err) 1941 return h.Sum(), nil 1942 } 1943 hashWriteStat(h, info) 1944 if info.IsDir() { 1945 files, err := os.ReadDir(name) 1946 if err != nil { 1947 fmt.Fprintf(h, "err %v\n", err) 1948 } 1949 for _, f := range files { 1950 fmt.Fprintf(h, "file %s ", f.Name()) 1951 finfo, err := f.Info() 1952 if err != nil { 1953 fmt.Fprintf(h, "err %v\n", err) 1954 } else { 1955 hashWriteStat(h, finfo) 1956 } 1957 } 1958 } else if info.Mode().IsRegular() { 1959 // Because files might be very large, do not attempt 1960 // to hash the entirety of their content. Instead assume 1961 // the mtime and size recorded in hashWriteStat above 1962 // are good enough. 1963 // 1964 // To avoid problems for very recent files where a new 1965 // write might not change the mtime due to file system 1966 // mtime precision, reject caching if a file was read that 1967 // is less than modTimeCutoff old. 1968 if time.Since(info.ModTime()) < modTimeCutoff { 1969 return cache.ActionID{}, errFileTooNew 1970 } 1971 } 1972 return h.Sum(), nil 1973} 1974 1975func hashStat(name string) cache.ActionID { 1976 h := cache.NewHash("stat") 1977 if info, err := os.Stat(name); err != nil { 1978 fmt.Fprintf(h, "err %v\n", err) 1979 } else { 1980 hashWriteStat(h, info) 1981 } 1982 if info, err := os.Lstat(name); err != nil { 1983 fmt.Fprintf(h, "err %v\n", err) 1984 } else { 1985 hashWriteStat(h, info) 1986 } 1987 return h.Sum() 1988} 1989 1990func hashWriteStat(h io.Writer, info fs.FileInfo) { 1991 fmt.Fprintf(h, "stat %d %x %v %v\n", info.Size(), uint64(info.Mode()), info.ModTime(), info.IsDir()) 1992} 1993 1994// testAndInputKey returns the actual cache key for the pair (testID, testInputsID). 1995func testAndInputKey(testID, testInputsID cache.ActionID) cache.ActionID { 1996 return cache.Subkey(testID, fmt.Sprintf("inputs:%x", testInputsID)) 1997} 1998 1999func (c *runCache) saveOutput(a *work.Action) { 2000 if c.id1 == (cache.ActionID{}) && c.id2 == (cache.ActionID{}) { 2001 return 2002 } 2003 2004 // See comment about two-level lookup in tryCacheWithID above. 2005 testlog, err := os.ReadFile(a.Objdir + "testlog.txt") 2006 if err != nil || !bytes.HasPrefix(testlog, testlogMagic) || testlog[len(testlog)-1] != '\n' { 2007 if cache.DebugTest { 2008 if err != nil { 2009 fmt.Fprintf(os.Stderr, "testcache: %s: reading testlog: %v\n", a.Package.ImportPath, err) 2010 } else { 2011 fmt.Fprintf(os.Stderr, "testcache: %s: reading testlog: malformed\n", a.Package.ImportPath) 2012 } 2013 } 2014 return 2015 } 2016 testInputsID, err := computeTestInputsID(a, testlog) 2017 if err != nil { 2018 return 2019 } 2020 if c.id1 != (cache.ActionID{}) { 2021 if cache.DebugTest { 2022 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)) 2023 } 2024 cache.PutNoVerify(cache.Default(), c.id1, bytes.NewReader(testlog)) 2025 cache.PutNoVerify(cache.Default(), testAndInputKey(c.id1, testInputsID), bytes.NewReader(a.TestOutput.Bytes())) 2026 } 2027 if c.id2 != (cache.ActionID{}) { 2028 if cache.DebugTest { 2029 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)) 2030 } 2031 cache.PutNoVerify(cache.Default(), c.id2, bytes.NewReader(testlog)) 2032 cache.PutNoVerify(cache.Default(), testAndInputKey(c.id2, testInputsID), bytes.NewReader(a.TestOutput.Bytes())) 2033 } 2034} 2035 2036// coveragePercentage returns the coverage results (if enabled) for the 2037// test. It uncovers the data by scanning the output from the test run. 2038func coveragePercentage(out []byte) string { 2039 if !cfg.BuildCover { 2040 return "" 2041 } 2042 // The string looks like 2043 // test coverage for encoding/binary: 79.9% of statements 2044 // Extract the piece from the percentage to the end of the line. 2045 re := regexp.MustCompile(`coverage: (.*)\n`) 2046 matches := re.FindSubmatch(out) 2047 if matches == nil { 2048 // Probably running "go test -cover" not "go test -cover fmt". 2049 // The coverage output will appear in the output directly. 2050 return "" 2051 } 2052 return fmt.Sprintf("\tcoverage: %s", matches[1]) 2053} 2054 2055// builderCleanTest is the action for cleaning up after a test. 2056func builderCleanTest(b *work.Builder, ctx context.Context, a *work.Action) error { 2057 if cfg.BuildWork { 2058 return nil 2059 } 2060 b.Shell(a).RemoveAll(a.Objdir) 2061 return nil 2062} 2063 2064// builderPrintTest is the action for printing a test result. 2065func builderPrintTest(b *work.Builder, ctx context.Context, a *work.Action) error { 2066 clean := a.Deps[0] 2067 run := clean.Deps[0] 2068 if run.TestOutput != nil { 2069 os.Stdout.Write(run.TestOutput.Bytes()) 2070 run.TestOutput = nil 2071 } 2072 return nil 2073} 2074 2075// printExitStatus is the action for printing the final exit status. 2076// If we are running multiple test targets, print a final "FAIL" 2077// in case a failure in an early package has already scrolled 2078// off of the user's terminal. 2079// (See https://golang.org/issue/30507#issuecomment-470593235.) 2080// 2081// In JSON mode, we need to maintain valid JSON output and 2082// we assume that the test output is being parsed by a tool 2083// anyway, so the failure will not be missed and would be 2084// awkward to try to wedge into the JSON stream. 2085// 2086// In fuzz mode, we only allow a single package for now 2087// (see CL 350156 and https://golang.org/issue/46312), 2088// so there is no possibility of scrolling off and no need 2089// to print the final status. 2090func printExitStatus(b *work.Builder, ctx context.Context, a *work.Action) error { 2091 if !testJSON && testFuzz == "" && len(pkgArgs) != 0 { 2092 if base.GetExitStatus() != 0 { 2093 fmt.Println("FAIL") 2094 return nil 2095 } 2096 } 2097 return nil 2098} 2099 2100// testBinaryName can be used to create name for test binary executable. 2101// Use last element of import path, not package name. 2102// They differ when package name is "main". 2103// But if the import path is "command-line-arguments", 2104// like it is during 'go run', use the package name. 2105func testBinaryName(p *load.Package) string { 2106 var elem string 2107 if p.ImportPath == "command-line-arguments" { 2108 elem = p.Name 2109 } else { 2110 elem = p.DefaultExecName() 2111 } 2112 2113 return elem + ".test" 2114} 2115