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