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

View as plain text