Black Lives Matter. Support the Equal Justice Initiative.

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

Documentation: cmd/go/internal/test

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

View as plain text