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  `))