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

View as plain text