github.com/zebozhuang/go@v0.0.0-20200207033046-f8a98f6f5c5d/src/cmd/go/internal/test/test.go (about) 1 // Copyright 2011 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package test 6 7 import ( 8 "bytes" 9 "errors" 10 "fmt" 11 "go/ast" 12 "go/build" 13 "go/doc" 14 "go/parser" 15 "go/token" 16 "os" 17 "os/exec" 18 "path" 19 "path/filepath" 20 "regexp" 21 "runtime" 22 "sort" 23 "strings" 24 "text/template" 25 "time" 26 "unicode" 27 "unicode/utf8" 28 29 "cmd/go/internal/base" 30 "cmd/go/internal/cfg" 31 "cmd/go/internal/load" 32 "cmd/go/internal/str" 33 "cmd/go/internal/work" 34 ) 35 36 // Break init loop. 37 func init() { 38 CmdTest.Run = runTest 39 } 40 41 const testUsage = "test [build/test flags] [packages] [build/test flags & test binary flags]" 42 43 var CmdTest = &base.Command{ 44 CustomFlags: true, 45 UsageLine: testUsage, 46 Short: "test packages", 47 Long: ` 48 'Go test' automates testing the packages named by the import paths. 49 It prints a summary of the test results in the format: 50 51 ok archive/tar 0.011s 52 FAIL archive/zip 0.022s 53 ok compress/gzip 0.033s 54 ... 55 56 followed by detailed output for each failed package. 57 58 'Go test' recompiles each package along with any files with names matching 59 the file pattern "*_test.go". 60 Files whose names begin with "_" (including "_test.go") or "." are ignored. 61 These additional files can contain test functions, benchmark functions, and 62 example functions. See 'go help testfunc' for more. 63 Each listed package causes the execution of a separate test binary. 64 65 Test files that declare a package with the suffix "_test" will be compiled as a 66 separate package, and then linked and run with the main test binary. 67 68 The go tool will ignore a directory named "testdata", making it available 69 to hold ancillary data needed by the tests. 70 71 By default, go test needs no arguments. It compiles and tests the package 72 with source in the current directory, including tests, and runs the tests. 73 74 The package is built in a temporary directory so it does not interfere with the 75 non-test installation. 76 77 ` + strings.TrimSpace(testFlag1) + ` See 'go help testflag' for details. 78 79 For more about build flags, see 'go help build'. 80 For more about specifying packages, see 'go help packages'. 81 82 See also: go build, go vet. 83 `, 84 } 85 86 const testFlag1 = ` 87 In addition to the build flags, the flags handled by 'go test' itself are: 88 89 -args 90 Pass the remainder of the command line (everything after -args) 91 to the test binary, uninterpreted and unchanged. 92 Because this flag consumes the remainder of the command line, 93 the package list (if present) must appear before this flag. 94 95 -c 96 Compile the test binary to pkg.test but do not run it 97 (where pkg is the last element of the package's import path). 98 The file name can be changed with the -o flag. 99 100 -exec xprog 101 Run the test binary using xprog. The behavior is the same as 102 in 'go run'. See 'go help run' for details. 103 104 -i 105 Install packages that are dependencies of the test. 106 Do not run the test. 107 108 -o file 109 Compile the test binary to the named file. 110 The test still runs (unless -c or -i is specified). 111 112 The test binary also accepts flags that control execution of the test; these 113 flags are also accessible by 'go test'. 114 ` 115 116 // Usage prints the usage message for 'go test -h' and exits. 117 func Usage() { 118 os.Stderr.WriteString(testUsage + "\n\n" + 119 strings.TrimSpace(testFlag1) + "\n\n\t" + 120 strings.TrimSpace(testFlag2) + "\n") 121 os.Exit(2) 122 } 123 124 var HelpTestflag = &base.Command{ 125 UsageLine: "testflag", 126 Short: "description of testing flags", 127 Long: ` 128 The 'go test' command takes both flags that apply to 'go test' itself 129 and flags that apply to the resulting test binary. 130 131 Several of the flags control profiling and write an execution profile 132 suitable for "go tool pprof"; run "go tool pprof -h" for more 133 information. The --alloc_space, --alloc_objects, and --show_bytes 134 options of pprof control how the information is presented. 135 136 The following flags are recognized by the 'go test' command and 137 control the execution of any test: 138 139 ` + strings.TrimSpace(testFlag2) + ` 140 `, 141 } 142 143 const testFlag2 = ` 144 -bench regexp 145 Run only those benchmarks matching a regular expression. 146 By default, no benchmarks are run. 147 To run all benchmarks, use '-bench .' or '-bench=.'. 148 The regular expression is split by unbracketed slash (/) 149 characters into a sequence of regular expressions, and each 150 part of a benchmark's identifier must match the corresponding 151 element in the sequence, if any. Possible parents of matches 152 are run with b.N=1 to identify sub-benchmarks. For example, 153 given -bench=X/Y, top-level benchmarks matching X are run 154 with b.N=1 to find any sub-benchmarks matching Y, which are 155 then run in full. 156 157 -benchtime t 158 Run enough iterations of each benchmark to take t, specified 159 as a time.Duration (for example, -benchtime 1h30s). 160 The default is 1 second (1s). 161 162 -count n 163 Run each test and benchmark n times (default 1). 164 If -cpu is set, run n times for each GOMAXPROCS value. 165 Examples are always run once. 166 167 -cover 168 Enable coverage analysis. 169 Note that because coverage works by annotating the source 170 code before compilation, compilation and test failures with 171 coverage enabled may report line numbers that don't correspond 172 to the original sources. 173 174 -covermode set,count,atomic 175 Set the mode for coverage analysis for the package[s] 176 being tested. The default is "set" unless -race is enabled, 177 in which case it is "atomic". 178 The values: 179 set: bool: does this statement run? 180 count: int: how many times does this statement run? 181 atomic: int: count, but correct in multithreaded tests; 182 significantly more expensive. 183 Sets -cover. 184 185 -coverpkg pkg1,pkg2,pkg3 186 Apply coverage analysis in each test to the given list of packages. 187 The default is for each test to analyze only the package being tested. 188 Packages are specified as import paths. 189 Sets -cover. 190 191 -cpu 1,2,4 192 Specify a list of GOMAXPROCS values for which the tests or 193 benchmarks should be executed. The default is the current value 194 of GOMAXPROCS. 195 196 -list regexp 197 List tests, benchmarks, or examples matching the regular expression. 198 No tests, benchmarks or examples will be run. This will only 199 list top-level tests. No subtest or subbenchmarks will be shown. 200 201 -parallel n 202 Allow parallel execution of test functions that call t.Parallel. 203 The value of this flag is the maximum number of tests to run 204 simultaneously; by default, it is set to the value of GOMAXPROCS. 205 Note that -parallel only applies within a single test binary. 206 The 'go test' command may run tests for different packages 207 in parallel as well, according to the setting of the -p flag 208 (see 'go help build'). 209 210 -run regexp 211 Run only those tests and examples matching the regular expression. 212 For tests, the regular expression is split by unbracketed slash (/) 213 characters into a sequence of regular expressions, and each part 214 of a test's identifier must match the corresponding element in 215 the sequence, if any. Note that possible parents of matches are 216 run too, so that -run=X/Y matches and runs and reports the result 217 of all tests matching X, even those without sub-tests matching Y, 218 because it must run them to look for those sub-tests. 219 220 -short 221 Tell long-running tests to shorten their run time. 222 It is off by default but set during all.bash so that installing 223 the Go tree can run a sanity check but not spend time running 224 exhaustive tests. 225 226 -timeout d 227 If a test binary runs longer than duration d, panic. 228 The default is 10 minutes (10m). 229 230 -v 231 Verbose output: log all tests as they are run. Also print all 232 text from Log and Logf calls even if the test succeeds. 233 234 The following flags are also recognized by 'go test' and can be used to 235 profile the tests during execution: 236 237 -benchmem 238 Print memory allocation statistics for benchmarks. 239 240 -blockprofile block.out 241 Write a goroutine blocking profile to the specified file 242 when all tests are complete. 243 Writes test binary as -c would. 244 245 -blockprofilerate n 246 Control the detail provided in goroutine blocking profiles by 247 calling runtime.SetBlockProfileRate with n. 248 See 'go doc runtime.SetBlockProfileRate'. 249 The profiler aims to sample, on average, one blocking event every 250 n nanoseconds the program spends blocked. By default, 251 if -test.blockprofile is set without this flag, all blocking events 252 are recorded, equivalent to -test.blockprofilerate=1. 253 254 -coverprofile cover.out 255 Write a coverage profile to the file after all tests have passed. 256 Sets -cover. 257 258 -cpuprofile cpu.out 259 Write a CPU profile to the specified file before exiting. 260 Writes test binary as -c would. 261 262 -memprofile mem.out 263 Write a memory profile to the file after all tests have passed. 264 Writes test binary as -c would. 265 266 -memprofilerate n 267 Enable more precise (and expensive) memory profiles by setting 268 runtime.MemProfileRate. See 'go doc runtime.MemProfileRate'. 269 To profile all memory allocations, use -test.memprofilerate=1 270 and pass --alloc_space flag to the pprof tool. 271 272 -mutexprofile mutex.out 273 Write a mutex contention profile to the specified file 274 when all tests are complete. 275 Writes test binary as -c would. 276 277 -mutexprofilefraction n 278 Sample 1 in n stack traces of goroutines holding a 279 contended mutex. 280 281 -outputdir directory 282 Place output files from profiling in the specified directory, 283 by default the directory in which "go test" is running. 284 285 -trace trace.out 286 Write an execution trace to the specified file before exiting. 287 288 Each of these flags is also recognized with an optional 'test.' prefix, 289 as in -test.v. When invoking the generated test binary (the result of 290 'go test -c') directly, however, the prefix is mandatory. 291 292 The 'go test' command rewrites or removes recognized flags, 293 as appropriate, both before and after the optional package list, 294 before invoking the test binary. 295 296 For instance, the command 297 298 go test -v -myflag testdata -cpuprofile=prof.out -x 299 300 will compile the test binary and then run it as 301 302 pkg.test -test.v -myflag testdata -test.cpuprofile=prof.out 303 304 (The -x flag is removed because it applies only to the go command's 305 execution, not to the test itself.) 306 307 The test flags that generate profiles (other than for coverage) also 308 leave the test binary in pkg.test for use when analyzing the profiles. 309 310 When 'go test' runs a test binary, it does so from within the 311 corresponding package's source code directory. Depending on the test, 312 it may be necessary to do the same when invoking a generated test 313 binary directly. 314 315 The command-line package list, if present, must appear before any 316 flag not known to the go test command. Continuing the example above, 317 the package list would have to appear before -myflag, but could appear 318 on either side of -v. 319 320 To keep an argument for a test binary from being interpreted as a 321 known flag or a package name, use -args (see 'go help test') which 322 passes the remainder of the command line through to the test binary 323 uninterpreted and unaltered. 324 325 For instance, the command 326 327 go test -v -args -x -v 328 329 will compile the test binary and then run it as 330 331 pkg.test -test.v -x -v 332 333 Similarly, 334 335 go test -args math 336 337 will compile the test binary and then run it as 338 339 pkg.test math 340 341 In the first example, the -x and the second -v are passed through to the 342 test binary unchanged and with no effect on the go command itself. 343 In the second example, the argument math is passed through to the test 344 binary, instead of being interpreted as the package list. 345 ` 346 347 var HelpTestfunc = &base.Command{ 348 UsageLine: "testfunc", 349 Short: "description of testing functions", 350 Long: ` 351 The 'go test' command expects to find test, benchmark, and example functions 352 in the "*_test.go" files corresponding to the package under test. 353 354 A test function is one named TestXXX (where XXX is any alphanumeric string 355 not starting with a lower case letter) and should have the signature, 356 357 func TestXXX(t *testing.T) { ... } 358 359 A benchmark function is one named BenchmarkXXX and should have the signature, 360 361 func BenchmarkXXX(b *testing.B) { ... } 362 363 An example function is similar to a test function but, instead of using 364 *testing.T to report success or failure, prints output to os.Stdout. 365 If the last comment in the function starts with "Output:" then the output 366 is compared exactly against the comment (see examples below). If the last 367 comment begins with "Unordered output:" then the output is compared to the 368 comment, however the order of the lines is ignored. An example with no such 369 comment is compiled but not executed. An example with no text after 370 "Output:" is compiled, executed, and expected to produce no output. 371 372 Godoc displays the body of ExampleXXX to demonstrate the use 373 of the function, constant, or variable XXX. An example of a method M with 374 receiver type T or *T is named ExampleT_M. There may be multiple examples 375 for a given function, constant, or variable, distinguished by a trailing _xxx, 376 where xxx is a suffix not beginning with an upper case letter. 377 378 Here is an example of an example: 379 380 func ExamplePrintln() { 381 Println("The output of\nthis example.") 382 // Output: The output of 383 // this example. 384 } 385 386 Here is another example where the ordering of the output is ignored: 387 388 func ExamplePerm() { 389 for _, value := range Perm(4) { 390 fmt.Println(value) 391 } 392 393 // Unordered output: 4 394 // 2 395 // 1 396 // 3 397 // 0 398 } 399 400 The entire test file is presented as the example when it contains a single 401 example function, at least one other function, type, variable, or constant 402 declaration, and no test or benchmark functions. 403 404 See the documentation of the testing package for more information. 405 `, 406 } 407 408 var ( 409 testC bool // -c flag 410 testCover bool // -cover flag 411 testCoverMode string // -covermode flag 412 testCoverPaths []string // -coverpkg flag 413 testCoverPkgs []*load.Package // -coverpkg flag 414 testO string // -o flag 415 testProfile bool // some profiling flag 416 testNeedBinary bool // profile needs to keep binary around 417 testV bool // -v flag 418 testTimeout string // -timeout flag 419 testArgs []string 420 testBench bool 421 testList bool 422 testStreamOutput bool // show output as it is generated 423 testShowPass bool // show passing output 424 425 testKillTimeout = 10 * time.Minute 426 ) 427 428 var testMainDeps = map[string]bool{ 429 // Dependencies for testmain. 430 "testing": true, 431 "testing/internal/testdeps": true, 432 "os": true, 433 } 434 435 func runTest(cmd *base.Command, args []string) { 436 var pkgArgs []string 437 pkgArgs, testArgs = testFlags(args) 438 439 work.FindExecCmd() // initialize cached result 440 441 work.InstrumentInit() 442 work.BuildModeInit() 443 pkgs := load.PackagesForBuild(pkgArgs) 444 if len(pkgs) == 0 { 445 base.Fatalf("no packages to test") 446 } 447 448 if testC && len(pkgs) != 1 { 449 base.Fatalf("cannot use -c flag with multiple packages") 450 } 451 if testO != "" && len(pkgs) != 1 { 452 base.Fatalf("cannot use -o flag with multiple packages") 453 } 454 if testProfile && len(pkgs) != 1 { 455 base.Fatalf("cannot use test profile flag with multiple packages") 456 } 457 458 // If a test timeout was given and is parseable, set our kill timeout 459 // to that timeout plus one minute. This is a backup alarm in case 460 // the test wedges with a goroutine spinning and its background 461 // timer does not get a chance to fire. 462 if dt, err := time.ParseDuration(testTimeout); err == nil && dt > 0 { 463 testKillTimeout = dt + 1*time.Minute 464 } 465 466 // show passing test output (after buffering) with -v flag. 467 // must buffer because tests are running in parallel, and 468 // otherwise the output will get mixed. 469 testShowPass = testV || testList 470 471 // stream test output (no buffering) when no package has 472 // been given on the command line (implicit current directory) 473 // or when benchmarking. 474 // Also stream if we're showing output anyway with a 475 // single package under test or if parallelism is set to 1. 476 // In these cases, streaming the output produces the same result 477 // as not streaming, just more immediately. 478 testStreamOutput = len(pkgArgs) == 0 || testBench || 479 (testShowPass && (len(pkgs) == 1 || cfg.BuildP == 1)) 480 481 // For 'go test -i -o x.test', we want to build x.test. Imply -c to make the logic easier. 482 if cfg.BuildI && testO != "" { 483 testC = true 484 } 485 486 var b work.Builder 487 b.Init() 488 489 if cfg.BuildI { 490 cfg.BuildV = testV 491 492 deps := make(map[string]bool) 493 for dep := range testMainDeps { 494 deps[dep] = true 495 } 496 497 for _, p := range pkgs { 498 // Dependencies for each test. 499 for _, path := range p.Imports { 500 deps[path] = true 501 } 502 for _, path := range p.Vendored(p.TestImports) { 503 deps[path] = true 504 } 505 for _, path := range p.Vendored(p.XTestImports) { 506 deps[path] = true 507 } 508 } 509 510 // translate C to runtime/cgo 511 if deps["C"] { 512 delete(deps, "C") 513 deps["runtime/cgo"] = true 514 if cfg.Goos == runtime.GOOS && cfg.Goarch == runtime.GOARCH && !cfg.BuildRace && !cfg.BuildMSan { 515 deps["cmd/cgo"] = true 516 } 517 } 518 // Ignore pseudo-packages. 519 delete(deps, "unsafe") 520 521 all := []string{} 522 for path := range deps { 523 if !build.IsLocalImport(path) { 524 all = append(all, path) 525 } 526 } 527 sort.Strings(all) 528 529 a := &work.Action{} 530 for _, p := range load.PackagesForBuild(all) { 531 a.Deps = append(a.Deps, b.Action(work.ModeInstall, work.ModeInstall, p)) 532 } 533 b.Do(a) 534 if !testC || a.Failed { 535 return 536 } 537 b.Init() 538 } 539 540 var builds, runs, prints []*work.Action 541 542 if testCoverPaths != nil { 543 // Load packages that were asked about for coverage. 544 // packagesForBuild exits if the packages cannot be loaded. 545 testCoverPkgs = load.PackagesForBuild(testCoverPaths) 546 547 // Warn about -coverpkg arguments that are not actually used. 548 used := make(map[string]bool) 549 for _, p := range pkgs { 550 used[p.ImportPath] = true 551 for _, dep := range p.Deps { 552 used[dep] = true 553 } 554 } 555 for _, p := range testCoverPkgs { 556 if !used[p.ImportPath] { 557 fmt.Fprintf(os.Stderr, "warning: no packages being tested depend on %s\n", p.ImportPath) 558 } 559 } 560 561 // Mark all the coverage packages for rebuilding with coverage. 562 for _, p := range testCoverPkgs { 563 // There is nothing to cover in package unsafe; it comes from the compiler. 564 if p.ImportPath == "unsafe" { 565 continue 566 } 567 p.Stale = true // rebuild 568 p.StaleReason = "rebuild for coverage" 569 p.Internal.Fake = true // do not warn about rebuild 570 p.Internal.CoverMode = testCoverMode 571 var coverFiles []string 572 coverFiles = append(coverFiles, p.GoFiles...) 573 coverFiles = append(coverFiles, p.CgoFiles...) 574 coverFiles = append(coverFiles, p.TestGoFiles...) 575 p.Internal.CoverVars = declareCoverVars(p.ImportPath, coverFiles...) 576 } 577 } 578 579 // Prepare build + run + print actions for all packages being tested. 580 for _, p := range pkgs { 581 // sync/atomic import is inserted by the cover tool. See #18486 582 if testCover && testCoverMode == "atomic" { 583 ensureImport(p, "sync/atomic") 584 } 585 586 buildTest, runTest, printTest, err := builderTest(&b, p) 587 if err != nil { 588 str := err.Error() 589 if strings.HasPrefix(str, "\n") { 590 str = str[1:] 591 } 592 failed := fmt.Sprintf("FAIL\t%s [setup failed]\n", p.ImportPath) 593 594 if p.ImportPath != "" { 595 base.Errorf("# %s\n%s\n%s", p.ImportPath, str, failed) 596 } else { 597 base.Errorf("%s\n%s", str, failed) 598 } 599 continue 600 } 601 builds = append(builds, buildTest) 602 runs = append(runs, runTest) 603 prints = append(prints, printTest) 604 } 605 606 // Ultimately the goal is to print the output. 607 root := &work.Action{Deps: prints} 608 609 // Force the printing of results to happen in order, 610 // one at a time. 611 for i, a := range prints { 612 if i > 0 { 613 a.Deps = append(a.Deps, prints[i-1]) 614 } 615 } 616 617 // Force benchmarks to run in serial. 618 if !testC && testBench { 619 // The first run must wait for all builds. 620 // Later runs must wait for the previous run's print. 621 for i, run := range runs { 622 if i == 0 { 623 run.Deps = append(run.Deps, builds...) 624 } else { 625 run.Deps = append(run.Deps, prints[i-1]) 626 } 627 } 628 } 629 630 // If we are building any out-of-date packages other 631 // than those under test, warn. 632 okBuild := map[*load.Package]bool{} 633 for _, p := range pkgs { 634 okBuild[p] = true 635 } 636 warned := false 637 for _, a := range work.ActionList(root) { 638 if a.Package == nil || okBuild[a.Package] { 639 continue 640 } 641 okBuild[a.Package] = true // warn at most once 642 643 // Don't warn about packages being rebuilt because of 644 // things like coverage analysis. 645 for _, p1 := range a.Package.Internal.Imports { 646 if p1.Internal.Fake { 647 a.Package.Internal.Fake = true 648 } 649 } 650 651 if a.Func != nil && !okBuild[a.Package] && !a.Package.Internal.Fake && !a.Package.Internal.Local { 652 if !warned { 653 fmt.Fprintf(os.Stderr, "warning: building out-of-date packages:\n") 654 warned = true 655 } 656 fmt.Fprintf(os.Stderr, "\t%s\n", a.Package.ImportPath) 657 } 658 } 659 if warned { 660 args := strings.Join(pkgArgs, " ") 661 if args != "" { 662 args = " " + args 663 } 664 extraOpts := "" 665 if cfg.BuildRace { 666 extraOpts = "-race " 667 } 668 if cfg.BuildMSan { 669 extraOpts = "-msan " 670 } 671 fmt.Fprintf(os.Stderr, "installing these packages with 'go test %s-i%s' will speed future tests.\n\n", extraOpts, args) 672 } 673 674 b.Do(root) 675 } 676 677 // ensures that package p imports the named package 678 func ensureImport(p *load.Package, pkg string) { 679 for _, d := range p.Internal.Deps { 680 if d.Name == pkg { 681 return 682 } 683 } 684 685 a := load.LoadPackage(pkg, &load.ImportStack{}) 686 if a.Error != nil { 687 base.Fatalf("load %s: %v", pkg, a.Error) 688 } 689 load.ComputeStale(a) 690 691 p.Internal.Imports = append(p.Internal.Imports, a) 692 } 693 694 var windowsBadWords = []string{ 695 "install", 696 "patch", 697 "setup", 698 "update", 699 } 700 701 func builderTest(b *work.Builder, p *load.Package) (buildAction, runAction, printAction *work.Action, err error) { 702 if len(p.TestGoFiles)+len(p.XTestGoFiles) == 0 { 703 build := b.Action(work.ModeBuild, work.ModeBuild, p) 704 run := &work.Action{Package: p, Deps: []*work.Action{build}} 705 print := &work.Action{Func: builderNoTest, Package: p, Deps: []*work.Action{run}} 706 return build, run, print, nil 707 } 708 709 // Build Package structs describing: 710 // ptest - package + test files 711 // pxtest - package of external test files 712 // pmain - pkg.test binary 713 var ptest, pxtest, pmain *load.Package 714 715 var imports, ximports []*load.Package 716 var stk load.ImportStack 717 stk.Push(p.ImportPath + " (test)") 718 for i, path := range p.TestImports { 719 p1 := load.LoadImport(path, p.Dir, p, &stk, p.Internal.Build.TestImportPos[path], load.UseVendor) 720 if p1.Error != nil { 721 return nil, nil, nil, p1.Error 722 } 723 if len(p1.DepsErrors) > 0 { 724 err := p1.DepsErrors[0] 725 err.Pos = "" // show full import stack 726 return nil, nil, nil, err 727 } 728 if str.Contains(p1.Deps, p.ImportPath) || p1.ImportPath == p.ImportPath { 729 // Same error that loadPackage returns (via reusePackage) in pkg.go. 730 // Can't change that code, because that code is only for loading the 731 // non-test copy of a package. 732 err := &load.PackageError{ 733 ImportStack: testImportStack(stk[0], p1, p.ImportPath), 734 Err: "import cycle not allowed in test", 735 IsImportCycle: true, 736 } 737 return nil, nil, nil, err 738 } 739 p.TestImports[i] = p1.ImportPath 740 imports = append(imports, p1) 741 } 742 stk.Pop() 743 stk.Push(p.ImportPath + "_test") 744 pxtestNeedsPtest := false 745 for i, path := range p.XTestImports { 746 p1 := load.LoadImport(path, p.Dir, p, &stk, p.Internal.Build.XTestImportPos[path], load.UseVendor) 747 if p1.Error != nil { 748 return nil, nil, nil, p1.Error 749 } 750 if len(p1.DepsErrors) > 0 { 751 err := p1.DepsErrors[0] 752 err.Pos = "" // show full import stack 753 return nil, nil, nil, err 754 } 755 if p1.ImportPath == p.ImportPath { 756 pxtestNeedsPtest = true 757 } else { 758 ximports = append(ximports, p1) 759 } 760 p.XTestImports[i] = p1.ImportPath 761 } 762 stk.Pop() 763 764 // Use last element of import path, not package name. 765 // They differ when package name is "main". 766 // But if the import path is "command-line-arguments", 767 // like it is during 'go run', use the package name. 768 var elem string 769 if p.ImportPath == "command-line-arguments" { 770 elem = p.Name 771 } else { 772 _, elem = path.Split(p.ImportPath) 773 } 774 testBinary := elem + ".test" 775 776 // The ptest package needs to be importable under the 777 // same import path that p has, but we cannot put it in 778 // the usual place in the temporary tree, because then 779 // other tests will see it as the real package. 780 // Instead we make a _test directory under the import path 781 // and then repeat the import path there. We tell the 782 // compiler and linker to look in that _test directory first. 783 // 784 // That is, if the package under test is unicode/utf8, 785 // then the normal place to write the package archive is 786 // $WORK/unicode/utf8.a, but we write the test package archive to 787 // $WORK/unicode/utf8/_test/unicode/utf8.a. 788 // We write the external test package archive to 789 // $WORK/unicode/utf8/_test/unicode/utf8_test.a. 790 testDir := filepath.Join(b.WorkDir, filepath.FromSlash(p.ImportPath+"/_test")) 791 ptestObj := work.BuildToolchain.Pkgpath(testDir, p) 792 793 // Create the directory for the .a files. 794 ptestDir, _ := filepath.Split(ptestObj) 795 if err := b.Mkdir(ptestDir); err != nil { 796 return nil, nil, nil, err 797 } 798 799 // Should we apply coverage analysis locally, 800 // only for this package and only for this test? 801 // Yes, if -cover is on but -coverpkg has not specified 802 // a list of packages for global coverage. 803 localCover := testCover && testCoverPaths == nil 804 805 // Test package. 806 if len(p.TestGoFiles) > 0 || localCover || p.Name == "main" { 807 ptest = new(load.Package) 808 *ptest = *p 809 ptest.GoFiles = nil 810 ptest.GoFiles = append(ptest.GoFiles, p.GoFiles...) 811 ptest.GoFiles = append(ptest.GoFiles, p.TestGoFiles...) 812 ptest.Internal.Target = "" 813 ptest.Imports = str.StringList(p.Imports, p.TestImports) 814 ptest.Internal.Imports = append(append([]*load.Package{}, p.Internal.Imports...), imports...) 815 ptest.Internal.Pkgdir = testDir 816 ptest.Internal.Fake = true 817 ptest.Internal.ForceLibrary = true 818 ptest.Stale = true 819 ptest.StaleReason = "rebuild for test" 820 ptest.Internal.Build = new(build.Package) 821 *ptest.Internal.Build = *p.Internal.Build 822 m := map[string][]token.Position{} 823 for k, v := range p.Internal.Build.ImportPos { 824 m[k] = append(m[k], v...) 825 } 826 for k, v := range p.Internal.Build.TestImportPos { 827 m[k] = append(m[k], v...) 828 } 829 ptest.Internal.Build.ImportPos = m 830 831 if localCover { 832 ptest.Internal.CoverMode = testCoverMode 833 var coverFiles []string 834 coverFiles = append(coverFiles, ptest.GoFiles...) 835 coverFiles = append(coverFiles, ptest.CgoFiles...) 836 ptest.Internal.CoverVars = declareCoverVars(ptest.ImportPath, coverFiles...) 837 } 838 } else { 839 ptest = p 840 } 841 842 // External test package. 843 if len(p.XTestGoFiles) > 0 { 844 pxtest = &load.Package{ 845 PackagePublic: load.PackagePublic{ 846 Name: p.Name + "_test", 847 ImportPath: p.ImportPath + "_test", 848 Root: p.Root, 849 Dir: p.Dir, 850 GoFiles: p.XTestGoFiles, 851 Imports: p.XTestImports, 852 Stale: true, 853 }, 854 Internal: load.PackageInternal{ 855 LocalPrefix: p.Internal.LocalPrefix, 856 Build: &build.Package{ 857 ImportPos: p.Internal.Build.XTestImportPos, 858 }, 859 Imports: ximports, 860 Pkgdir: testDir, 861 Fake: true, 862 External: true, 863 }, 864 } 865 if pxtestNeedsPtest { 866 pxtest.Internal.Imports = append(pxtest.Internal.Imports, ptest) 867 } 868 } 869 870 // Action for building pkg.test. 871 pmain = &load.Package{ 872 PackagePublic: load.PackagePublic{ 873 Name: "main", 874 Dir: testDir, 875 GoFiles: []string{"_testmain.go"}, 876 ImportPath: "testmain", 877 Root: p.Root, 878 Stale: true, 879 }, 880 Internal: load.PackageInternal{ 881 Build: &build.Package{Name: "main"}, 882 Pkgdir: testDir, 883 Fake: true, 884 OmitDebug: !testC && !testNeedBinary, 885 }, 886 } 887 888 // The generated main also imports testing, regexp, and os. 889 stk.Push("testmain") 890 for dep := range testMainDeps { 891 if dep == ptest.ImportPath { 892 pmain.Internal.Imports = append(pmain.Internal.Imports, ptest) 893 } else { 894 p1 := load.LoadImport(dep, "", nil, &stk, nil, 0) 895 if p1.Error != nil { 896 return nil, nil, nil, p1.Error 897 } 898 pmain.Internal.Imports = append(pmain.Internal.Imports, p1) 899 } 900 } 901 902 if testCoverPkgs != nil { 903 // Add imports, but avoid duplicates. 904 seen := map[*load.Package]bool{p: true, ptest: true} 905 for _, p1 := range pmain.Internal.Imports { 906 seen[p1] = true 907 } 908 for _, p1 := range testCoverPkgs { 909 if !seen[p1] { 910 seen[p1] = true 911 pmain.Internal.Imports = append(pmain.Internal.Imports, p1) 912 } 913 } 914 } 915 916 // Do initial scan for metadata needed for writing _testmain.go 917 // Use that metadata to update the list of imports for package main. 918 // The list of imports is used by recompileForTest and by the loop 919 // afterward that gathers t.Cover information. 920 t, err := loadTestFuncs(ptest) 921 if err != nil { 922 return nil, nil, nil, err 923 } 924 if len(ptest.GoFiles)+len(ptest.CgoFiles) > 0 { 925 pmain.Internal.Imports = append(pmain.Internal.Imports, ptest) 926 t.ImportTest = true 927 } 928 if pxtest != nil { 929 pmain.Internal.Imports = append(pmain.Internal.Imports, pxtest) 930 t.ImportXtest = true 931 } 932 933 if ptest != p && localCover { 934 // We have made modifications to the package p being tested 935 // and are rebuilding p (as ptest), writing it to the testDir tree. 936 // Arrange to rebuild, writing to that same tree, all packages q 937 // such that the test depends on q, and q depends on p. 938 // This makes sure that q sees the modifications to p. 939 // Strictly speaking, the rebuild is only necessary if the 940 // modifications to p change its export metadata, but 941 // determining that is a bit tricky, so we rebuild always. 942 // 943 // This will cause extra compilation, so for now we only do it 944 // when testCover is set. The conditions are more general, though, 945 // and we may find that we need to do it always in the future. 946 recompileForTest(pmain, p, ptest, testDir) 947 } 948 949 if cfg.BuildContext.GOOS == "darwin" { 950 if cfg.BuildContext.GOARCH == "arm" || cfg.BuildContext.GOARCH == "arm64" { 951 t.NeedCgo = true 952 } 953 } 954 955 for _, cp := range pmain.Internal.Imports { 956 if len(cp.Internal.CoverVars) > 0 { 957 t.Cover = append(t.Cover, coverInfo{cp, cp.Internal.CoverVars}) 958 } 959 } 960 961 if !cfg.BuildN { 962 // writeTestmain writes _testmain.go. This must happen after recompileForTest, 963 // because recompileForTest modifies XXX. 964 if err := writeTestmain(filepath.Join(testDir, "_testmain.go"), t); err != nil { 965 return nil, nil, nil, err 966 } 967 } 968 969 load.ComputeStale(pmain) 970 971 if ptest != p { 972 a := b.Action(work.ModeBuild, work.ModeBuild, ptest) 973 a.Objdir = testDir + string(filepath.Separator) + "_obj_test" + string(filepath.Separator) 974 a.Objpkg = ptestObj 975 a.Target = ptestObj 976 a.Link = false 977 } 978 979 if pxtest != nil { 980 a := b.Action(work.ModeBuild, work.ModeBuild, pxtest) 981 a.Objdir = testDir + string(filepath.Separator) + "_obj_xtest" + string(filepath.Separator) 982 a.Objpkg = work.BuildToolchain.Pkgpath(testDir, pxtest) 983 a.Target = a.Objpkg 984 } 985 986 a := b.Action(work.ModeBuild, work.ModeBuild, pmain) 987 a.Objdir = testDir + string(filepath.Separator) 988 a.Objpkg = filepath.Join(testDir, "main.a") 989 a.Target = filepath.Join(testDir, testBinary) + cfg.ExeSuffix 990 if cfg.Goos == "windows" { 991 // There are many reserved words on Windows that, 992 // if used in the name of an executable, cause Windows 993 // to try to ask for extra permissions. 994 // The word list includes setup, install, update, and patch, 995 // but it does not appear to be defined anywhere. 996 // We have run into this trying to run the 997 // go.codereview/patch tests. 998 // For package names containing those words, use test.test.exe 999 // instead of pkgname.test.exe. 1000 // Note that this file name is only used in the Go command's 1001 // temporary directory. If the -c or other flags are 1002 // given, the code below will still use pkgname.test.exe. 1003 // There are two user-visible effects of this change. 1004 // First, you can actually run 'go test' in directories that 1005 // have names that Windows thinks are installer-like, 1006 // without getting a dialog box asking for more permissions. 1007 // Second, in the Windows process listing during go test, 1008 // the test shows up as test.test.exe, not pkgname.test.exe. 1009 // That second one is a drawback, but it seems a small 1010 // price to pay for the test running at all. 1011 // If maintaining the list of bad words is too onerous, 1012 // we could just do this always on Windows. 1013 for _, bad := range windowsBadWords { 1014 if strings.Contains(testBinary, bad) { 1015 a.Target = filepath.Join(testDir, "test.test") + cfg.ExeSuffix 1016 break 1017 } 1018 } 1019 } 1020 buildAction = a 1021 1022 if testC || testNeedBinary { 1023 // -c or profiling flag: create action to copy binary to ./test.out. 1024 target := filepath.Join(base.Cwd, testBinary+cfg.ExeSuffix) 1025 if testO != "" { 1026 target = testO 1027 if !filepath.IsAbs(target) { 1028 target = filepath.Join(base.Cwd, target) 1029 } 1030 } 1031 buildAction = &work.Action{ 1032 Func: work.BuildInstallFunc, 1033 Deps: []*work.Action{buildAction}, 1034 Package: pmain, 1035 Target: target, 1036 } 1037 runAction = buildAction // make sure runAction != nil even if not running test 1038 } 1039 if testC { 1040 printAction = &work.Action{Package: p, Deps: []*work.Action{runAction}} // nop 1041 } else { 1042 // run test 1043 runAction = &work.Action{ 1044 Func: builderRunTest, 1045 Deps: []*work.Action{buildAction}, 1046 Package: p, 1047 IgnoreFail: true, 1048 } 1049 cleanAction := &work.Action{ 1050 Func: builderCleanTest, 1051 Deps: []*work.Action{runAction}, 1052 Package: p, 1053 } 1054 printAction = &work.Action{ 1055 Func: builderPrintTest, 1056 Deps: []*work.Action{cleanAction}, 1057 Package: p, 1058 } 1059 } 1060 1061 return buildAction, runAction, printAction, nil 1062 } 1063 1064 func testImportStack(top string, p *load.Package, target string) []string { 1065 stk := []string{top, p.ImportPath} 1066 Search: 1067 for p.ImportPath != target { 1068 for _, p1 := range p.Internal.Imports { 1069 if p1.ImportPath == target || str.Contains(p1.Deps, target) { 1070 stk = append(stk, p1.ImportPath) 1071 p = p1 1072 continue Search 1073 } 1074 } 1075 // Can't happen, but in case it does... 1076 stk = append(stk, "<lost path to cycle>") 1077 break 1078 } 1079 return stk 1080 } 1081 1082 func recompileForTest(pmain, preal, ptest *load.Package, testDir string) { 1083 // The "test copy" of preal is ptest. 1084 // For each package that depends on preal, make a "test copy" 1085 // that depends on ptest. And so on, up the dependency tree. 1086 testCopy := map[*load.Package]*load.Package{preal: ptest} 1087 for _, p := range load.PackageList([]*load.Package{pmain}) { 1088 // Copy on write. 1089 didSplit := false 1090 split := func() { 1091 if didSplit { 1092 return 1093 } 1094 didSplit = true 1095 if p.Internal.Pkgdir != testDir { 1096 p1 := new(load.Package) 1097 testCopy[p] = p1 1098 *p1 = *p 1099 p1.Internal.Imports = make([]*load.Package, len(p.Internal.Imports)) 1100 copy(p1.Internal.Imports, p.Internal.Imports) 1101 p = p1 1102 p.Internal.Pkgdir = testDir 1103 p.Internal.Target = "" 1104 p.Internal.Fake = true 1105 p.Stale = true 1106 p.StaleReason = "depends on package being tested" 1107 } 1108 } 1109 1110 // Update p.Deps and p.Internal.Imports to use at test copies. 1111 for i, dep := range p.Internal.Deps { 1112 if p1 := testCopy[dep]; p1 != nil && p1 != dep { 1113 split() 1114 p.Internal.Deps[i] = p1 1115 } 1116 } 1117 for i, imp := range p.Internal.Imports { 1118 if p1 := testCopy[imp]; p1 != nil && p1 != imp { 1119 split() 1120 p.Internal.Imports[i] = p1 1121 } 1122 } 1123 } 1124 } 1125 1126 var coverIndex = 0 1127 1128 // isTestFile reports whether the source file is a set of tests and should therefore 1129 // be excluded from coverage analysis. 1130 func isTestFile(file string) bool { 1131 // We don't cover tests, only the code they test. 1132 return strings.HasSuffix(file, "_test.go") 1133 } 1134 1135 // declareCoverVars attaches the required cover variables names 1136 // to the files, to be used when annotating the files. 1137 func declareCoverVars(importPath string, files ...string) map[string]*load.CoverVar { 1138 coverVars := make(map[string]*load.CoverVar) 1139 for _, file := range files { 1140 if isTestFile(file) { 1141 continue 1142 } 1143 coverVars[file] = &load.CoverVar{ 1144 File: filepath.Join(importPath, file), 1145 Var: fmt.Sprintf("GoCover_%d", coverIndex), 1146 } 1147 coverIndex++ 1148 } 1149 return coverVars 1150 } 1151 1152 var noTestsToRun = []byte("\ntesting: warning: no tests to run\n") 1153 1154 // builderRunTest is the action for running a test binary. 1155 func builderRunTest(b *work.Builder, a *work.Action) error { 1156 args := str.StringList(work.FindExecCmd(), a.Deps[0].Target, testArgs) 1157 a.TestOutput = new(bytes.Buffer) 1158 1159 if cfg.BuildN || cfg.BuildX { 1160 b.Showcmd("", "%s", strings.Join(args, " ")) 1161 if cfg.BuildN { 1162 return nil 1163 } 1164 } 1165 1166 if a.Failed { 1167 // We were unable to build the binary. 1168 a.Failed = false 1169 fmt.Fprintf(a.TestOutput, "FAIL\t%s [build failed]\n", a.Package.ImportPath) 1170 base.SetExitStatus(1) 1171 return nil 1172 } 1173 1174 cmd := exec.Command(args[0], args[1:]...) 1175 cmd.Dir = a.Package.Dir 1176 cmd.Env = base.EnvForDir(cmd.Dir, cfg.OrigEnv) 1177 var buf bytes.Buffer 1178 if testStreamOutput { 1179 cmd.Stdout = os.Stdout 1180 cmd.Stderr = os.Stderr 1181 } else { 1182 cmd.Stdout = &buf 1183 cmd.Stderr = &buf 1184 } 1185 1186 // If there are any local SWIG dependencies, we want to load 1187 // the shared library from the build directory. 1188 if a.Package.UsesSwig() { 1189 env := cmd.Env 1190 found := false 1191 prefix := "LD_LIBRARY_PATH=" 1192 for i, v := range env { 1193 if strings.HasPrefix(v, prefix) { 1194 env[i] = v + ":." 1195 found = true 1196 break 1197 } 1198 } 1199 if !found { 1200 env = append(env, "LD_LIBRARY_PATH=.") 1201 } 1202 cmd.Env = env 1203 } 1204 1205 t0 := time.Now() 1206 err := cmd.Start() 1207 1208 // This is a last-ditch deadline to detect and 1209 // stop wedged test binaries, to keep the builders 1210 // running. 1211 if err == nil { 1212 tick := time.NewTimer(testKillTimeout) 1213 base.StartSigHandlers() 1214 done := make(chan error) 1215 go func() { 1216 done <- cmd.Wait() 1217 }() 1218 Outer: 1219 select { 1220 case err = <-done: 1221 // ok 1222 case <-tick.C: 1223 if base.SignalTrace != nil { 1224 // Send a quit signal in the hope that the program will print 1225 // a stack trace and exit. Give it five seconds before resorting 1226 // to Kill. 1227 cmd.Process.Signal(base.SignalTrace) 1228 select { 1229 case err = <-done: 1230 fmt.Fprintf(&buf, "*** Test killed with %v: ran too long (%v).\n", base.SignalTrace, testKillTimeout) 1231 break Outer 1232 case <-time.After(5 * time.Second): 1233 } 1234 } 1235 cmd.Process.Kill() 1236 err = <-done 1237 fmt.Fprintf(&buf, "*** Test killed: ran too long (%v).\n", testKillTimeout) 1238 } 1239 tick.Stop() 1240 } 1241 out := buf.Bytes() 1242 t := fmt.Sprintf("%.3fs", time.Since(t0).Seconds()) 1243 if err == nil { 1244 norun := "" 1245 if testShowPass { 1246 a.TestOutput.Write(out) 1247 } 1248 if bytes.HasPrefix(out, noTestsToRun[1:]) || bytes.Contains(out, noTestsToRun) { 1249 norun = " [no tests to run]" 1250 } 1251 fmt.Fprintf(a.TestOutput, "ok \t%s\t%s%s%s\n", a.Package.ImportPath, t, coveragePercentage(out), norun) 1252 return nil 1253 } 1254 1255 base.SetExitStatus(1) 1256 if len(out) > 0 { 1257 a.TestOutput.Write(out) 1258 // assume printing the test binary's exit status is superfluous 1259 } else { 1260 fmt.Fprintf(a.TestOutput, "%s\n", err) 1261 } 1262 fmt.Fprintf(a.TestOutput, "FAIL\t%s\t%s\n", a.Package.ImportPath, t) 1263 1264 return nil 1265 } 1266 1267 // coveragePercentage returns the coverage results (if enabled) for the 1268 // test. It uncovers the data by scanning the output from the test run. 1269 func coveragePercentage(out []byte) string { 1270 if !testCover { 1271 return "" 1272 } 1273 // The string looks like 1274 // test coverage for encoding/binary: 79.9% of statements 1275 // Extract the piece from the percentage to the end of the line. 1276 re := regexp.MustCompile(`coverage: (.*)\n`) 1277 matches := re.FindSubmatch(out) 1278 if matches == nil { 1279 // Probably running "go test -cover" not "go test -cover fmt". 1280 // The coverage output will appear in the output directly. 1281 return "" 1282 } 1283 return fmt.Sprintf("\tcoverage: %s", matches[1]) 1284 } 1285 1286 // builderCleanTest is the action for cleaning up after a test. 1287 func builderCleanTest(b *work.Builder, a *work.Action) error { 1288 if cfg.BuildWork { 1289 return nil 1290 } 1291 run := a.Deps[0] 1292 testDir := filepath.Join(b.WorkDir, filepath.FromSlash(run.Package.ImportPath+"/_test")) 1293 os.RemoveAll(testDir) 1294 return nil 1295 } 1296 1297 // builderPrintTest is the action for printing a test result. 1298 func builderPrintTest(b *work.Builder, a *work.Action) error { 1299 clean := a.Deps[0] 1300 run := clean.Deps[0] 1301 os.Stdout.Write(run.TestOutput.Bytes()) 1302 run.TestOutput = nil 1303 return nil 1304 } 1305 1306 // builderNoTest is the action for testing a package with no test files. 1307 func builderNoTest(b *work.Builder, a *work.Action) error { 1308 fmt.Printf("? \t%s\t[no test files]\n", a.Package.ImportPath) 1309 return nil 1310 } 1311 1312 // isTestFunc tells whether fn has the type of a testing function. arg 1313 // specifies the parameter type we look for: B, M or T. 1314 func isTestFunc(fn *ast.FuncDecl, arg string) bool { 1315 if fn.Type.Results != nil && len(fn.Type.Results.List) > 0 || 1316 fn.Type.Params.List == nil || 1317 len(fn.Type.Params.List) != 1 || 1318 len(fn.Type.Params.List[0].Names) > 1 { 1319 return false 1320 } 1321 ptr, ok := fn.Type.Params.List[0].Type.(*ast.StarExpr) 1322 if !ok { 1323 return false 1324 } 1325 // We can't easily check that the type is *testing.M 1326 // because we don't know how testing has been imported, 1327 // but at least check that it's *M or *something.M. 1328 // Same applies for B and T. 1329 if name, ok := ptr.X.(*ast.Ident); ok && name.Name == arg { 1330 return true 1331 } 1332 if sel, ok := ptr.X.(*ast.SelectorExpr); ok && sel.Sel.Name == arg { 1333 return true 1334 } 1335 return false 1336 } 1337 1338 // isTest tells whether name looks like a test (or benchmark, according to prefix). 1339 // It is a Test (say) if there is a character after Test that is not a lower-case letter. 1340 // We don't want TesticularCancer. 1341 func isTest(name, prefix string) bool { 1342 if !strings.HasPrefix(name, prefix) { 1343 return false 1344 } 1345 if len(name) == len(prefix) { // "Test" is ok 1346 return true 1347 } 1348 rune, _ := utf8.DecodeRuneInString(name[len(prefix):]) 1349 return !unicode.IsLower(rune) 1350 } 1351 1352 type coverInfo struct { 1353 Package *load.Package 1354 Vars map[string]*load.CoverVar 1355 } 1356 1357 // loadTestFuncs returns the testFuncs describing the tests that will be run. 1358 func loadTestFuncs(ptest *load.Package) (*testFuncs, error) { 1359 t := &testFuncs{ 1360 Package: ptest, 1361 } 1362 for _, file := range ptest.TestGoFiles { 1363 if err := t.load(filepath.Join(ptest.Dir, file), "_test", &t.ImportTest, &t.NeedTest); err != nil { 1364 return nil, err 1365 } 1366 } 1367 for _, file := range ptest.XTestGoFiles { 1368 if err := t.load(filepath.Join(ptest.Dir, file), "_xtest", &t.ImportXtest, &t.NeedXtest); err != nil { 1369 return nil, err 1370 } 1371 } 1372 return t, nil 1373 } 1374 1375 // writeTestmain writes the _testmain.go file for t to the file named out. 1376 func writeTestmain(out string, t *testFuncs) error { 1377 f, err := os.Create(out) 1378 if err != nil { 1379 return err 1380 } 1381 defer f.Close() 1382 1383 if err := testmainTmpl.Execute(f, t); err != nil { 1384 return err 1385 } 1386 1387 return nil 1388 } 1389 1390 type testFuncs struct { 1391 Tests []testFunc 1392 Benchmarks []testFunc 1393 Examples []testFunc 1394 TestMain *testFunc 1395 Package *load.Package 1396 ImportTest bool 1397 NeedTest bool 1398 ImportXtest bool 1399 NeedXtest bool 1400 NeedCgo bool 1401 Cover []coverInfo 1402 } 1403 1404 func (t *testFuncs) CoverMode() string { 1405 return testCoverMode 1406 } 1407 1408 func (t *testFuncs) CoverEnabled() bool { 1409 return testCover 1410 } 1411 1412 // ImportPath returns the import path of the package being tested, if it is within GOPATH. 1413 // This is printed by the testing package when running benchmarks. 1414 func (t *testFuncs) ImportPath() string { 1415 pkg := t.Package.ImportPath 1416 if strings.HasPrefix(pkg, "_/") { 1417 return "" 1418 } 1419 if pkg == "command-line-arguments" { 1420 return "" 1421 } 1422 return pkg 1423 } 1424 1425 // Covered returns a string describing which packages are being tested for coverage. 1426 // If the covered package is the same as the tested package, it returns the empty string. 1427 // Otherwise it is a comma-separated human-readable list of packages beginning with 1428 // " in", ready for use in the coverage message. 1429 func (t *testFuncs) Covered() string { 1430 if testCoverPaths == nil { 1431 return "" 1432 } 1433 return " in " + strings.Join(testCoverPaths, ", ") 1434 } 1435 1436 // Tested returns the name of the package being tested. 1437 func (t *testFuncs) Tested() string { 1438 return t.Package.Name 1439 } 1440 1441 type testFunc struct { 1442 Package string // imported package name (_test or _xtest) 1443 Name string // function name 1444 Output string // output, for examples 1445 Unordered bool // output is allowed to be unordered. 1446 } 1447 1448 var testFileSet = token.NewFileSet() 1449 1450 func (t *testFuncs) load(filename, pkg string, doImport, seen *bool) error { 1451 f, err := parser.ParseFile(testFileSet, filename, nil, parser.ParseComments) 1452 if err != nil { 1453 return base.ExpandScanner(err) 1454 } 1455 for _, d := range f.Decls { 1456 n, ok := d.(*ast.FuncDecl) 1457 if !ok { 1458 continue 1459 } 1460 if n.Recv != nil { 1461 continue 1462 } 1463 name := n.Name.String() 1464 switch { 1465 case name == "TestMain" && isTestFunc(n, "M"): 1466 if t.TestMain != nil { 1467 return errors.New("multiple definitions of TestMain") 1468 } 1469 t.TestMain = &testFunc{pkg, name, "", false} 1470 *doImport, *seen = true, true 1471 case isTest(name, "Test"): 1472 err := checkTestFunc(n, "T") 1473 if err != nil { 1474 return err 1475 } 1476 t.Tests = append(t.Tests, testFunc{pkg, name, "", false}) 1477 *doImport, *seen = true, true 1478 case isTest(name, "Benchmark"): 1479 err := checkTestFunc(n, "B") 1480 if err != nil { 1481 return err 1482 } 1483 t.Benchmarks = append(t.Benchmarks, testFunc{pkg, name, "", false}) 1484 *doImport, *seen = true, true 1485 } 1486 } 1487 ex := doc.Examples(f) 1488 sort.Slice(ex, func(i, j int) bool { return ex[i].Order < ex[j].Order }) 1489 for _, e := range ex { 1490 *doImport = true // import test file whether executed or not 1491 if e.Output == "" && !e.EmptyOutput { 1492 // Don't run examples with no output. 1493 continue 1494 } 1495 t.Examples = append(t.Examples, testFunc{pkg, "Example" + e.Name, e.Output, e.Unordered}) 1496 *seen = true 1497 } 1498 return nil 1499 } 1500 1501 func checkTestFunc(fn *ast.FuncDecl, arg string) error { 1502 if !isTestFunc(fn, arg) { 1503 name := fn.Name.String() 1504 pos := testFileSet.Position(fn.Pos()) 1505 return fmt.Errorf("%s: wrong signature for %s, must be: func %s(%s *testing.%s)", pos, name, name, strings.ToLower(arg), arg) 1506 } 1507 return nil 1508 } 1509 1510 var testmainTmpl = template.Must(template.New("main").Parse(` 1511 package main 1512 1513 import ( 1514 {{if not .TestMain}} 1515 "os" 1516 {{end}} 1517 "testing" 1518 "testing/internal/testdeps" 1519 1520 {{if .ImportTest}} 1521 {{if .NeedTest}}_test{{else}}_{{end}} {{.Package.ImportPath | printf "%q"}} 1522 {{end}} 1523 {{if .ImportXtest}} 1524 {{if .NeedXtest}}_xtest{{else}}_{{end}} {{.Package.ImportPath | printf "%s_test" | printf "%q"}} 1525 {{end}} 1526 {{range $i, $p := .Cover}} 1527 _cover{{$i}} {{$p.Package.ImportPath | printf "%q"}} 1528 {{end}} 1529 1530 {{if .NeedCgo}} 1531 _ "runtime/cgo" 1532 {{end}} 1533 ) 1534 1535 var tests = []testing.InternalTest{ 1536 {{range .Tests}} 1537 {"{{.Name}}", {{.Package}}.{{.Name}}}, 1538 {{end}} 1539 } 1540 1541 var benchmarks = []testing.InternalBenchmark{ 1542 {{range .Benchmarks}} 1543 {"{{.Name}}", {{.Package}}.{{.Name}}}, 1544 {{end}} 1545 } 1546 1547 var examples = []testing.InternalExample{ 1548 {{range .Examples}} 1549 {"{{.Name}}", {{.Package}}.{{.Name}}, {{.Output | printf "%q"}}, {{.Unordered}}}, 1550 {{end}} 1551 } 1552 1553 func init() { 1554 testdeps.ImportPath = {{.ImportPath | printf "%q"}} 1555 } 1556 1557 {{if .CoverEnabled}} 1558 1559 // Only updated by init functions, so no need for atomicity. 1560 var ( 1561 coverCounters = make(map[string][]uint32) 1562 coverBlocks = make(map[string][]testing.CoverBlock) 1563 ) 1564 1565 func init() { 1566 {{range $i, $p := .Cover}} 1567 {{range $file, $cover := $p.Vars}} 1568 coverRegisterFile({{printf "%q" $cover.File}}, _cover{{$i}}.{{$cover.Var}}.Count[:], _cover{{$i}}.{{$cover.Var}}.Pos[:], _cover{{$i}}.{{$cover.Var}}.NumStmt[:]) 1569 {{end}} 1570 {{end}} 1571 } 1572 1573 func coverRegisterFile(fileName string, counter []uint32, pos []uint32, numStmts []uint16) { 1574 if 3*len(counter) != len(pos) || len(counter) != len(numStmts) { 1575 panic("coverage: mismatched sizes") 1576 } 1577 if coverCounters[fileName] != nil { 1578 // Already registered. 1579 return 1580 } 1581 coverCounters[fileName] = counter 1582 block := make([]testing.CoverBlock, len(counter)) 1583 for i := range counter { 1584 block[i] = testing.CoverBlock{ 1585 Line0: pos[3*i+0], 1586 Col0: uint16(pos[3*i+2]), 1587 Line1: pos[3*i+1], 1588 Col1: uint16(pos[3*i+2]>>16), 1589 Stmts: numStmts[i], 1590 } 1591 } 1592 coverBlocks[fileName] = block 1593 } 1594 {{end}} 1595 1596 func main() { 1597 {{if .CoverEnabled}} 1598 testing.RegisterCover(testing.Cover{ 1599 Mode: {{printf "%q" .CoverMode}}, 1600 Counters: coverCounters, 1601 Blocks: coverBlocks, 1602 CoveredPackages: {{printf "%q" .Covered}}, 1603 }) 1604 {{end}} 1605 m := testing.MainStart(testdeps.TestDeps{}, tests, benchmarks, examples) 1606 {{with .TestMain}} 1607 {{.Package}}.{{.Name}}(m) 1608 {{else}} 1609 os.Exit(m.Run()) 1610 {{end}} 1611 } 1612 1613 `))