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

View as plain text