github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/cmd/go/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 main 6 7 import ( 8 "bytes" 9 "fmt" 10 "go/ast" 11 "go/build" 12 "go/doc" 13 "go/parser" 14 "go/token" 15 "os" 16 "os/exec" 17 "path" 18 "path/filepath" 19 "runtime" 20 "sort" 21 "strings" 22 "text/template" 23 "time" 24 "unicode" 25 "unicode/utf8" 26 ) 27 28 // Break init loop. 29 func init() { 30 cmdTest.Run = runTest 31 } 32 33 var cmdTest = &Command{ 34 CustomFlags: true, 35 UsageLine: "test [-c] [-i] [build flags] [packages] [flags for test binary]", 36 Short: "test packages", 37 Long: ` 38 'Go test' automates testing the packages named by the import paths. 39 It prints a summary of the test results in the format: 40 41 ok archive/tar 0.011s 42 FAIL archive/zip 0.022s 43 ok compress/gzip 0.033s 44 ... 45 46 followed by detailed output for each failed package. 47 48 'Go test' recompiles each package along with any files with names matching 49 the file pattern "*_test.go". These additional files can contain test functions, 50 benchmark functions, and example functions. See 'go help testfunc' for more. 51 Each listed package causes the execution of a separate test binary. 52 53 Test files that declare a package with the suffix "_test" will be compiled as a 54 separate package, and then linked and run with the main test binary. 55 56 By default, go test needs no arguments. It compiles and tests the package 57 with source in the current directory, including tests, and runs the tests. 58 59 The package is built in a temporary directory so it does not interfere with the 60 non-test installation. 61 62 In addition to the build flags, the flags handled by 'go test' itself are: 63 64 -c Compile the test binary to pkg.test but do not run it. 65 (Where pkg is the last element of the package's import path.) 66 67 -i 68 Install packages that are dependencies of the test. 69 Do not run the test. 70 71 The test binary also accepts flags that control execution of the test; these 72 flags are also accessible by 'go test'. See 'go help testflag' for details. 73 74 For more about build flags, see 'go help build'. 75 For more about specifying packages, see 'go help packages'. 76 77 See also: go build, go vet. 78 `, 79 } 80 81 var helpTestflag = &Command{ 82 UsageLine: "testflag", 83 Short: "description of testing flags", 84 Long: ` 85 The 'go test' command takes both flags that apply to 'go test' itself 86 and flags that apply to the resulting test binary. 87 88 Several of the flags control profiling and write an execution profile 89 suitable for "go tool pprof"; run "go tool pprof help" for more 90 information. The --alloc_space, --alloc_objects, and --show_bytes 91 options of pprof control how the information is presented. 92 93 The following flags are recognized by the 'go test' command and 94 control the execution of any test: 95 96 -bench regexp 97 Run benchmarks matching the regular expression. 98 By default, no benchmarks run. To run all benchmarks, 99 use '-bench .' or '-bench=.'. 100 101 -benchmem 102 Print memory allocation statistics for benchmarks. 103 104 -benchtime t 105 Run enough iterations of each benchmark to take t, specified 106 as a time.Duration (for example, -benchtime 1h30s). 107 The default is 1 second (1s). 108 109 -blockprofile block.out 110 Write a goroutine blocking profile to the specified file 111 when all tests are complete. 112 113 -blockprofilerate n 114 Control the detail provided in goroutine blocking profiles by 115 calling runtime.SetBlockProfileRate with n. 116 See 'godoc runtime SetBlockProfileRate'. 117 The profiler aims to sample, on average, one blocking event every 118 n nanoseconds the program spends blocked. By default, 119 if -test.blockprofile is set without this flag, all blocking events 120 are recorded, equivalent to -test.blockprofilerate=1. 121 122 -cpu 1,2,4 123 Specify a list of GOMAXPROCS values for which the tests or 124 benchmarks should be executed. The default is the current value 125 of GOMAXPROCS. 126 127 -cpuprofile cpu.out 128 Write a CPU profile to the specified file before exiting. 129 130 -memprofile mem.out 131 Write a memory profile to the specified file after all tests 132 have passed. 133 134 -memprofilerate n 135 Enable more precise (and expensive) memory profiles by setting 136 runtime.MemProfileRate. See 'godoc runtime MemProfileRate'. 137 To profile all memory allocations, use -test.memprofilerate=1 138 and set the environment variable GOGC=off to disable the 139 garbage collector, provided the test can run in the available 140 memory without garbage collection. 141 142 -parallel n 143 Allow parallel execution of test functions that call t.Parallel. 144 The value of this flag is the maximum number of tests to run 145 simultaneously; by default, it is set to the value of GOMAXPROCS. 146 147 -run regexp 148 Run only those tests and examples matching the regular 149 expression. 150 151 -short 152 Tell long-running tests to shorten their run time. 153 It is off by default but set during all.bash so that installing 154 the Go tree can run a sanity check but not spend time running 155 exhaustive tests. 156 157 -timeout t 158 If a test runs longer than t, panic. 159 160 -v 161 Verbose output: log all tests as they are run. Also print all 162 text from Log and Logf calls even if the test succeeds. 163 164 The test binary, called pkg.test where pkg is the name of the 165 directory containing the package sources, can be invoked directly 166 after building it with 'go test -c'. When invoking the test binary 167 directly, each of the standard flag names must be prefixed with 'test.', 168 as in -test.run=TestMyFunc or -test.v. 169 170 When running 'go test', flags not listed above are passed through 171 unaltered. For instance, the command 172 173 go test -x -v -cpuprofile=prof.out -dir=testdata -update 174 175 will compile the test binary and then run it as 176 177 pkg.test -test.v -test.cpuprofile=prof.out -dir=testdata -update 178 179 The test flags that generate profiles also leave the test binary in pkg.test 180 for use when analyzing the profiles. 181 182 Flags not recognized by 'go test' must be placed after any specified packages. 183 `, 184 } 185 186 var helpTestfunc = &Command{ 187 UsageLine: "testfunc", 188 Short: "description of testing functions", 189 Long: ` 190 The 'go test' command expects to find test, benchmark, and example functions 191 in the "*_test.go" files corresponding to the package under test. 192 193 A test function is one named TestXXX (where XXX is any alphanumeric string 194 not starting with a lower case letter) and should have the signature, 195 196 func TestXXX(t *testing.T) { ... } 197 198 A benchmark function is one named BenchmarkXXX and should have the signature, 199 200 func BenchmarkXXX(b *testing.B) { ... } 201 202 An example function is similar to a test function but, instead of using 203 *testing.T to report success or failure, prints output to os.Stdout. 204 That output is compared against the function's "Output:" comment, which 205 must be the last comment in the function body (see example below). An 206 example with no such comment, or with no text after "Output:" is compiled 207 but not executed. 208 209 Godoc displays the body of ExampleXXX to demonstrate the use 210 of the function, constant, or variable XXX. An example of a method M with 211 receiver type T or *T is named ExampleT_M. There may be multiple examples 212 for a given function, constant, or variable, distinguished by a trailing _xxx, 213 where xxx is a suffix not beginning with an upper case letter. 214 215 Here is an example of an example: 216 217 func ExamplePrintln() { 218 Println("The output of\nthis example.") 219 // Output: The output of 220 // this example. 221 } 222 223 The entire test file is presented as the example when it contains a single 224 example function, at least one other function, type, variable, or constant 225 declaration, and no test or benchmark functions. 226 227 See the documentation of the testing package for more information. 228 `, 229 } 230 231 var ( 232 testC bool // -c flag 233 testProfile bool // some profiling flag 234 testI bool // -i flag 235 testV bool // -v flag 236 testFiles []string // -file flag(s) TODO: not respected 237 testTimeout string // -timeout flag 238 testArgs []string 239 testBench bool 240 testStreamOutput bool // show output as it is generated 241 testShowPass bool // show passing output 242 243 testKillTimeout = 10 * time.Minute 244 ) 245 246 func runTest(cmd *Command, args []string) { 247 var pkgArgs []string 248 pkgArgs, testArgs = testFlags(args) 249 250 raceInit() 251 pkgs := packagesForBuild(pkgArgs) 252 if len(pkgs) == 0 { 253 fatalf("no packages to test") 254 } 255 256 if testC && len(pkgs) != 1 { 257 fatalf("cannot use -c flag with multiple packages") 258 } 259 if testProfile && len(pkgs) != 1 { 260 fatalf("cannot use test profile flag with multiple packages") 261 } 262 263 // If a test timeout was given and is parseable, set our kill timeout 264 // to that timeout plus one minute. This is a backup alarm in case 265 // the test wedges with a goroutine spinning and its background 266 // timer does not get a chance to fire. 267 if dt, err := time.ParseDuration(testTimeout); err == nil && dt > 0 { 268 testKillTimeout = dt + 1*time.Minute 269 } 270 271 // show passing test output (after buffering) with -v flag. 272 // must buffer because tests are running in parallel, and 273 // otherwise the output will get mixed. 274 testShowPass = testV 275 276 // stream test output (no buffering) when no package has 277 // been given on the command line (implicit current directory) 278 // or when benchmarking. 279 // Also stream if we're showing output anyway with a 280 // single package under test. In that case, streaming the 281 // output produces the same result as not streaming, 282 // just more immediately. 283 testStreamOutput = len(pkgArgs) == 0 || testBench || 284 (len(pkgs) <= 1 && testShowPass) 285 286 var b builder 287 b.init() 288 289 if testI { 290 buildV = testV 291 292 deps := map[string]bool{ 293 // Dependencies for testmain. 294 "testing": true, 295 "regexp": true, 296 } 297 for _, p := range pkgs { 298 // Dependencies for each test. 299 for _, path := range p.Imports { 300 deps[path] = true 301 } 302 for _, path := range p.TestImports { 303 deps[path] = true 304 } 305 for _, path := range p.XTestImports { 306 deps[path] = true 307 } 308 } 309 310 // translate C to runtime/cgo 311 if deps["C"] { 312 delete(deps, "C") 313 deps["runtime/cgo"] = true 314 if buildContext.GOOS == runtime.GOOS && buildContext.GOARCH == runtime.GOARCH { 315 deps["cmd/cgo"] = true 316 } 317 } 318 // Ignore pseudo-packages. 319 delete(deps, "unsafe") 320 321 all := []string{} 322 for path := range deps { 323 if !build.IsLocalImport(path) { 324 all = append(all, path) 325 } 326 } 327 sort.Strings(all) 328 329 a := &action{} 330 for _, p := range packagesForBuild(all) { 331 a.deps = append(a.deps, b.action(modeInstall, modeInstall, p)) 332 } 333 b.do(a) 334 if !testC { 335 return 336 } 337 b.init() 338 } 339 340 var builds, runs, prints []*action 341 342 // Prepare build + run + print actions for all packages being tested. 343 for _, p := range pkgs { 344 buildTest, runTest, printTest, err := b.test(p) 345 if err != nil { 346 str := err.Error() 347 if strings.HasPrefix(str, "\n") { 348 str = str[1:] 349 } 350 if p.ImportPath != "" { 351 errorf("# %s\n%s", p.ImportPath, str) 352 } else { 353 errorf("%s", str) 354 } 355 continue 356 } 357 builds = append(builds, buildTest) 358 runs = append(runs, runTest) 359 prints = append(prints, printTest) 360 } 361 362 // Ultimately the goal is to print the output. 363 root := &action{deps: prints} 364 365 // Force the printing of results to happen in order, 366 // one at a time. 367 for i, a := range prints { 368 if i > 0 { 369 a.deps = append(a.deps, prints[i-1]) 370 } 371 } 372 373 // If we are benchmarking, force everything to 374 // happen in serial. Could instead allow all the 375 // builds to run before any benchmarks start, 376 // but try this for now. 377 if testBench { 378 for i, a := range builds { 379 if i > 0 { 380 // Make build of test i depend on 381 // completing the run of test i-1. 382 a.deps = append(a.deps, runs[i-1]) 383 } 384 } 385 } 386 387 // If we are building any out-of-date packages other 388 // than those under test, warn. 389 okBuild := map[*Package]bool{} 390 for _, p := range pkgs { 391 okBuild[p] = true 392 } 393 394 warned := false 395 for _, a := range actionList(root) { 396 if a.p != nil && a.f != nil && !okBuild[a.p] && !a.p.fake && !a.p.local { 397 okBuild[a.p] = true // don't warn again 398 if !warned { 399 fmt.Fprintf(os.Stderr, "warning: building out-of-date packages:\n") 400 warned = true 401 } 402 fmt.Fprintf(os.Stderr, "\t%s\n", a.p.ImportPath) 403 } 404 } 405 if warned { 406 args := strings.Join(pkgArgs, " ") 407 if args != "" { 408 args = " " + args 409 } 410 extraOpts := "" 411 if buildRace { 412 extraOpts = "-race " 413 } 414 fmt.Fprintf(os.Stderr, "installing these packages with 'go test %s-i%s' will speed future tests.\n\n", extraOpts, args) 415 } 416 417 b.do(root) 418 } 419 420 func (b *builder) test(p *Package) (buildAction, runAction, printAction *action, err error) { 421 if len(p.TestGoFiles)+len(p.XTestGoFiles) == 0 { 422 build := &action{p: p} 423 run := &action{p: p} 424 print := &action{f: (*builder).notest, p: p, deps: []*action{build}} 425 return build, run, print, nil 426 } 427 428 // Build Package structs describing: 429 // ptest - package + test files 430 // pxtest - package of external test files 431 // pmain - pkg.test binary 432 var ptest, pxtest, pmain *Package 433 434 var imports, ximports []*Package 435 var stk importStack 436 stk.push(p.ImportPath + "_test") 437 for _, path := range p.TestImports { 438 p1 := loadImport(path, p.Dir, &stk, p.build.TestImportPos[path]) 439 if p1.Error != nil { 440 return nil, nil, nil, p1.Error 441 } 442 imports = append(imports, p1) 443 } 444 for _, path := range p.XTestImports { 445 if path == p.ImportPath { 446 continue 447 } 448 p1 := loadImport(path, p.Dir, &stk, p.build.XTestImportPos[path]) 449 if p1.Error != nil { 450 return nil, nil, nil, p1.Error 451 } 452 ximports = append(ximports, p1) 453 } 454 stk.pop() 455 456 // Use last element of import path, not package name. 457 // They differ when package name is "main". 458 // But if the import path is "command-line-arguments", 459 // like it is during 'go run', use the package name. 460 var elem string 461 if p.ImportPath == "command-line-arguments" { 462 elem = p.Name 463 } else { 464 _, elem = path.Split(p.ImportPath) 465 } 466 testBinary := elem + ".test" 467 468 // The ptest package needs to be importable under the 469 // same import path that p has, but we cannot put it in 470 // the usual place in the temporary tree, because then 471 // other tests will see it as the real package. 472 // Instead we make a _test directory under the import path 473 // and then repeat the import path there. We tell the 474 // compiler and linker to look in that _test directory first. 475 // 476 // That is, if the package under test is unicode/utf8, 477 // then the normal place to write the package archive is 478 // $WORK/unicode/utf8.a, but we write the test package archive to 479 // $WORK/unicode/utf8/_test/unicode/utf8.a. 480 // We write the external test package archive to 481 // $WORK/unicode/utf8/_test/unicode/utf8_test.a. 482 testDir := filepath.Join(b.work, filepath.FromSlash(p.ImportPath+"/_test")) 483 ptestObj := buildToolchain.pkgpath(testDir, p) 484 485 // Create the directory for the .a files. 486 ptestDir, _ := filepath.Split(ptestObj) 487 if err := b.mkdir(ptestDir); err != nil { 488 return nil, nil, nil, err 489 } 490 if err := writeTestmain(filepath.Join(testDir, "_testmain.go"), p); err != nil { 491 return nil, nil, nil, err 492 } 493 494 // Test package. 495 if len(p.TestGoFiles) > 0 { 496 ptest = new(Package) 497 *ptest = *p 498 ptest.GoFiles = nil 499 ptest.GoFiles = append(ptest.GoFiles, p.GoFiles...) 500 ptest.GoFiles = append(ptest.GoFiles, p.TestGoFiles...) 501 ptest.target = "" 502 ptest.Imports = stringList(p.Imports, p.TestImports) 503 ptest.imports = append(append([]*Package{}, p.imports...), imports...) 504 ptest.pkgdir = testDir 505 ptest.fake = true 506 ptest.forceLibrary = true 507 ptest.Stale = true 508 ptest.build = new(build.Package) 509 *ptest.build = *p.build 510 m := map[string][]token.Position{} 511 for k, v := range p.build.ImportPos { 512 m[k] = append(m[k], v...) 513 } 514 for k, v := range p.build.TestImportPos { 515 m[k] = append(m[k], v...) 516 } 517 ptest.build.ImportPos = m 518 } else { 519 ptest = p 520 } 521 522 // External test package. 523 if len(p.XTestGoFiles) > 0 { 524 pxtest = &Package{ 525 Name: p.Name + "_test", 526 ImportPath: p.ImportPath + "_test", 527 localPrefix: p.localPrefix, 528 Root: p.Root, 529 Dir: p.Dir, 530 GoFiles: p.XTestGoFiles, 531 Imports: p.XTestImports, 532 build: &build.Package{ 533 ImportPos: p.build.XTestImportPos, 534 }, 535 imports: append(ximports, ptest), 536 pkgdir: testDir, 537 fake: true, 538 Stale: true, 539 } 540 } 541 542 // Action for building pkg.test. 543 pmain = &Package{ 544 Name: "main", 545 Dir: testDir, 546 GoFiles: []string{"_testmain.go"}, 547 ImportPath: "testmain", 548 Root: p.Root, 549 imports: []*Package{ptest}, 550 build: &build.Package{Name: "main"}, 551 fake: true, 552 Stale: true, 553 } 554 if pxtest != nil { 555 pmain.imports = append(pmain.imports, pxtest) 556 } 557 558 // The generated main also imports testing and regexp. 559 stk.push("testmain") 560 ptesting := loadImport("testing", "", &stk, nil) 561 if ptesting.Error != nil { 562 return nil, nil, nil, ptesting.Error 563 } 564 pregexp := loadImport("regexp", "", &stk, nil) 565 if pregexp.Error != nil { 566 return nil, nil, nil, pregexp.Error 567 } 568 pmain.imports = append(pmain.imports, ptesting, pregexp) 569 computeStale(pmain) 570 571 if ptest != p { 572 a := b.action(modeBuild, modeBuild, ptest) 573 a.objdir = testDir + string(filepath.Separator) 574 a.objpkg = ptestObj 575 a.target = ptestObj 576 a.link = false 577 } 578 579 if pxtest != nil { 580 a := b.action(modeBuild, modeBuild, pxtest) 581 a.objdir = testDir + string(filepath.Separator) 582 a.objpkg = buildToolchain.pkgpath(testDir, pxtest) 583 a.target = a.objpkg 584 } 585 586 a := b.action(modeBuild, modeBuild, pmain) 587 a.objdir = testDir + string(filepath.Separator) 588 a.objpkg = filepath.Join(testDir, "main.a") 589 a.target = filepath.Join(testDir, testBinary) + exeSuffix 590 pmainAction := a 591 592 if testC || testProfile { 593 // -c or profiling flag: create action to copy binary to ./test.out. 594 runAction = &action{ 595 f: (*builder).install, 596 deps: []*action{pmainAction}, 597 p: pmain, 598 target: filepath.Join(cwd, testBinary+exeSuffix), 599 } 600 pmainAction = runAction // in case we are running the test 601 } 602 if testC { 603 printAction = &action{p: p, deps: []*action{runAction}} // nop 604 } else { 605 // run test 606 runAction = &action{ 607 f: (*builder).runTest, 608 deps: []*action{pmainAction}, 609 p: p, 610 ignoreFail: true, 611 } 612 cleanAction := &action{ 613 f: (*builder).cleanTest, 614 deps: []*action{runAction}, 615 p: p, 616 } 617 printAction = &action{ 618 f: (*builder).printTest, 619 deps: []*action{cleanAction}, 620 p: p, 621 } 622 } 623 624 return pmainAction, runAction, printAction, nil 625 } 626 627 // runTest is the action for running a test binary. 628 func (b *builder) runTest(a *action) error { 629 args := stringList(a.deps[0].target, testArgs) 630 a.testOutput = new(bytes.Buffer) 631 632 if buildN || buildX { 633 b.showcmd("", "%s", strings.Join(args, " ")) 634 if buildN { 635 return nil 636 } 637 } 638 639 if a.failed { 640 // We were unable to build the binary. 641 a.failed = false 642 fmt.Fprintf(a.testOutput, "FAIL\t%s [build failed]\n", a.p.ImportPath) 643 setExitStatus(1) 644 return nil 645 } 646 647 cmd := exec.Command(args[0], args[1:]...) 648 cmd.Dir = a.p.Dir 649 cmd.Env = envForDir(cmd.Dir) 650 var buf bytes.Buffer 651 if testStreamOutput { 652 cmd.Stdout = os.Stdout 653 cmd.Stderr = os.Stderr 654 } else { 655 cmd.Stdout = &buf 656 cmd.Stderr = &buf 657 } 658 659 // If there are any local SWIG dependencies, we want to load 660 // the shared library from the build directory. 661 if a.p.usesSwig() { 662 env := cmd.Env 663 found := false 664 prefix := "LD_LIBRARY_PATH=" 665 for i, v := range env { 666 if strings.HasPrefix(v, prefix) { 667 env[i] = v + ":." 668 found = true 669 break 670 } 671 } 672 if !found { 673 env = append(env, "LD_LIBRARY_PATH=.") 674 } 675 cmd.Env = env 676 } 677 678 t0 := time.Now() 679 err := cmd.Start() 680 681 // This is a last-ditch deadline to detect and 682 // stop wedged test binaries, to keep the builders 683 // running. 684 if err == nil { 685 tick := time.NewTimer(testKillTimeout) 686 startSigHandlers() 687 done := make(chan error) 688 go func() { 689 done <- cmd.Wait() 690 }() 691 select { 692 case err = <-done: 693 // ok 694 case <-tick.C: 695 cmd.Process.Kill() 696 err = <-done 697 fmt.Fprintf(&buf, "*** Test killed: ran too long (%v).\n", testKillTimeout) 698 } 699 tick.Stop() 700 } 701 out := buf.Bytes() 702 t := fmt.Sprintf("%.3fs", time.Since(t0).Seconds()) 703 if err == nil { 704 if testShowPass { 705 a.testOutput.Write(out) 706 } 707 fmt.Fprintf(a.testOutput, "ok \t%s\t%s\n", a.p.ImportPath, t) 708 return nil 709 } 710 711 setExitStatus(1) 712 if len(out) > 0 { 713 a.testOutput.Write(out) 714 // assume printing the test binary's exit status is superfluous 715 } else { 716 fmt.Fprintf(a.testOutput, "%s\n", err) 717 } 718 fmt.Fprintf(a.testOutput, "FAIL\t%s\t%s\n", a.p.ImportPath, t) 719 720 return nil 721 } 722 723 // cleanTest is the action for cleaning up after a test. 724 func (b *builder) cleanTest(a *action) error { 725 if buildWork { 726 return nil 727 } 728 run := a.deps[0] 729 testDir := filepath.Join(b.work, filepath.FromSlash(run.p.ImportPath+"/_test")) 730 os.RemoveAll(testDir) 731 return nil 732 } 733 734 // printTest is the action for printing a test result. 735 func (b *builder) printTest(a *action) error { 736 clean := a.deps[0] 737 run := clean.deps[0] 738 os.Stdout.Write(run.testOutput.Bytes()) 739 run.testOutput = nil 740 return nil 741 } 742 743 // notest is the action for testing a package with no test files. 744 func (b *builder) notest(a *action) error { 745 fmt.Printf("? \t%s\t[no test files]\n", a.p.ImportPath) 746 return nil 747 } 748 749 // isTest tells whether name looks like a test (or benchmark, according to prefix). 750 // It is a Test (say) if there is a character after Test that is not a lower-case letter. 751 // We don't want TesticularCancer. 752 func isTest(name, prefix string) bool { 753 if !strings.HasPrefix(name, prefix) { 754 return false 755 } 756 if len(name) == len(prefix) { // "Test" is ok 757 return true 758 } 759 rune, _ := utf8.DecodeRuneInString(name[len(prefix):]) 760 return !unicode.IsLower(rune) 761 } 762 763 // writeTestmain writes the _testmain.go file for package p to 764 // the file named out. 765 func writeTestmain(out string, p *Package) error { 766 t := &testFuncs{ 767 Package: p, 768 } 769 for _, file := range p.TestGoFiles { 770 if err := t.load(filepath.Join(p.Dir, file), "_test", &t.NeedTest); err != nil { 771 return err 772 } 773 } 774 for _, file := range p.XTestGoFiles { 775 if err := t.load(filepath.Join(p.Dir, file), "_xtest", &t.NeedXtest); err != nil { 776 return err 777 } 778 } 779 780 f, err := os.Create(out) 781 if err != nil { 782 return err 783 } 784 defer f.Close() 785 786 if err := testmainTmpl.Execute(f, t); err != nil { 787 return err 788 } 789 790 return nil 791 } 792 793 type testFuncs struct { 794 Tests []testFunc 795 Benchmarks []testFunc 796 Examples []testFunc 797 Package *Package 798 NeedTest bool 799 NeedXtest bool 800 } 801 802 type testFunc struct { 803 Package string // imported package name (_test or _xtest) 804 Name string // function name 805 Output string // output, for examples 806 } 807 808 var testFileSet = token.NewFileSet() 809 810 func (t *testFuncs) load(filename, pkg string, seen *bool) error { 811 f, err := parser.ParseFile(testFileSet, filename, nil, parser.ParseComments) 812 if err != nil { 813 return expandScanner(err) 814 } 815 for _, d := range f.Decls { 816 n, ok := d.(*ast.FuncDecl) 817 if !ok { 818 continue 819 } 820 if n.Recv != nil { 821 continue 822 } 823 name := n.Name.String() 824 switch { 825 case isTest(name, "Test"): 826 t.Tests = append(t.Tests, testFunc{pkg, name, ""}) 827 *seen = true 828 case isTest(name, "Benchmark"): 829 t.Benchmarks = append(t.Benchmarks, testFunc{pkg, name, ""}) 830 *seen = true 831 } 832 } 833 ex := doc.Examples(f) 834 sort.Sort(byOrder(ex)) 835 for _, e := range ex { 836 if e.Output == "" && !e.EmptyOutput { 837 // Don't run examples with no output. 838 continue 839 } 840 t.Examples = append(t.Examples, testFunc{pkg, "Example" + e.Name, e.Output}) 841 *seen = true 842 } 843 return nil 844 } 845 846 type byOrder []*doc.Example 847 848 func (x byOrder) Len() int { return len(x) } 849 func (x byOrder) Swap(i, j int) { x[i], x[j] = x[j], x[i] } 850 func (x byOrder) Less(i, j int) bool { return x[i].Order < x[j].Order } 851 852 var testmainTmpl = template.Must(template.New("main").Parse(` 853 package main 854 855 import ( 856 "regexp" 857 "testing" 858 859 {{if .NeedTest}} 860 _test {{.Package.ImportPath | printf "%q"}} 861 {{end}} 862 {{if .NeedXtest}} 863 _xtest {{.Package.ImportPath | printf "%s_test" | printf "%q"}} 864 {{end}} 865 ) 866 867 var tests = []testing.InternalTest{ 868 {{range .Tests}} 869 {"{{.Name}}", {{.Package}}.{{.Name}}}, 870 {{end}} 871 } 872 873 var benchmarks = []testing.InternalBenchmark{ 874 {{range .Benchmarks}} 875 {"{{.Name}}", {{.Package}}.{{.Name}}}, 876 {{end}} 877 } 878 879 var examples = []testing.InternalExample{ 880 {{range .Examples}} 881 {"{{.Name}}", {{.Package}}.{{.Name}}, {{.Output | printf "%q"}}}, 882 {{end}} 883 } 884 885 var matchPat string 886 var matchRe *regexp.Regexp 887 888 func matchString(pat, str string) (result bool, err error) { 889 if matchRe == nil || matchPat != pat { 890 matchPat = pat 891 matchRe, err = regexp.Compile(matchPat) 892 if err != nil { 893 return 894 } 895 } 896 return matchRe.MatchString(str), nil 897 } 898 899 func main() { 900 testing.Main(matchString, tests, benchmarks, examples) 901 } 902 903 `))