Black Lives Matter. Support the Equal Justice Initiative.

Source file src/cmd/go/internal/test/test.go

Documentation: cmd/go/internal/test

     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  	"context"
    10  	"crypto/sha256"
    11  	"errors"
    12  	"fmt"
    13  	"go/build"
    14  	exec "internal/execabs"
    15  	"io"
    16  	"io/fs"
    17  	"os"
    18  	"path"
    19  	"path/filepath"
    20  	"regexp"
    21  	"sort"
    22  	"strconv"
    23  	"strings"
    24  	"sync"
    25  	"time"
    26  
    27  	"cmd/go/internal/base"
    28  	"cmd/go/internal/cache"
    29  	"cmd/go/internal/cfg"
    30  	"cmd/go/internal/load"
    31  	"cmd/go/internal/lockedfile"
    32  	"cmd/go/internal/search"
    33  	"cmd/go/internal/str"
    34  	"cmd/go/internal/trace"
    35  	"cmd/go/internal/work"
    36  	"cmd/internal/test2json"
    37  )
    38  
    39  // Break init loop.
    40  func init() {
    41  	CmdTest.Run = runTest
    42  }
    43  
    44  const testUsage = "go test [build/test flags] [packages] [build/test flags & test binary flags]"
    45  
    46  var CmdTest = &base.Command{
    47  	CustomFlags: true,
    48  	UsageLine:   testUsage,
    49  	Short:       "test packages",
    50  	Long: `
    51  'Go test' automates testing the packages named by the import paths.
    52  It prints a summary of the test results in the format:
    53  
    54  	ok   archive/tar   0.011s
    55  	FAIL archive/zip   0.022s
    56  	ok   compress/gzip 0.033s
    57  	...
    58  
    59  followed by detailed output for each failed package.
    60  
    61  'Go test' recompiles each package along with any files with names matching
    62  the file pattern "*_test.go".
    63  These additional files can contain test functions, benchmark functions, and
    64  example functions. See 'go help testfunc' for more.
    65  Each listed package causes the execution of a separate test binary.
    66  Files whose names begin with "_" (including "_test.go") or "." are ignored.
    67  
    68  Test files that declare a package with the suffix "_test" will be compiled as a
    69  separate package, and then linked and run with the main test binary.
    70  
    71  The go tool will ignore a directory named "testdata", making it available
    72  to hold ancillary data needed by the tests.
    73  
    74  As part of building a test binary, go test runs go vet on the package
    75  and its test source files to identify significant problems. If go vet
    76  finds any problems, go test reports those and does not run the test
    77  binary. Only a high-confidence subset of the default go vet checks are
    78  used. That subset is: 'atomic', 'bool', 'buildtags', 'errorsas',
    79  'ifaceassert', 'nilfunc', 'printf', and 'stringintconv'. You can see
    80  the documentation for these and other vet tests via "go doc cmd/vet".
    81  To disable the running of go vet, use the -vet=off flag.
    82  
    83  All test output and summary lines are printed to the go command's
    84  standard output, even if the test printed them to its own standard
    85  error. (The go command's standard error is reserved for printing
    86  errors building the tests.)
    87  
    88  Go test runs in two different modes:
    89  
    90  The first, called local directory mode, occurs when go test is
    91  invoked with no package arguments (for example, 'go test' or 'go
    92  test -v'). In this mode, go test compiles the package sources and
    93  tests found in the current directory and then runs the resulting
    94  test binary. In this mode, caching (discussed below) is disabled.
    95  After the package test finishes, go test prints a summary line
    96  showing the test status ('ok' or 'FAIL'), package name, and elapsed
    97  time.
    98  
    99  The second, called package list mode, occurs when go test is invoked
   100  with explicit package arguments (for example 'go test math', 'go
   101  test ./...', and even 'go test .'). In this mode, go test compiles
   102  and tests each of the packages listed on the command line. If a
   103  package test passes, go test prints only the final 'ok' summary
   104  line. If a package test fails, go test prints the full test output.
   105  If invoked with the -bench or -v flag, go test prints the full
   106  output even for passing package tests, in order to display the
   107  requested benchmark results or verbose logging. After the package
   108  tests for all of the listed packages finish, and their output is
   109  printed, go test prints a final 'FAIL' status if any package test
   110  has failed.
   111  
   112  In package list mode only, go test caches successful package test
   113  results to avoid unnecessary repeated running of tests. When the
   114  result of a test can be recovered from the cache, go test will
   115  redisplay the previous output instead of running the test binary
   116  again. When this happens, go test prints '(cached)' in place of the
   117  elapsed time in the summary line.
   118  
   119  The rule for a match in the cache is that the run involves the same
   120  test binary and the flags on the command line come entirely from a
   121  restricted set of 'cacheable' test flags, defined as -benchtime, -cpu,
   122  -list, -parallel, -run, -short, and -v. If a run of go test has any test
   123  or non-test flags outside this set, the result is not cached. To
   124  disable test caching, use any test flag or argument other than the
   125  cacheable flags. The idiomatic way to disable test caching explicitly
   126  is to use -count=1. Tests that open files within the package's source
   127  root (usually $GOPATH) or that consult environment variables only
   128  match future runs in which the files and environment variables are unchanged.
   129  A cached test result is treated as executing in no time at all,
   130  so a successful package test result will be cached and reused
   131  regardless of -timeout setting.
   132  
   133  In addition to the build flags, the flags handled by 'go test' itself are:
   134  
   135  	-args
   136  	    Pass the remainder of the command line (everything after -args)
   137  	    to the test binary, uninterpreted and unchanged.
   138  	    Because this flag consumes the remainder of the command line,
   139  	    the package list (if present) must appear before this flag.
   140  
   141  	-c
   142  	    Compile the test binary to pkg.test but do not run it
   143  	    (where pkg is the last element of the package's import path).
   144  	    The file name can be changed with the -o flag.
   145  
   146  	-exec xprog
   147  	    Run the test binary using xprog. The behavior is the same as
   148  	    in 'go run'. See 'go help run' for details.
   149  
   150  	-i
   151  	    Install packages that are dependencies of the test.
   152  	    Do not run the test.
   153  	    The -i flag is deprecated. Compiled packages are cached automatically.
   154  
   155  	-json
   156  	    Convert test output to JSON suitable for automated processing.
   157  	    See 'go doc test2json' for the encoding details.
   158  
   159  	-o file
   160  	    Compile the test binary to the named file.
   161  	    The test still runs (unless -c or -i is specified).
   162  
   163  The test binary also accepts flags that control execution of the test; these
   164  flags are also accessible by 'go test'. See 'go help testflag' for details.
   165  
   166  For more about build flags, see 'go help build'.
   167  For more about specifying packages, see 'go help packages'.
   168  
   169  See also: go build, go vet.
   170  `,
   171  }
   172  
   173  var HelpTestflag = &base.Command{
   174  	UsageLine: "testflag",
   175  	Short:     "testing flags",
   176  	Long: `
   177  The 'go test' command takes both flags that apply to 'go test' itself
   178  and flags that apply to the resulting test binary.
   179  
   180  Several of the flags control profiling and write an execution profile
   181  suitable for "go tool pprof"; run "go tool pprof -h" for more
   182  information. The --alloc_space, --alloc_objects, and --show_bytes
   183  options of pprof control how the information is presented.
   184  
   185  The following flags are recognized by the 'go test' command and
   186  control the execution of any test:
   187  
   188  	-bench regexp
   189  	    Run only those benchmarks matching a regular expression.
   190  	    By default, no benchmarks are run.
   191  	    To run all benchmarks, use '-bench .' or '-bench=.'.
   192  	    The regular expression is split by unbracketed slash (/)
   193  	    characters into a sequence of regular expressions, and each
   194  	    part of a benchmark's identifier must match the corresponding
   195  	    element in the sequence, if any. Possible parents of matches
   196  	    are run with b.N=1 to identify sub-benchmarks. For example,
   197  	    given -bench=X/Y, top-level benchmarks matching X are run
   198  	    with b.N=1 to find any sub-benchmarks matching Y, which are
   199  	    then run in full.
   200  
   201  	-benchtime t
   202  	    Run enough iterations of each benchmark to take t, specified
   203  	    as a time.Duration (for example, -benchtime 1h30s).
   204  	    The default is 1 second (1s).
   205  	    The special syntax Nx means to run the benchmark N times
   206  	    (for example, -benchtime 100x).
   207  
   208  	-count n
   209  	    Run each test and benchmark n times (default 1).
   210  	    If -cpu is set, run n times for each GOMAXPROCS value.
   211  	    Examples are always run once.
   212  
   213  	-cover
   214  	    Enable coverage analysis.
   215  	    Note that because coverage works by annotating the source
   216  	    code before compilation, compilation and test failures with
   217  	    coverage enabled may report line numbers that don't correspond
   218  	    to the original sources.
   219  
   220  	-covermode set,count,atomic
   221  	    Set the mode for coverage analysis for the package[s]
   222  	    being tested. The default is "set" unless -race is enabled,
   223  	    in which case it is "atomic".
   224  	    The values:
   225  		set: bool: does this statement run?
   226  		count: int: how many times does this statement run?
   227  		atomic: int: count, but correct in multithreaded tests;
   228  			significantly more expensive.
   229  	    Sets -cover.
   230  
   231  	-coverpkg pattern1,pattern2,pattern3
   232  	    Apply coverage analysis in each test to packages matching the patterns.
   233  	    The default is for each test to analyze only the package being tested.
   234  	    See 'go help packages' for a description of package patterns.
   235  	    Sets -cover.
   236  
   237  	-cpu 1,2,4
   238  	    Specify a list of GOMAXPROCS values for which the tests or
   239  	    benchmarks should be executed. The default is the current value
   240  	    of GOMAXPROCS.
   241  
   242  	-failfast
   243  	    Do not start new tests after the first test failure.
   244  
   245  	-list regexp
   246  	    List tests, benchmarks, or examples matching the regular expression.
   247  	    No tests, benchmarks or examples will be run. This will only
   248  	    list top-level tests. No subtest or subbenchmarks will be shown.
   249  
   250  	-parallel n
   251  	    Allow parallel execution of test functions that call t.Parallel.
   252  	    The value of this flag is the maximum number of tests to run
   253  	    simultaneously; by default, it is set to the value of GOMAXPROCS.
   254  	    Note that -parallel only applies within a single test binary.
   255  	    The 'go test' command may run tests for different packages
   256  	    in parallel as well, according to the setting of the -p flag
   257  	    (see 'go help build').
   258  
   259  	-run regexp
   260  	    Run only those tests and examples matching the regular expression.
   261  	    For tests, the regular expression is split by unbracketed slash (/)
   262  	    characters into a sequence of regular expressions, and each part
   263  	    of a test's identifier must match the corresponding element in
   264  	    the sequence, if any. Note that possible parents of matches are
   265  	    run too, so that -run=X/Y matches and runs and reports the result
   266  	    of all tests matching X, even those without sub-tests matching Y,
   267  	    because it must run them to look for those sub-tests.
   268  
   269  	-short
   270  	    Tell long-running tests to shorten their run time.
   271  	    It is off by default but set during all.bash so that installing
   272  	    the Go tree can run a sanity check but not spend time running
   273  	    exhaustive tests.
   274  
   275  	-shuffle off,on,N
   276  		Randomize the execution order of tests and benchmarks.
   277  		It is off by default. If -shuffle is set to on, then it will seed
   278  		the randomizer using the system clock. If -shuffle is set to an
   279  		integer N, then N will be used as the seed value. In both cases,
   280  		the seed will be reported for reproducibility.
   281  
   282  	-timeout d
   283  	    If a test binary runs longer than duration d, panic.
   284  	    If d is 0, the timeout is disabled.
   285  	    The default is 10 minutes (10m).
   286  
   287  	-v
   288  	    Verbose output: log all tests as they are run. Also print all
   289  	    text from Log and Logf calls even if the test succeeds.
   290  
   291  	-vet list
   292  	    Configure the invocation of "go vet" during "go test"
   293  	    to use the comma-separated list of vet checks.
   294  	    If list is empty, "go test" runs "go vet" with a curated list of
   295  	    checks believed to be always worth addressing.
   296  	    If list is "off", "go test" does not run "go vet" at all.
   297  
   298  The following flags are also recognized by 'go test' and can be used to
   299  profile the tests during execution:
   300  
   301  	-benchmem
   302  	    Print memory allocation statistics for benchmarks.
   303  
   304  	-blockprofile block.out
   305  	    Write a goroutine blocking profile to the specified file
   306  	    when all tests are complete.
   307  	    Writes test binary as -c would.
   308  
   309  	-blockprofilerate n
   310  	    Control the detail provided in goroutine blocking profiles by
   311  	    calling runtime.SetBlockProfileRate with n.
   312  	    See 'go doc runtime.SetBlockProfileRate'.
   313  	    The profiler aims to sample, on average, one blocking event every
   314  	    n nanoseconds the program spends blocked. By default,
   315  	    if -test.blockprofile is set without this flag, all blocking events
   316  	    are recorded, equivalent to -test.blockprofilerate=1.
   317  
   318  	-coverprofile cover.out
   319  	    Write a coverage profile to the file after all tests have passed.
   320  	    Sets -cover.
   321  
   322  	-cpuprofile cpu.out
   323  	    Write a CPU profile to the specified file before exiting.
   324  	    Writes test binary as -c would.
   325  
   326  	-memprofile mem.out
   327  	    Write an allocation profile to the file after all tests have passed.
   328  	    Writes test binary as -c would.
   329  
   330  	-memprofilerate n
   331  	    Enable more precise (and expensive) memory allocation profiles by
   332  	    setting runtime.MemProfileRate. See 'go doc runtime.MemProfileRate'.
   333  	    To profile all memory allocations, use -test.memprofilerate=1.
   334  
   335  	-mutexprofile mutex.out
   336  	    Write a mutex contention profile to the specified file
   337  	    when all tests are complete.
   338  	    Writes test binary as -c would.
   339  
   340  	-mutexprofilefraction n
   341  	    Sample 1 in n stack traces of goroutines holding a
   342  	    contended mutex.
   343  
   344  	-outputdir directory
   345  	    Place output files from profiling in the specified directory,
   346  	    by default the directory in which "go test" is running.
   347  
   348  	-trace trace.out
   349  	    Write an execution trace to the specified file before exiting.
   350  
   351  Each of these flags is also recognized with an optional 'test.' prefix,
   352  as in -test.v. When invoking the generated test binary (the result of
   353  'go test -c') directly, however, the prefix is mandatory.
   354  
   355  The 'go test' command rewrites or removes recognized flags,
   356  as appropriate, both before and after the optional package list,
   357  before invoking the test binary.
   358  
   359  For instance, the command
   360  
   361  	go test -v -myflag testdata -cpuprofile=prof.out -x
   362  
   363  will compile the test binary and then run it as
   364  
   365  	pkg.test -test.v -myflag testdata -test.cpuprofile=prof.out
   366  
   367  (The -x flag is removed because it applies only to the go command's
   368  execution, not to the test itself.)
   369  
   370  The test flags that generate profiles (other than for coverage) also
   371  leave the test binary in pkg.test for use when analyzing the profiles.
   372  
   373  When 'go test' runs a test binary, it does so from within the
   374  corresponding package's source code directory. Depending on the test,
   375  it may be necessary to do the same when invoking a generated test
   376  binary directly.
   377  
   378  The command-line package list, if present, must appear before any
   379  flag not known to the go test command. Continuing the example above,
   380  the package list would have to appear before -myflag, but could appear
   381  on either side of -v.
   382  
   383  When 'go test' runs in package list mode, 'go test' caches successful
   384  package test results to avoid unnecessary repeated running of tests. To
   385  disable test caching, use any test flag or argument other than the
   386  cacheable flags. The idiomatic way to disable test caching explicitly
   387  is to use -count=1.
   388  
   389  To keep an argument for a test binary from being interpreted as a
   390  known flag or a package name, use -args (see 'go help test') which
   391  passes the remainder of the command line through to the test binary
   392  uninterpreted and unaltered.
   393  
   394  For instance, the command
   395  
   396  	go test -v -args -x -v
   397  
   398  will compile the test binary and then run it as
   399  
   400  	pkg.test -test.v -x -v
   401  
   402  Similarly,
   403  
   404  	go test -args math
   405  
   406  will compile the test binary and then run it as
   407  
   408  	pkg.test math
   409  
   410  In the first example, the -x and the second -v are passed through to the
   411  test binary unchanged and with no effect on the go command itself.
   412  In the second example, the argument math is passed through to the test
   413  binary, instead of being interpreted as the package list.
   414  `,
   415  }
   416  
   417  var HelpTestfunc = &base.Command{
   418  	UsageLine: "testfunc",
   419  	Short:     "testing functions",
   420  	Long: `
   421  The 'go test' command expects to find test, benchmark, and example functions
   422  in the "*_test.go" files corresponding to the package under test.
   423  
   424  A test function is one named TestXxx (where Xxx does not start with a
   425  lower case letter) and should have the signature,
   426  
   427  	func TestXxx(t *testing.T) { ... }
   428  
   429  A benchmark function is one named BenchmarkXxx and should have the signature,
   430  
   431  	func BenchmarkXxx(b *testing.B) { ... }
   432  
   433  An example function is similar to a test function but, instead of using
   434  *testing.T to report success or failure, prints output to os.Stdout.
   435  If the last comment in the function starts with "Output:" then the output
   436  is compared exactly against the comment (see examples below). If the last
   437  comment begins with "Unordered output:" then the output is compared to the
   438  comment, however the order of the lines is ignored. An example with no such
   439  comment is compiled but not executed. An example with no text after
   440  "Output:" is compiled, executed, and expected to produce no output.
   441  
   442  Godoc displays the body of ExampleXxx to demonstrate the use
   443  of the function, constant, or variable Xxx. An example of a method M with
   444  receiver type T or *T is named ExampleT_M. There may be multiple examples
   445  for a given function, constant, or variable, distinguished by a trailing _xxx,
   446  where xxx is a suffix not beginning with an upper case letter.
   447  
   448  Here is an example of an example:
   449  
   450  	func ExamplePrintln() {
   451  		Println("The output of\nthis example.")
   452  		// Output: The output of
   453  		// this example.
   454  	}
   455  
   456  Here is another example where the ordering of the output is ignored:
   457  
   458  	func ExamplePerm() {
   459  		for _, value := range Perm(4) {
   460  			fmt.Println(value)
   461  		}
   462  
   463  		// Unordered output: 4
   464  		// 2
   465  		// 1
   466  		// 3
   467  		// 0
   468  	}
   469  
   470  The entire test file is presented as the example when it contains a single
   471  example function, at least one other function, type, variable, or constant
   472  declaration, and no test or benchmark functions.
   473  
   474  See the documentation of the testing package for more information.
   475  `,
   476  }
   477  
   478  var (
   479  	testBench        string                            // -bench flag
   480  	testC            bool                              // -c flag
   481  	testCover        bool                              // -cover flag
   482  	testCoverMode    string                            // -covermode flag
   483  	testCoverPaths   []string                          // -coverpkg flag
   484  	testCoverPkgs    []*load.Package                   // -coverpkg flag
   485  	testCoverProfile string                            // -coverprofile flag
   486  	testJSON         bool                              // -json flag
   487  	testList         string                            // -list flag
   488  	testO            string                            // -o flag
   489  	testOutputDir    outputdirFlag                     // -outputdir flag
   490  	testShuffle      shuffleFlag                       // -shuffle flag
   491  	testTimeout      time.Duration                     // -timeout flag
   492  	testV            bool                              // -v flag
   493  	testVet          = vetFlag{flags: defaultVetFlags} // -vet flag
   494  )
   495  
   496  var (
   497  	testArgs []string
   498  	pkgArgs  []string
   499  	pkgs     []*load.Package
   500  
   501  	testHelp bool // -help option passed to test via -args
   502  
   503  	testKillTimeout = 100 * 365 * 24 * time.Hour // backup alarm; defaults to about a century if no timeout is set
   504  	testCacheExpire time.Time                    // ignore cached test results before this time
   505  
   506  	testBlockProfile, testCPUProfile, testMemProfile, testMutexProfile, testTrace string // profiling flag that limits test to one package
   507  )
   508  
   509  // testProfile returns the name of an arbitrary single-package profiling flag
   510  // that is set, if any.
   511  func testProfile() string {
   512  	switch {
   513  	case testBlockProfile != "":
   514  		return "-blockprofile"
   515  	case testCPUProfile != "":
   516  		return "-cpuprofile"
   517  	case testMemProfile != "":
   518  		return "-memprofile"
   519  	case testMutexProfile != "":
   520  		return "-mutexprofile"
   521  	case testTrace != "":
   522  		return "-trace"
   523  	default:
   524  		return ""
   525  	}
   526  }
   527  
   528  // testNeedBinary reports whether the test needs to keep the binary around.
   529  func testNeedBinary() bool {
   530  	switch {
   531  	case testBlockProfile != "":
   532  		return true
   533  	case testCPUProfile != "":
   534  		return true
   535  	case testMemProfile != "":
   536  		return true
   537  	case testMutexProfile != "":
   538  		return true
   539  	case testO != "":
   540  		return true
   541  	default:
   542  		return false
   543  	}
   544  }
   545  
   546  // testShowPass reports whether the output for a passing test should be shown.
   547  func testShowPass() bool {
   548  	return testV || (testList != "") || testHelp
   549  }
   550  
   551  var defaultVetFlags = []string{
   552  	// TODO(rsc): Decide which tests are enabled by default.
   553  	// See golang.org/issue/18085.
   554  	// "-asmdecl",
   555  	// "-assign",
   556  	"-atomic",
   557  	"-bool",
   558  	"-buildtags",
   559  	// "-cgocall",
   560  	// "-composites",
   561  	// "-copylocks",
   562  	"-errorsas",
   563  	// "-httpresponse",
   564  	"-ifaceassert",
   565  	// "-lostcancel",
   566  	// "-methods",
   567  	"-nilfunc",
   568  	"-printf",
   569  	// "-rangeloops",
   570  	// "-shift",
   571  	"-stringintconv",
   572  	// "-structtags",
   573  	// "-tests",
   574  	// "-unreachable",
   575  	// "-unsafeptr",
   576  	// "-unusedresult",
   577  }
   578  
   579  func runTest(ctx context.Context, cmd *base.Command, args []string) {
   580  	pkgArgs, testArgs = testFlags(args)
   581  
   582  	if cfg.DebugTrace != "" {
   583  		var close func() error
   584  		var err error
   585  		ctx, close, err = trace.Start(ctx, cfg.DebugTrace)
   586  		if err != nil {
   587  			base.Fatalf("failed to start trace: %v", err)
   588  		}
   589  		defer func() {
   590  			if err := close(); err != nil {
   591  				base.Fatalf("failed to stop trace: %v", err)
   592  			}
   593  		}()
   594  	}
   595  
   596  	ctx, span := trace.StartSpan(ctx, fmt.Sprint("Running ", cmd.Name(), " command"))
   597  	defer span.Done()
   598  
   599  	work.FindExecCmd() // initialize cached result
   600  
   601  	work.BuildInit()
   602  	work.VetFlags = testVet.flags
   603  	work.VetExplicit = testVet.explicit
   604  
   605  	pkgOpts := load.PackageOpts{ModResolveTests: true}
   606  	pkgs = load.PackagesAndErrors(ctx, pkgOpts, pkgArgs)
   607  	load.CheckPackageErrors(pkgs)
   608  	if len(pkgs) == 0 {
   609  		base.Fatalf("no packages to test")
   610  	}
   611  
   612  	if testC && len(pkgs) != 1 {
   613  		base.Fatalf("cannot use -c flag with multiple packages")
   614  	}
   615  	if testO != "" && len(pkgs) != 1 {
   616  		base.Fatalf("cannot use -o flag with multiple packages")
   617  	}
   618  	if testProfile() != "" && len(pkgs) != 1 {
   619  		base.Fatalf("cannot use %s flag with multiple packages", testProfile())
   620  	}
   621  	initCoverProfile()
   622  	defer closeCoverProfile()
   623  
   624  	// If a test timeout is finite, set our kill timeout
   625  	// to that timeout plus one minute. This is a backup alarm in case
   626  	// the test wedges with a goroutine spinning and its background
   627  	// timer does not get a chance to fire.
   628  	if testTimeout > 0 {
   629  		testKillTimeout = testTimeout + 1*time.Minute
   630  	}
   631  
   632  	// For 'go test -i -o x.test', we want to build x.test. Imply -c to make the logic easier.
   633  	if cfg.BuildI && testO != "" {
   634  		testC = true
   635  	}
   636  
   637  	// Read testcache expiration time, if present.
   638  	// (We implement go clean -testcache by writing an expiration date
   639  	// instead of searching out and deleting test result cache entries.)
   640  	if dir := cache.DefaultDir(); dir != "off" {
   641  		if data, _ := lockedfile.Read(filepath.Join(dir, "testexpire.txt")); len(data) > 0 && data[len(data)-1] == '\n' {
   642  			if t, err := strconv.ParseInt(string(data[:len(data)-1]), 10, 64); err == nil {
   643  				testCacheExpire = time.Unix(0, t)
   644  			}
   645  		}
   646  	}
   647  
   648  	var b work.Builder
   649  	b.Init()
   650  
   651  	if cfg.BuildI {
   652  		fmt.Fprint(os.Stderr, "go test: -i flag is deprecated\n")
   653  		cfg.BuildV = testV
   654  
   655  		deps := make(map[string]bool)
   656  		for _, dep := range load.TestMainDeps {
   657  			deps[dep] = true
   658  		}
   659  
   660  		for _, p := range pkgs {
   661  			// Dependencies for each test.
   662  			for _, path := range p.Imports {
   663  				deps[path] = true
   664  			}
   665  			for _, path := range p.Resolve(p.TestImports) {
   666  				deps[path] = true
   667  			}
   668  			for _, path := range p.Resolve(p.XTestImports) {
   669  				deps[path] = true
   670  			}
   671  		}
   672  
   673  		// translate C to runtime/cgo
   674  		if deps["C"] {
   675  			delete(deps, "C")
   676  			deps["runtime/cgo"] = true
   677  		}
   678  		// Ignore pseudo-packages.
   679  		delete(deps, "unsafe")
   680  
   681  		all := []string{}
   682  		for path := range deps {
   683  			if !build.IsLocalImport(path) {
   684  				all = append(all, path)
   685  			}
   686  		}
   687  		sort.Strings(all)
   688  
   689  		a := &work.Action{Mode: "go test -i"}
   690  		pkgs := load.PackagesAndErrors(ctx, pkgOpts, all)
   691  		load.CheckPackageErrors(pkgs)
   692  		for _, p := range pkgs {
   693  			if cfg.BuildToolchainName == "gccgo" && p.Standard {
   694  				// gccgo's standard library packages
   695  				// can not be reinstalled.
   696  				continue
   697  			}
   698  			a.Deps = append(a.Deps, b.CompileAction(work.ModeInstall, work.ModeInstall, p))
   699  		}
   700  		b.Do(ctx, a)
   701  		if !testC || a.Failed {
   702  			return
   703  		}
   704  		b.Init()
   705  	}
   706  
   707  	var builds, runs, prints []*work.Action
   708  
   709  	if testCoverPaths != nil {
   710  		match := make([]func(*load.Package) bool, len(testCoverPaths))
   711  		matched := make([]bool, len(testCoverPaths))
   712  		for i := range testCoverPaths {
   713  			match[i] = load.MatchPackage(testCoverPaths[i], base.Cwd())
   714  		}
   715  
   716  		// Select for coverage all dependencies matching the testCoverPaths patterns.
   717  		for _, p := range load.TestPackageList(ctx, pkgOpts, pkgs) {
   718  			haveMatch := false
   719  			for i := range testCoverPaths {
   720  				if match[i](p) {
   721  					matched[i] = true
   722  					haveMatch = true
   723  				}
   724  			}
   725  
   726  			// A package which only has test files can't be imported
   727  			// as a dependency, nor can it be instrumented for coverage.
   728  			if len(p.GoFiles)+len(p.CgoFiles) == 0 {
   729  				continue
   730  			}
   731  
   732  			// Silently ignore attempts to run coverage on
   733  			// sync/atomic when using atomic coverage mode.
   734  			// Atomic coverage mode uses sync/atomic, so
   735  			// we can't also do coverage on it.
   736  			if testCoverMode == "atomic" && p.Standard && p.ImportPath == "sync/atomic" {
   737  				continue
   738  			}
   739  
   740  			// If using the race detector, silently ignore
   741  			// attempts to run coverage on the runtime
   742  			// packages. It will cause the race detector
   743  			// to be invoked before it has been initialized.
   744  			if cfg.BuildRace && p.Standard && (p.ImportPath == "runtime" || strings.HasPrefix(p.ImportPath, "runtime/internal")) {
   745  				continue
   746  			}
   747  
   748  			if haveMatch {
   749  				testCoverPkgs = append(testCoverPkgs, p)
   750  			}
   751  		}
   752  
   753  		// Warn about -coverpkg arguments that are not actually used.
   754  		for i := range testCoverPaths {
   755  			if !matched[i] {
   756  				fmt.Fprintf(os.Stderr, "warning: no packages being tested depend on matches for pattern %s\n", testCoverPaths[i])
   757  			}
   758  		}
   759  
   760  		// Mark all the coverage packages for rebuilding with coverage.
   761  		for _, p := range testCoverPkgs {
   762  			// There is nothing to cover in package unsafe; it comes from the compiler.
   763  			if p.ImportPath == "unsafe" {
   764  				continue
   765  			}
   766  			p.Internal.CoverMode = testCoverMode
   767  			var coverFiles []string
   768  			coverFiles = append(coverFiles, p.GoFiles...)
   769  			coverFiles = append(coverFiles, p.CgoFiles...)
   770  			coverFiles = append(coverFiles, p.TestGoFiles...)
   771  			p.Internal.CoverVars = declareCoverVars(p, coverFiles...)
   772  			if testCover && testCoverMode == "atomic" {
   773  				ensureImport(p, "sync/atomic")
   774  			}
   775  		}
   776  	}
   777  
   778  	// Prepare build + run + print actions for all packages being tested.
   779  	for _, p := range pkgs {
   780  		// sync/atomic import is inserted by the cover tool. See #18486
   781  		if testCover && testCoverMode == "atomic" {
   782  			ensureImport(p, "sync/atomic")
   783  		}
   784  
   785  		buildTest, runTest, printTest, err := builderTest(&b, ctx, pkgOpts, p)
   786  		if err != nil {
   787  			str := err.Error()
   788  			str = strings.TrimPrefix(str, "\n")
   789  			if p.ImportPath != "" {
   790  				base.Errorf("# %s\n%s", p.ImportPath, str)
   791  			} else {
   792  				base.Errorf("%s", str)
   793  			}
   794  			fmt.Printf("FAIL\t%s [setup failed]\n", p.ImportPath)
   795  			continue
   796  		}
   797  		builds = append(builds, buildTest)
   798  		runs = append(runs, runTest)
   799  		prints = append(prints, printTest)
   800  	}
   801  
   802  	// Ultimately the goal is to print the output.
   803  	root := &work.Action{Mode: "go test", Func: printExitStatus, Deps: prints}
   804  
   805  	// Force the printing of results to happen in order,
   806  	// one at a time.
   807  	for i, a := range prints {
   808  		if i > 0 {
   809  			a.Deps = append(a.Deps, prints[i-1])
   810  		}
   811  	}
   812  
   813  	// Force benchmarks to run in serial.
   814  	if !testC && (testBench != "") {
   815  		// The first run must wait for all builds.
   816  		// Later runs must wait for the previous run's print.
   817  		for i, run := range runs {
   818  			if i == 0 {
   819  				run.Deps = append(run.Deps, builds...)
   820  			} else {
   821  				run.Deps = append(run.Deps, prints[i-1])
   822  			}
   823  		}
   824  	}
   825  
   826  	b.Do(ctx, root)
   827  }
   828  
   829  // ensures that package p imports the named package
   830  func ensureImport(p *load.Package, pkg string) {
   831  	for _, d := range p.Internal.Imports {
   832  		if d.Name == pkg {
   833  			return
   834  		}
   835  	}
   836  
   837  	p1 := load.LoadImportWithFlags(pkg, p.Dir, p, &load.ImportStack{}, nil, 0)
   838  	if p1.Error != nil {
   839  		base.Fatalf("load %s: %v", pkg, p1.Error)
   840  	}
   841  
   842  	p.Internal.Imports = append(p.Internal.Imports, p1)
   843  }
   844  
   845  var windowsBadWords = []string{
   846  	"install",
   847  	"patch",
   848  	"setup",
   849  	"update",
   850  }
   851  
   852  func builderTest(b *work.Builder, ctx context.Context, pkgOpts load.PackageOpts, p *load.Package) (buildAction, runAction, printAction *work.Action, err error) {
   853  	if len(p.TestGoFiles)+len(p.XTestGoFiles) == 0 {
   854  		build := b.CompileAction(work.ModeBuild, work.ModeBuild, p)
   855  		run := &work.Action{Mode: "test run", Package: p, Deps: []*work.Action{build}}
   856  		addTestVet(b, p, run, nil)
   857  		print := &work.Action{Mode: "test print", Func: builderNoTest, Package: p, Deps: []*work.Action{run}}
   858  		return build, run, print, nil
   859  	}
   860  
   861  	// Build Package structs describing:
   862  	//	pmain - pkg.test binary
   863  	//	ptest - package + test files
   864  	//	pxtest - package of external test files
   865  	var cover *load.TestCover
   866  	if testCover {
   867  		cover = &load.TestCover{
   868  			Mode:     testCoverMode,
   869  			Local:    testCover && testCoverPaths == nil,
   870  			Pkgs:     testCoverPkgs,
   871  			Paths:    testCoverPaths,
   872  			DeclVars: declareCoverVars,
   873  		}
   874  	}
   875  	pmain, ptest, pxtest, err := load.TestPackagesFor(ctx, pkgOpts, p, cover)
   876  	if err != nil {
   877  		return nil, nil, nil, err
   878  	}
   879  
   880  	// Use last element of import path, not package name.
   881  	// They differ when package name is "main".
   882  	// But if the import path is "command-line-arguments",
   883  	// like it is during 'go run', use the package name.
   884  	var elem string
   885  	if p.ImportPath == "command-line-arguments" {
   886  		elem = p.Name
   887  	} else {
   888  		elem = p.DefaultExecName()
   889  	}
   890  	testBinary := elem + ".test"
   891  
   892  	testDir := b.NewObjdir()
   893  	if err := b.Mkdir(testDir); err != nil {
   894  		return nil, nil, nil, err
   895  	}
   896  
   897  	pmain.Dir = testDir
   898  	pmain.Internal.OmitDebug = !testC && !testNeedBinary()
   899  
   900  	if !cfg.BuildN {
   901  		// writeTestmain writes _testmain.go,
   902  		// using the test description gathered in t.
   903  		if err := os.WriteFile(testDir+"_testmain.go", *pmain.Internal.TestmainGo, 0666); err != nil {
   904  			return nil, nil, nil, err
   905  		}
   906  	}
   907  
   908  	// Set compile objdir to testDir we've already created,
   909  	// so that the default file path stripping applies to _testmain.go.
   910  	b.CompileAction(work.ModeBuild, work.ModeBuild, pmain).Objdir = testDir
   911  
   912  	a := b.LinkAction(work.ModeBuild, work.ModeBuild, pmain)
   913  	a.Target = testDir + testBinary + cfg.ExeSuffix
   914  	if cfg.Goos == "windows" {
   915  		// There are many reserved words on Windows that,
   916  		// if used in the name of an executable, cause Windows
   917  		// to try to ask for extra permissions.
   918  		// The word list includes setup, install, update, and patch,
   919  		// but it does not appear to be defined anywhere.
   920  		// We have run into this trying to run the
   921  		// go.codereview/patch tests.
   922  		// For package names containing those words, use test.test.exe
   923  		// instead of pkgname.test.exe.
   924  		// Note that this file name is only used in the Go command's
   925  		// temporary directory. If the -c or other flags are
   926  		// given, the code below will still use pkgname.test.exe.
   927  		// There are two user-visible effects of this change.
   928  		// First, you can actually run 'go test' in directories that
   929  		// have names that Windows thinks are installer-like,
   930  		// without getting a dialog box asking for more permissions.
   931  		// Second, in the Windows process listing during go test,
   932  		// the test shows up as test.test.exe, not pkgname.test.exe.
   933  		// That second one is a drawback, but it seems a small
   934  		// price to pay for the test running at all.
   935  		// If maintaining the list of bad words is too onerous,
   936  		// we could just do this always on Windows.
   937  		for _, bad := range windowsBadWords {
   938  			if strings.Contains(testBinary, bad) {
   939  				a.Target = testDir + "test.test" + cfg.ExeSuffix
   940  				break
   941  			}
   942  		}
   943  	}
   944  	buildAction = a
   945  	var installAction, cleanAction *work.Action
   946  	if testC || testNeedBinary() {
   947  		// -c or profiling flag: create action to copy binary to ./test.out.
   948  		target := filepath.Join(base.Cwd(), testBinary+cfg.ExeSuffix)
   949  		if testO != "" {
   950  			target = testO
   951  			if !filepath.IsAbs(target) {
   952  				target = filepath.Join(base.Cwd(), target)
   953  			}
   954  		}
   955  		if target == os.DevNull {
   956  			runAction = buildAction
   957  		} else {
   958  			pmain.Target = target
   959  			installAction = &work.Action{
   960  				Mode:    "test build",
   961  				Func:    work.BuildInstallFunc,
   962  				Deps:    []*work.Action{buildAction},
   963  				Package: pmain,
   964  				Target:  target,
   965  			}
   966  			runAction = installAction // make sure runAction != nil even if not running test
   967  		}
   968  	}
   969  	var vetRunAction *work.Action
   970  	if testC {
   971  		printAction = &work.Action{Mode: "test print (nop)", Package: p, Deps: []*work.Action{runAction}} // nop
   972  		vetRunAction = printAction
   973  	} else {
   974  		// run test
   975  		c := new(runCache)
   976  		runAction = &work.Action{
   977  			Mode:       "test run",
   978  			Func:       c.builderRunTest,
   979  			Deps:       []*work.Action{buildAction},
   980  			Package:    p,
   981  			IgnoreFail: true, // run (prepare output) even if build failed
   982  			TryCache:   c.tryCache,
   983  			Objdir:     testDir,
   984  		}
   985  		vetRunAction = runAction
   986  		cleanAction = &work.Action{
   987  			Mode:       "test clean",
   988  			Func:       builderCleanTest,
   989  			Deps:       []*work.Action{runAction},
   990  			Package:    p,
   991  			IgnoreFail: true, // clean even if test failed
   992  			Objdir:     testDir,
   993  		}
   994  		printAction = &work.Action{
   995  			Mode:       "test print",
   996  			Func:       builderPrintTest,
   997  			Deps:       []*work.Action{cleanAction},
   998  			Package:    p,
   999  			IgnoreFail: true, // print even if test failed
  1000  		}
  1001  	}
  1002  
  1003  	if len(ptest.GoFiles)+len(ptest.CgoFiles) > 0 {
  1004  		addTestVet(b, ptest, vetRunAction, installAction)
  1005  	}
  1006  	if pxtest != nil {
  1007  		addTestVet(b, pxtest, vetRunAction, installAction)
  1008  	}
  1009  
  1010  	if installAction != nil {
  1011  		if runAction != installAction {
  1012  			installAction.Deps = append(installAction.Deps, runAction)
  1013  		}
  1014  		if cleanAction != nil {
  1015  			cleanAction.Deps = append(cleanAction.Deps, installAction)
  1016  		}
  1017  	}
  1018  
  1019  	return buildAction, runAction, printAction, nil
  1020  }
  1021  
  1022  func addTestVet(b *work.Builder, p *load.Package, runAction, installAction *work.Action) {
  1023  	if testVet.off {
  1024  		return
  1025  	}
  1026  
  1027  	vet := b.VetAction(work.ModeBuild, work.ModeBuild, p)
  1028  	runAction.Deps = append(runAction.Deps, vet)
  1029  	// Install will clean the build directory.
  1030  	// Make sure vet runs first.
  1031  	// The install ordering in b.VetAction does not apply here
  1032  	// because we are using a custom installAction (created above).
  1033  	if installAction != nil {
  1034  		installAction.Deps = append(installAction.Deps, vet)
  1035  	}
  1036  }
  1037  
  1038  // isTestFile reports whether the source file is a set of tests and should therefore
  1039  // be excluded from coverage analysis.
  1040  func isTestFile(file string) bool {
  1041  	// We don't cover tests, only the code they test.
  1042  	return strings.HasSuffix(file, "_test.go")
  1043  }
  1044  
  1045  // declareCoverVars attaches the required cover variables names
  1046  // to the files, to be used when annotating the files.
  1047  func declareCoverVars(p *load.Package, files ...string) map[string]*load.CoverVar {
  1048  	coverVars := make(map[string]*load.CoverVar)
  1049  	coverIndex := 0
  1050  	// We create the cover counters as new top-level variables in the package.
  1051  	// We need to avoid collisions with user variables (GoCover_0 is unlikely but still)
  1052  	// and more importantly with dot imports of other covered packages,
  1053  	// so we append 12 hex digits from the SHA-256 of the import path.
  1054  	// The point is only to avoid accidents, not to defeat users determined to
  1055  	// break things.
  1056  	sum := sha256.Sum256([]byte(p.ImportPath))
  1057  	h := fmt.Sprintf("%x", sum[:6])
  1058  	for _, file := range files {
  1059  		if isTestFile(file) {
  1060  			continue
  1061  		}
  1062  		// For a package that is "local" (imported via ./ import or command line, outside GOPATH),
  1063  		// we record the full path to the file name.
  1064  		// Otherwise we record the import path, then a forward slash, then the file name.
  1065  		// This makes profiles within GOPATH file system-independent.
  1066  		// These names appear in the cmd/cover HTML interface.
  1067  		var longFile string
  1068  		if p.Internal.Local {
  1069  			longFile = filepath.Join(p.Dir, file)
  1070  		} else {
  1071  			longFile = path.Join(p.ImportPath, file)
  1072  		}
  1073  		coverVars[file] = &load.CoverVar{
  1074  			File: longFile,
  1075  			Var:  fmt.Sprintf("GoCover_%d_%x", coverIndex, h),
  1076  		}
  1077  		coverIndex++
  1078  	}
  1079  	return coverVars
  1080  }
  1081  
  1082  var noTestsToRun = []byte("\ntesting: warning: no tests to run\n")
  1083  
  1084  type runCache struct {
  1085  	disableCache bool // cache should be disabled for this run
  1086  
  1087  	buf *bytes.Buffer
  1088  	id1 cache.ActionID
  1089  	id2 cache.ActionID
  1090  }
  1091  
  1092  // stdoutMu and lockedStdout provide a locked standard output
  1093  // that guarantees never to interlace writes from multiple
  1094  // goroutines, so that we can have multiple JSON streams writing
  1095  // to a lockedStdout simultaneously and know that events will
  1096  // still be intelligible.
  1097  var stdoutMu sync.Mutex
  1098  
  1099  type lockedStdout struct{}
  1100  
  1101  func (lockedStdout) Write(b []byte) (int, error) {
  1102  	stdoutMu.Lock()
  1103  	defer stdoutMu.Unlock()
  1104  	return os.Stdout.Write(b)
  1105  }
  1106  
  1107  // builderRunTest is the action for running a test binary.
  1108  func (c *runCache) builderRunTest(b *work.Builder, ctx context.Context, a *work.Action) error {
  1109  	if a.Failed {
  1110  		// We were unable to build the binary.
  1111  		a.Failed = false
  1112  		a.TestOutput = new(bytes.Buffer)
  1113  		fmt.Fprintf(a.TestOutput, "FAIL\t%s [build failed]\n", a.Package.ImportPath)
  1114  		base.SetExitStatus(1)
  1115  		return nil
  1116  	}
  1117  
  1118  	var stdout io.Writer = os.Stdout
  1119  	var err error
  1120  	if testJSON {
  1121  		json := test2json.NewConverter(lockedStdout{}, a.Package.ImportPath, test2json.Timestamp)
  1122  		defer func() {
  1123  			json.Exited(err)
  1124  			json.Close()
  1125  		}()
  1126  		stdout = json
  1127  	}
  1128  
  1129  	var buf bytes.Buffer
  1130  	if len(pkgArgs) == 0 || (testBench != "") {
  1131  		// Stream test output (no buffering) when no package has
  1132  		// been given on the command line (implicit current directory)
  1133  		// or when benchmarking.
  1134  		// No change to stdout.
  1135  	} else {
  1136  		// If we're only running a single package under test or if parallelism is
  1137  		// set to 1, and if we're displaying all output (testShowPass), we can
  1138  		// hurry the output along, echoing it as soon as it comes in.
  1139  		// We still have to copy to &buf for caching the result. This special
  1140  		// case was introduced in Go 1.5 and is intentionally undocumented:
  1141  		// the exact details of output buffering are up to the go command and
  1142  		// subject to change. It would be nice to remove this special case
  1143  		// entirely, but it is surely very helpful to see progress being made
  1144  		// when tests are run on slow single-CPU ARM systems.
  1145  		//
  1146  		// If we're showing JSON output, then display output as soon as
  1147  		// possible even when multiple tests are being run: the JSON output
  1148  		// events are attributed to specific package tests, so interlacing them
  1149  		// is OK.
  1150  		if testShowPass() && (len(pkgs) == 1 || cfg.BuildP == 1) || testJSON {
  1151  			// Write both to stdout and buf, for possible saving
  1152  			// to cache, and for looking for the "no tests to run" message.
  1153  			stdout = io.MultiWriter(stdout, &buf)
  1154  		} else {
  1155  			stdout = &buf
  1156  		}
  1157  	}
  1158  
  1159  	if c.buf == nil {
  1160  		// We did not find a cached result using the link step action ID,
  1161  		// so we ran the link step. Try again now with the link output
  1162  		// content ID. The attempt using the action ID makes sure that
  1163  		// if the link inputs don't change, we reuse the cached test
  1164  		// result without even rerunning the linker. The attempt using
  1165  		// the link output (test binary) content ID makes sure that if
  1166  		// we have different link inputs but the same final binary,
  1167  		// we still reuse the cached test result.
  1168  		// c.saveOutput will store the result under both IDs.
  1169  		c.tryCacheWithID(b, a, a.Deps[0].BuildContentID())
  1170  	}
  1171  	if c.buf != nil {
  1172  		if stdout != &buf {
  1173  			stdout.Write(c.buf.Bytes())
  1174  			c.buf.Reset()
  1175  		}
  1176  		a.TestOutput = c.buf
  1177  		return nil
  1178  	}
  1179  
  1180  	execCmd := work.FindExecCmd()
  1181  	testlogArg := []string{}
  1182  	if !c.disableCache && len(execCmd) == 0 {
  1183  		testlogArg = []string{"-test.testlogfile=" + a.Objdir + "testlog.txt"}
  1184  	}
  1185  	panicArg := "-test.paniconexit0"
  1186  	args := str.StringList(execCmd, a.Deps[0].BuiltTarget(), testlogArg, panicArg, testArgs)
  1187  
  1188  	if testCoverProfile != "" {
  1189  		// Write coverage to temporary profile, for merging later.
  1190  		for i, arg := range args {
  1191  			if strings.HasPrefix(arg, "-test.coverprofile=") {
  1192  				args[i] = "-test.coverprofile=" + a.Objdir + "_cover_.out"
  1193  			}
  1194  		}
  1195  	}
  1196  
  1197  	if cfg.BuildN || cfg.BuildX {
  1198  		b.Showcmd("", "%s", strings.Join(args, " "))
  1199  		if cfg.BuildN {
  1200  			return nil
  1201  		}
  1202  	}
  1203  
  1204  	cmd := exec.Command(args[0], args[1:]...)
  1205  	cmd.Dir = a.Package.Dir
  1206  	cmd.Env = base.AppendPWD(cfg.OrigEnv[:len(cfg.OrigEnv):len(cfg.OrigEnv)], cmd.Dir)
  1207  	cmd.Stdout = stdout
  1208  	cmd.Stderr = stdout
  1209  
  1210  	// If there are any local SWIG dependencies, we want to load
  1211  	// the shared library from the build directory.
  1212  	if a.Package.UsesSwig() {
  1213  		env := cmd.Env
  1214  		found := false
  1215  		prefix := "LD_LIBRARY_PATH="
  1216  		for i, v := range env {
  1217  			if strings.HasPrefix(v, prefix) {
  1218  				env[i] = v + ":."
  1219  				found = true
  1220  				break
  1221  			}
  1222  		}
  1223  		if !found {
  1224  			env = append(env, "LD_LIBRARY_PATH=.")
  1225  		}
  1226  		cmd.Env = env
  1227  	}
  1228  
  1229  	t0 := time.Now()
  1230  	err = cmd.Start()
  1231  
  1232  	// This is a last-ditch deadline to detect and
  1233  	// stop wedged test binaries, to keep the builders
  1234  	// running.
  1235  	if err == nil {
  1236  		tick := time.NewTimer(testKillTimeout)
  1237  		base.StartSigHandlers()
  1238  		done := make(chan error)
  1239  		go func() {
  1240  			done <- cmd.Wait()
  1241  		}()
  1242  	Outer:
  1243  		select {
  1244  		case err = <-done:
  1245  			// ok
  1246  		case <-tick.C:
  1247  			if base.SignalTrace != nil {
  1248  				// Send a quit signal in the hope that the program will print
  1249  				// a stack trace and exit. Give it five seconds before resorting
  1250  				// to Kill.
  1251  				cmd.Process.Signal(base.SignalTrace)
  1252  				select {
  1253  				case err = <-done:
  1254  					fmt.Fprintf(cmd.Stdout, "*** Test killed with %v: ran too long (%v).\n", base.SignalTrace, testKillTimeout)
  1255  					break Outer
  1256  				case <-time.After(5 * time.Second):
  1257  				}
  1258  			}
  1259  			cmd.Process.Kill()
  1260  			err = <-done
  1261  			fmt.Fprintf(cmd.Stdout, "*** Test killed: ran too long (%v).\n", testKillTimeout)
  1262  		}
  1263  		tick.Stop()
  1264  	}
  1265  	out := buf.Bytes()
  1266  	a.TestOutput = &buf
  1267  	t := fmt.Sprintf("%.3fs", time.Since(t0).Seconds())
  1268  
  1269  	mergeCoverProfile(cmd.Stdout, a.Objdir+"_cover_.out")
  1270  
  1271  	if err == nil {
  1272  		norun := ""
  1273  		if !testShowPass() && !testJSON {
  1274  			buf.Reset()
  1275  		}
  1276  		if bytes.HasPrefix(out, noTestsToRun[1:]) || bytes.Contains(out, noTestsToRun) {
  1277  			norun = " [no tests to run]"
  1278  		}
  1279  		fmt.Fprintf(cmd.Stdout, "ok  \t%s\t%s%s%s\n", a.Package.ImportPath, t, coveragePercentage(out), norun)
  1280  		c.saveOutput(a)
  1281  	} else {
  1282  		base.SetExitStatus(1)
  1283  		// If there was test output, assume we don't need to print the exit status.
  1284  		// Buf there's no test output, do print the exit status.
  1285  		if len(out) == 0 {
  1286  			fmt.Fprintf(cmd.Stdout, "%s\n", err)
  1287  		}
  1288  		// NOTE(golang.org/issue/37555): test2json reports that a test passes
  1289  		// unless "FAIL" is printed at the beginning of a line. The test may not
  1290  		// actually print that if it panics, exits, or terminates abnormally,
  1291  		// so we print it here. We can't always check whether it was printed
  1292  		// because some tests need stdout to be a terminal (golang.org/issue/34791),
  1293  		// not a pipe.
  1294  		// TODO(golang.org/issue/29062): tests that exit with status 0 without
  1295  		// printing a final result should fail.
  1296  		fmt.Fprintf(cmd.Stdout, "FAIL\t%s\t%s\n", a.Package.ImportPath, t)
  1297  	}
  1298  
  1299  	if cmd.Stdout != &buf {
  1300  		buf.Reset() // cmd.Stdout was going to os.Stdout already
  1301  	}
  1302  	return nil
  1303  }
  1304  
  1305  // tryCache is called just before the link attempt,
  1306  // to see if the test result is cached and therefore the link is unneeded.
  1307  // It reports whether the result can be satisfied from cache.
  1308  func (c *runCache) tryCache(b *work.Builder, a *work.Action) bool {
  1309  	return c.tryCacheWithID(b, a, a.Deps[0].BuildActionID())
  1310  }
  1311  
  1312  func (c *runCache) tryCacheWithID(b *work.Builder, a *work.Action, id string) bool {
  1313  	if len(pkgArgs) == 0 {
  1314  		// Caching does not apply to "go test",
  1315  		// only to "go test foo" (including "go test .").
  1316  		if cache.DebugTest {
  1317  			fmt.Fprintf(os.Stderr, "testcache: caching disabled in local directory mode\n")
  1318  		}
  1319  		c.disableCache = true
  1320  		return false
  1321  	}
  1322  
  1323  	if a.Package.Root == "" {
  1324  		// Caching does not apply to tests outside of any module, GOPATH, or GOROOT.
  1325  		if cache.DebugTest {
  1326  			fmt.Fprintf(os.Stderr, "testcache: caching disabled for package outside of module root, GOPATH, or GOROOT: %s\n", a.Package.ImportPath)
  1327  		}
  1328  		c.disableCache = true
  1329  		return false
  1330  	}
  1331  
  1332  	var cacheArgs []string
  1333  	for _, arg := range testArgs {
  1334  		i := strings.Index(arg, "=")
  1335  		if i < 0 || !strings.HasPrefix(arg, "-test.") {
  1336  			if cache.DebugTest {
  1337  				fmt.Fprintf(os.Stderr, "testcache: caching disabled for test argument: %s\n", arg)
  1338  			}
  1339  			c.disableCache = true
  1340  			return false
  1341  		}
  1342  		switch arg[:i] {
  1343  		case "-test.benchtime",
  1344  			"-test.cpu",
  1345  			"-test.list",
  1346  			"-test.parallel",
  1347  			"-test.run",
  1348  			"-test.short",
  1349  			"-test.timeout",
  1350  			"-test.v":
  1351  			// These are cacheable.
  1352  			// Note that this list is documented above,
  1353  			// so if you add to this list, update the docs too.
  1354  			cacheArgs = append(cacheArgs, arg)
  1355  
  1356  		default:
  1357  			// nothing else is cacheable
  1358  			if cache.DebugTest {
  1359  				fmt.Fprintf(os.Stderr, "testcache: caching disabled for test argument: %s\n", arg)
  1360  			}
  1361  			c.disableCache = true
  1362  			return false
  1363  		}
  1364  	}
  1365  
  1366  	if cache.Default() == nil {
  1367  		if cache.DebugTest {
  1368  			fmt.Fprintf(os.Stderr, "testcache: GOCACHE=off\n")
  1369  		}
  1370  		c.disableCache = true
  1371  		return false
  1372  	}
  1373  
  1374  	// The test cache result fetch is a two-level lookup.
  1375  	//
  1376  	// First, we use the content hash of the test binary
  1377  	// and its command-line arguments to find the
  1378  	// list of environment variables and files consulted
  1379  	// the last time the test was run with those arguments.
  1380  	// (To avoid unnecessary links, we store this entry
  1381  	// under two hashes: id1 uses the linker inputs as a
  1382  	// proxy for the test binary, and id2 uses the actual
  1383  	// test binary. If the linker inputs are unchanged,
  1384  	// this way we avoid the link step, even though we
  1385  	// do not cache link outputs.)
  1386  	//
  1387  	// Second, we compute a hash of the values of the
  1388  	// environment variables and the content of the files
  1389  	// listed in the log from the previous run.
  1390  	// Then we look up test output using a combination of
  1391  	// the hash from the first part (testID) and the hash of the
  1392  	// test inputs (testInputsID).
  1393  	//
  1394  	// In order to store a new test result, we must redo the
  1395  	// testInputsID computation using the log from the run
  1396  	// we want to cache, and then we store that new log and
  1397  	// the new outputs.
  1398  
  1399  	h := cache.NewHash("testResult")
  1400  	fmt.Fprintf(h, "test binary %s args %q execcmd %q", id, cacheArgs, work.ExecCmd)
  1401  	testID := h.Sum()
  1402  	if c.id1 == (cache.ActionID{}) {
  1403  		c.id1 = testID
  1404  	} else {
  1405  		c.id2 = testID
  1406  	}
  1407  	if cache.DebugTest {
  1408  		fmt.Fprintf(os.Stderr, "testcache: %s: test ID %x => %x\n", a.Package.ImportPath, id, testID)
  1409  	}
  1410  
  1411  	// Load list of referenced environment variables and files
  1412  	// from last run of testID, and compute hash of that content.
  1413  	data, entry, err := cache.Default().GetBytes(testID)
  1414  	if !bytes.HasPrefix(data, testlogMagic) || data[len(data)-1] != '\n' {
  1415  		if cache.DebugTest {
  1416  			if err != nil {
  1417  				fmt.Fprintf(os.Stderr, "testcache: %s: input list not found: %v\n", a.Package.ImportPath, err)
  1418  			} else {
  1419  				fmt.Fprintf(os.Stderr, "testcache: %s: input list malformed\n", a.Package.ImportPath)
  1420  			}
  1421  		}
  1422  		return false
  1423  	}
  1424  	testInputsID, err := computeTestInputsID(a, data)
  1425  	if err != nil {
  1426  		return false
  1427  	}
  1428  	if cache.DebugTest {
  1429  		fmt.Fprintf(os.Stderr, "testcache: %s: test ID %x => input ID %x => %x\n", a.Package.ImportPath, testID, testInputsID, testAndInputKey(testID, testInputsID))
  1430  	}
  1431  
  1432  	// Parse cached result in preparation for changing run time to "(cached)".
  1433  	// If we can't parse the cached result, don't use it.
  1434  	data, entry, err = cache.Default().GetBytes(testAndInputKey(testID, testInputsID))
  1435  	if len(data) == 0 || data[len(data)-1] != '\n' {
  1436  		if cache.DebugTest {
  1437  			if err != nil {
  1438  				fmt.Fprintf(os.Stderr, "testcache: %s: test output not found: %v\n", a.Package.ImportPath, err)
  1439  			} else {
  1440  				fmt.Fprintf(os.Stderr, "testcache: %s: test output malformed\n", a.Package.ImportPath)
  1441  			}
  1442  		}
  1443  		return false
  1444  	}
  1445  	if entry.Time.Before(testCacheExpire) {
  1446  		if cache.DebugTest {
  1447  			fmt.Fprintf(os.Stderr, "testcache: %s: test output expired due to go clean -testcache\n", a.Package.ImportPath)
  1448  		}
  1449  		return false
  1450  	}
  1451  	i := bytes.LastIndexByte(data[:len(data)-1], '\n') + 1
  1452  	if !bytes.HasPrefix(data[i:], []byte("ok  \t")) {
  1453  		if cache.DebugTest {
  1454  			fmt.Fprintf(os.Stderr, "testcache: %s: test output malformed\n", a.Package.ImportPath)
  1455  		}
  1456  		return false
  1457  	}
  1458  	j := bytes.IndexByte(data[i+len("ok  \t"):], '\t')
  1459  	if j < 0 {
  1460  		if cache.DebugTest {
  1461  			fmt.Fprintf(os.Stderr, "testcache: %s: test output malformed\n", a.Package.ImportPath)
  1462  		}
  1463  		return false
  1464  	}
  1465  	j += i + len("ok  \t") + 1
  1466  
  1467  	// Committed to printing.
  1468  	c.buf = new(bytes.Buffer)
  1469  	c.buf.Write(data[:j])
  1470  	c.buf.WriteString("(cached)")
  1471  	for j < len(data) && ('0' <= data[j] && data[j] <= '9' || data[j] == '.' || data[j] == 's') {
  1472  		j++
  1473  	}
  1474  	c.buf.Write(data[j:])
  1475  	return true
  1476  }
  1477  
  1478  var errBadTestInputs = errors.New("error parsing test inputs")
  1479  var testlogMagic = []byte("# test log\n") // known to testing/internal/testdeps/deps.go
  1480  
  1481  // computeTestInputsID computes the "test inputs ID"
  1482  // (see comment in tryCacheWithID above) for the
  1483  // test log.
  1484  func computeTestInputsID(a *work.Action, testlog []byte) (cache.ActionID, error) {
  1485  	testlog = bytes.TrimPrefix(testlog, testlogMagic)
  1486  	h := cache.NewHash("testInputs")
  1487  	pwd := a.Package.Dir
  1488  	for _, line := range bytes.Split(testlog, []byte("\n")) {
  1489  		if len(line) == 0 {
  1490  			continue
  1491  		}
  1492  		s := string(line)
  1493  		i := strings.Index(s, " ")
  1494  		if i < 0 {
  1495  			if cache.DebugTest {
  1496  				fmt.Fprintf(os.Stderr, "testcache: %s: input list malformed (%q)\n", a.Package.ImportPath, line)
  1497  			}
  1498  			return cache.ActionID{}, errBadTestInputs
  1499  		}
  1500  		op := s[:i]
  1501  		name := s[i+1:]
  1502  		switch op {
  1503  		default:
  1504  			if cache.DebugTest {
  1505  				fmt.Fprintf(os.Stderr, "testcache: %s: input list malformed (%q)\n", a.Package.ImportPath, line)
  1506  			}
  1507  			return cache.ActionID{}, errBadTestInputs
  1508  		case "getenv":
  1509  			fmt.Fprintf(h, "env %s %x\n", name, hashGetenv(name))
  1510  		case "chdir":
  1511  			pwd = name // always absolute
  1512  			fmt.Fprintf(h, "chdir %s %x\n", name, hashStat(name))
  1513  		case "stat":
  1514  			if !filepath.IsAbs(name) {
  1515  				name = filepath.Join(pwd, name)
  1516  			}
  1517  			if a.Package.Root == "" || search.InDir(name, a.Package.Root) == "" {
  1518  				// Do not recheck files outside the module, GOPATH, or GOROOT root.
  1519  				break
  1520  			}
  1521  			fmt.Fprintf(h, "stat %s %x\n", name, hashStat(name))
  1522  		case "open":
  1523  			if !filepath.IsAbs(name) {
  1524  				name = filepath.Join(pwd, name)
  1525  			}
  1526  			if a.Package.Root == "" || search.InDir(name, a.Package.Root) == "" {
  1527  				// Do not recheck files outside the module, GOPATH, or GOROOT root.
  1528  				break
  1529  			}
  1530  			fh, err := hashOpen(name)
  1531  			if err != nil {
  1532  				if cache.DebugTest {
  1533  					fmt.Fprintf(os.Stderr, "testcache: %s: input file %s: %s\n", a.Package.ImportPath, name, err)
  1534  				}
  1535  				return cache.ActionID{}, err
  1536  			}
  1537  			fmt.Fprintf(h, "open %s %x\n", name, fh)
  1538  		}
  1539  	}
  1540  	sum := h.Sum()
  1541  	return sum, nil
  1542  }
  1543  
  1544  func hashGetenv(name string) cache.ActionID {
  1545  	h := cache.NewHash("getenv")
  1546  	v, ok := os.LookupEnv(name)
  1547  	if !ok {
  1548  		h.Write([]byte{0})
  1549  	} else {
  1550  		h.Write([]byte{1})
  1551  		h.Write([]byte(v))
  1552  	}
  1553  	return h.Sum()
  1554  }
  1555  
  1556  const modTimeCutoff = 2 * time.Second
  1557  
  1558  var errFileTooNew = errors.New("file used as input is too new")
  1559  
  1560  func hashOpen(name string) (cache.ActionID, error) {
  1561  	h := cache.NewHash("open")
  1562  	info, err := os.Stat(name)
  1563  	if err != nil {
  1564  		fmt.Fprintf(h, "err %v\n", err)
  1565  		return h.Sum(), nil
  1566  	}
  1567  	hashWriteStat(h, info)
  1568  	if info.IsDir() {
  1569  		files, err := os.ReadDir(name)
  1570  		if err != nil {
  1571  			fmt.Fprintf(h, "err %v\n", err)
  1572  		}
  1573  		for _, f := range files {
  1574  			fmt.Fprintf(h, "file %s ", f.Name())
  1575  			finfo, err := f.Info()
  1576  			if err != nil {
  1577  				fmt.Fprintf(h, "err %v\n", err)
  1578  			} else {
  1579  				hashWriteStat(h, finfo)
  1580  			}
  1581  		}
  1582  	} else if info.Mode().IsRegular() {
  1583  		// Because files might be very large, do not attempt
  1584  		// to hash the entirety of their content. Instead assume
  1585  		// the mtime and size recorded in hashWriteStat above
  1586  		// are good enough.
  1587  		//
  1588  		// To avoid problems for very recent files where a new
  1589  		// write might not change the mtime due to file system
  1590  		// mtime precision, reject caching if a file was read that
  1591  		// is less than modTimeCutoff old.
  1592  		if time.Since(info.ModTime()) < modTimeCutoff {
  1593  			return cache.ActionID{}, errFileTooNew
  1594  		}
  1595  	}
  1596  	return h.Sum(), nil
  1597  }
  1598  
  1599  func hashStat(name string) cache.ActionID {
  1600  	h := cache.NewHash("stat")
  1601  	if info, err := os.Stat(name); err != nil {
  1602  		fmt.Fprintf(h, "err %v\n", err)
  1603  	} else {
  1604  		hashWriteStat(h, info)
  1605  	}
  1606  	if info, err := os.Lstat(name); err != nil {
  1607  		fmt.Fprintf(h, "err %v\n", err)
  1608  	} else {
  1609  		hashWriteStat(h, info)
  1610  	}
  1611  	return h.Sum()
  1612  }
  1613  
  1614  func hashWriteStat(h io.Writer, info fs.FileInfo) {
  1615  	fmt.Fprintf(h, "stat %d %x %v %v\n", info.Size(), uint64(info.Mode()), info.ModTime(), info.IsDir())
  1616  }
  1617  
  1618  // testAndInputKey returns the actual cache key for the pair (testID, testInputsID).
  1619  func testAndInputKey(testID, testInputsID cache.ActionID) cache.ActionID {
  1620  	return cache.Subkey(testID, fmt.Sprintf("inputs:%x", testInputsID))
  1621  }
  1622  
  1623  func (c *runCache) saveOutput(a *work.Action) {
  1624  	if c.id1 == (cache.ActionID{}) && c.id2 == (cache.ActionID{}) {
  1625  		return
  1626  	}
  1627  
  1628  	// See comment about two-level lookup in tryCacheWithID above.
  1629  	testlog, err := os.ReadFile(a.Objdir + "testlog.txt")
  1630  	if err != nil || !bytes.HasPrefix(testlog, testlogMagic) || testlog[len(testlog)-1] != '\n' {
  1631  		if cache.DebugTest {
  1632  			if err != nil {
  1633  				fmt.Fprintf(os.Stderr, "testcache: %s: reading testlog: %v\n", a.Package.ImportPath, err)
  1634  			} else {
  1635  				fmt.Fprintf(os.Stderr, "testcache: %s: reading testlog: malformed\n", a.Package.ImportPath)
  1636  			}
  1637  		}
  1638  		return
  1639  	}
  1640  	testInputsID, err := computeTestInputsID(a, testlog)
  1641  	if err != nil {
  1642  		return
  1643  	}
  1644  	if c.id1 != (cache.ActionID{}) {
  1645  		if cache.DebugTest {
  1646  			fmt.Fprintf(os.Stderr, "testcache: %s: save test ID %x => input ID %x => %x\n", a.Package.ImportPath, c.id1, testInputsID, testAndInputKey(c.id1, testInputsID))
  1647  		}
  1648  		cache.Default().PutNoVerify(c.id1, bytes.NewReader(testlog))
  1649  		cache.Default().PutNoVerify(testAndInputKey(c.id1, testInputsID), bytes.NewReader(a.TestOutput.Bytes()))
  1650  	}
  1651  	if c.id2 != (cache.ActionID{}) {
  1652  		if cache.DebugTest {
  1653  			fmt.Fprintf(os.Stderr, "testcache: %s: save test ID %x => input ID %x => %x\n", a.Package.ImportPath, c.id2, testInputsID, testAndInputKey(c.id2, testInputsID))
  1654  		}
  1655  		cache.Default().PutNoVerify(c.id2, bytes.NewReader(testlog))
  1656  		cache.Default().PutNoVerify(testAndInputKey(c.id2, testInputsID), bytes.NewReader(a.TestOutput.Bytes()))
  1657  	}
  1658  }
  1659  
  1660  // coveragePercentage returns the coverage results (if enabled) for the
  1661  // test. It uncovers the data by scanning the output from the test run.
  1662  func coveragePercentage(out []byte) string {
  1663  	if !testCover {
  1664  		return ""
  1665  	}
  1666  	// The string looks like
  1667  	//	test coverage for encoding/binary: 79.9% of statements
  1668  	// Extract the piece from the percentage to the end of the line.
  1669  	re := regexp.MustCompile(`coverage: (.*)\n`)
  1670  	matches := re.FindSubmatch(out)
  1671  	if matches == nil {
  1672  		// Probably running "go test -cover" not "go test -cover fmt".
  1673  		// The coverage output will appear in the output directly.
  1674  		return ""
  1675  	}
  1676  	return fmt.Sprintf("\tcoverage: %s", matches[1])
  1677  }
  1678  
  1679  // builderCleanTest is the action for cleaning up after a test.
  1680  func builderCleanTest(b *work.Builder, ctx context.Context, a *work.Action) error {
  1681  	if cfg.BuildWork {
  1682  		return nil
  1683  	}
  1684  	if cfg.BuildX {
  1685  		b.Showcmd("", "rm -r %s", a.Objdir)
  1686  	}
  1687  	os.RemoveAll(a.Objdir)
  1688  	return nil
  1689  }
  1690  
  1691  // builderPrintTest is the action for printing a test result.
  1692  func builderPrintTest(b *work.Builder, ctx context.Context, a *work.Action) error {
  1693  	clean := a.Deps[0]
  1694  	run := clean.Deps[0]
  1695  	if run.TestOutput != nil {
  1696  		os.Stdout.Write(run.TestOutput.Bytes())
  1697  		run.TestOutput = nil
  1698  	}
  1699  	return nil
  1700  }
  1701  
  1702  // builderNoTest is the action for testing a package with no test files.
  1703  func builderNoTest(b *work.Builder, ctx context.Context, a *work.Action) error {
  1704  	var stdout io.Writer = os.Stdout
  1705  	if testJSON {
  1706  		json := test2json.NewConverter(lockedStdout{}, a.Package.ImportPath, test2json.Timestamp)
  1707  		defer json.Close()
  1708  		stdout = json
  1709  	}
  1710  	fmt.Fprintf(stdout, "?   \t%s\t[no test files]\n", a.Package.ImportPath)
  1711  	return nil
  1712  }
  1713  
  1714  // printExitStatus is the action for printing the exit status
  1715  func printExitStatus(b *work.Builder, ctx context.Context, a *work.Action) error {
  1716  	if !testJSON && len(pkgArgs) != 0 {
  1717  		if base.GetExitStatus() != 0 {
  1718  			fmt.Println("FAIL")
  1719  			return nil
  1720  		}
  1721  	}
  1722  	return nil
  1723  }
  1724  

View as plain text