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

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

View as plain text