Source file src/cmd/go/go_test.go

     1  // Copyright 2015 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 main_test
     6  
     7  import (
     8  	"bytes"
     9  	"debug/elf"
    10  	"debug/macho"
    11  	"debug/pe"
    12  	"flag"
    13  	"fmt"
    14  	"go/format"
    15  	"internal/godebug"
    16  	"internal/platform"
    17  	"internal/testenv"
    18  	"io"
    19  	"io/fs"
    20  	"log"
    21  	"math"
    22  	"os"
    23  	"os/exec"
    24  	"path/filepath"
    25  	"regexp"
    26  	"runtime"
    27  	"slices"
    28  	"strconv"
    29  	"strings"
    30  	"testing"
    31  	"time"
    32  
    33  	"cmd/go/internal/base"
    34  	"cmd/go/internal/cache"
    35  	"cmd/go/internal/cfg"
    36  	"cmd/go/internal/gover"
    37  	"cmd/go/internal/search"
    38  	"cmd/go/internal/toolchain"
    39  	"cmd/go/internal/vcs"
    40  	"cmd/go/internal/vcweb/vcstest"
    41  	"cmd/go/internal/web/intercept"
    42  	"cmd/go/internal/work"
    43  	"cmd/internal/robustio"
    44  	"cmd/internal/sys"
    45  
    46  	cmdgo "cmd/go"
    47  )
    48  
    49  func init() {
    50  	// GOVCS defaults to public:git|hg,private:all,
    51  	// which breaks many tests here - they can't use non-git, non-hg VCS at all!
    52  	// Change to fully permissive.
    53  	// The tests of the GOVCS setting itself are in ../../testdata/script/govcs.txt.
    54  	os.Setenv("GOVCS", "*:all")
    55  }
    56  
    57  var (
    58  	canRace = false // whether we can run the race detector
    59  	canMSan = false // whether we can run the memory sanitizer
    60  	canASan = false // whether we can run the address sanitizer
    61  )
    62  
    63  var (
    64  	goHostOS, goHostArch string
    65  	cgoEnabled           string // raw value from 'go env CGO_ENABLED'
    66  )
    67  
    68  // netTestSem is a semaphore limiting the number of tests that may use the
    69  // external network in parallel. If non-nil, it contains one buffer slot per
    70  // test (send to acquire), with a low enough limit that the overall number of
    71  // connections (summed across subprocesses) stays at or below base.NetLimit.
    72  var netTestSem chan struct{}
    73  
    74  var exeSuffix string = func() string {
    75  	if runtime.GOOS == "windows" {
    76  		return ".exe"
    77  	}
    78  	return ""
    79  }()
    80  
    81  func tooSlow(t *testing.T, reason string) {
    82  	if testing.Short() {
    83  		t.Helper()
    84  		t.Skipf("skipping test in -short mode: %s", reason)
    85  	}
    86  }
    87  
    88  // testGOROOT is the GOROOT to use when running testgo, a cmd/go binary
    89  // build from this process's current GOROOT, but run from a different
    90  // (temp) directory.
    91  var testGOROOT string
    92  
    93  var testGOCACHE string
    94  
    95  var testGo string
    96  var testTmpDir string
    97  var testBin string
    98  
    99  // The TestMain function creates a go command for testing purposes and
   100  // deletes it after the tests have been run.
   101  func TestMain(m *testing.M) {
   102  	// When CMDGO_TEST_RUN_MAIN is set, we're reusing the test binary as cmd/go.
   103  	// Enable the special behavior needed in cmd/go/internal/work,
   104  	// run the main func exported via export_test.go, and exit.
   105  	// We set CMDGO_TEST_RUN_MAIN via os.Setenv and testScript.setup.
   106  	if os.Getenv("CMDGO_TEST_RUN_MAIN") != "" {
   107  		cfg.SetGOROOT(cfg.GOROOT, true)
   108  		gover.TestVersion = os.Getenv("TESTGO_VERSION")
   109  		toolchain.TestVersionSwitch = os.Getenv("TESTGO_VERSION_SWITCH")
   110  		if v := os.Getenv("TESTGO_TOOLCHAIN_VERSION"); v != "" {
   111  			work.ToolchainVersion = v
   112  		}
   113  
   114  		if testGOROOT := os.Getenv("TESTGO_GOROOT"); testGOROOT != "" {
   115  			// Disallow installs to the GOROOT from which testgo was built.
   116  			// Installs to other GOROOTs — such as one set explicitly within a test — are ok.
   117  			work.AllowInstall = func(a *work.Action) error {
   118  				if cfg.BuildN {
   119  					return nil
   120  				}
   121  
   122  				rel := search.InDir(a.Target, testGOROOT)
   123  				if rel == "" {
   124  					return nil
   125  				}
   126  
   127  				callerPos := ""
   128  				if _, file, line, ok := runtime.Caller(1); ok {
   129  					if shortFile := search.InDir(file, filepath.Join(testGOROOT, "src")); shortFile != "" {
   130  						file = shortFile
   131  					}
   132  					callerPos = fmt.Sprintf("%s:%d: ", file, line)
   133  				}
   134  				notice := "This error error can occur if GOROOT is stale, in which case rerunning make.bash will fix it."
   135  				return fmt.Errorf("%stestgo must not write to GOROOT (installing to %s) (%v)", callerPos, filepath.Join("GOROOT", rel), notice)
   136  			}
   137  		}
   138  
   139  		if vcsTestHost := os.Getenv("TESTGO_VCSTEST_HOST"); vcsTestHost != "" {
   140  			vcs.VCSTestRepoURL = "http://" + vcsTestHost
   141  			vcs.VCSTestHosts = vcstest.Hosts
   142  			vcsTestTLSHost := os.Getenv("TESTGO_VCSTEST_TLS_HOST")
   143  			vcsTestClient, err := vcstest.TLSClient(os.Getenv("TESTGO_VCSTEST_CERT"))
   144  			if err != nil {
   145  				fmt.Fprintf(os.Stderr, "loading certificates from $TESTGO_VCSTEST_CERT: %v", err)
   146  			}
   147  			var interceptors []intercept.Interceptor
   148  			for _, host := range vcstest.Hosts {
   149  				interceptors = append(interceptors,
   150  					intercept.Interceptor{Scheme: "http", FromHost: host, ToHost: vcsTestHost},
   151  					intercept.Interceptor{Scheme: "https", FromHost: host, ToHost: vcsTestTLSHost, Client: vcsTestClient})
   152  			}
   153  			intercept.EnableTestHooks(interceptors)
   154  		}
   155  
   156  		cmdgo.Main()
   157  		os.Exit(0)
   158  	}
   159  	os.Setenv("CMDGO_TEST_RUN_MAIN", "true")
   160  
   161  	// $GO_GCFLAGS a compiler debug flag known to cmd/dist, make.bash, etc.
   162  	// It is not a standard go command flag; use os.Getenv, not cfg.Getenv.
   163  	if os.Getenv("GO_GCFLAGS") != "" {
   164  		fmt.Fprintf(os.Stderr, "testing: warning: no tests to run\n") // magic string for cmd/go
   165  		fmt.Printf("cmd/go test is not compatible with $GO_GCFLAGS being set\n")
   166  		fmt.Printf("SKIP\n")
   167  		return
   168  	}
   169  
   170  	flag.Parse()
   171  
   172  	if *proxyAddr != "" {
   173  		StartProxy()
   174  		select {}
   175  	}
   176  
   177  	// Run with a temporary TMPDIR to check that the tests don't
   178  	// leave anything behind.
   179  	topTmpdir, err := os.MkdirTemp("", "cmd-go-test-")
   180  	if err != nil {
   181  		log.Fatal(err)
   182  	}
   183  	if !*testWork {
   184  		defer removeAll(topTmpdir)
   185  	} else {
   186  		fmt.Fprintf(os.Stderr, "TESTWORK: preserving top level tempdir %s\n", topTmpdir)
   187  	}
   188  	os.Setenv(tempEnvName(), topTmpdir)
   189  
   190  	dir, err := os.MkdirTemp(topTmpdir, "tmpdir")
   191  	if err != nil {
   192  		log.Fatal(err)
   193  	}
   194  	testTmpDir = dir
   195  	if !*testWork {
   196  		defer removeAll(testTmpDir)
   197  	}
   198  
   199  	testGOCACHE, _, _ = cache.DefaultDir()
   200  	if testenv.HasGoBuild() {
   201  		testBin = filepath.Join(testTmpDir, "testbin")
   202  		if err := os.Mkdir(testBin, 0777); err != nil {
   203  			log.Fatal(err)
   204  		}
   205  		testGo = filepath.Join(testBin, "go"+exeSuffix)
   206  		gotool, err := testenv.GoTool()
   207  		if err != nil {
   208  			fmt.Fprintln(os.Stderr, "locating go tool: ", err)
   209  			os.Exit(2)
   210  		}
   211  
   212  		goEnv := func(name string) string {
   213  			out, err := exec.Command(gotool, "env", name).CombinedOutput()
   214  			if err != nil {
   215  				fmt.Fprintf(os.Stderr, "go env %s: %v\n%s", name, err, out)
   216  				os.Exit(2)
   217  			}
   218  			return strings.TrimSpace(string(out))
   219  		}
   220  		testGOROOT = goEnv("GOROOT")
   221  		os.Setenv("TESTGO_GOROOT", testGOROOT)
   222  		os.Setenv("GOROOT", testGOROOT)
   223  
   224  		// The whole GOROOT/pkg tree was installed using the GOHOSTOS/GOHOSTARCH
   225  		// toolchain (installed in GOROOT/pkg/tool/GOHOSTOS_GOHOSTARCH).
   226  		// The testgo.exe we are about to create will be built for GOOS/GOARCH,
   227  		// which means it will use the GOOS/GOARCH toolchain
   228  		// (installed in GOROOT/pkg/tool/GOOS_GOARCH).
   229  		// If these are not the same toolchain, then the entire standard library
   230  		// will look out of date (the compilers in those two different tool directories
   231  		// are built for different architectures and have different build IDs),
   232  		// which will cause many tests to do unnecessary rebuilds and some
   233  		// tests to attempt to overwrite the installed standard library.
   234  		// Bail out entirely in this case.
   235  		goHostOS = goEnv("GOHOSTOS")
   236  		os.Setenv("TESTGO_GOHOSTOS", goHostOS)
   237  		goHostArch = goEnv("GOHOSTARCH")
   238  		os.Setenv("TESTGO_GOHOSTARCH", goHostArch)
   239  
   240  		cgoEnabled = goEnv("CGO_ENABLED")
   241  
   242  		// Duplicate the test executable into the path at testGo, for $PATH.
   243  		// If the OS supports symlinks, use them instead of copying bytes.
   244  		testExe, err := os.Executable()
   245  		if err != nil {
   246  			log.Fatal(err)
   247  		}
   248  		if err := os.Symlink(testExe, testGo); err != nil {
   249  			// Otherwise, copy the bytes.
   250  			src, err := os.Open(testExe)
   251  			if err != nil {
   252  				log.Fatal(err)
   253  			}
   254  			defer src.Close()
   255  
   256  			dst, err := os.OpenFile(testGo, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0o777)
   257  			if err != nil {
   258  				log.Fatal(err)
   259  			}
   260  
   261  			_, err = io.Copy(dst, src)
   262  			if closeErr := dst.Close(); err == nil {
   263  				err = closeErr
   264  			}
   265  			if err != nil {
   266  				log.Fatal(err)
   267  			}
   268  		}
   269  
   270  		out, err := exec.Command(gotool, "env", "GOCACHE").CombinedOutput()
   271  		if err != nil {
   272  			fmt.Fprintf(os.Stderr, "could not find testing GOCACHE: %v\n%s", err, out)
   273  			os.Exit(2)
   274  		}
   275  		testGOCACHE = strings.TrimSpace(string(out))
   276  
   277  		canMSan = testenv.HasCGO() && platform.MSanSupported(runtime.GOOS, runtime.GOARCH)
   278  		canASan = testenv.HasCGO() && platform.ASanSupported(runtime.GOOS, runtime.GOARCH)
   279  		canRace = testenv.HasCGO() && platform.RaceDetectorSupported(runtime.GOOS, runtime.GOARCH)
   280  		// The race detector doesn't work on Alpine Linux:
   281  		// golang.org/issue/14481
   282  		// gccgo does not support the race detector.
   283  		if isAlpineLinux() || runtime.Compiler == "gccgo" {
   284  			canRace = false
   285  		}
   286  	}
   287  
   288  	if n, limited := base.NetLimit(); limited && n > 0 {
   289  		// Split the network limit into chunks, so that each parallel script can
   290  		// have one chunk. We want to run as many parallel scripts as possible, but
   291  		// also want to give each script as high a limit as possible.
   292  		// We arbitrarily split by sqrt(n) to try to balance those two goals.
   293  		netTestLimit := int(math.Sqrt(float64(n)))
   294  		netTestSem = make(chan struct{}, netTestLimit)
   295  		reducedLimit := fmt.Sprintf(",%s=%d", base.NetLimitGodebug.Name(), n/netTestLimit)
   296  		os.Setenv("GODEBUG", os.Getenv("GODEBUG")+reducedLimit)
   297  	}
   298  
   299  	// Don't let these environment variables confuse the test.
   300  	os.Setenv("GOENV", "off")
   301  	os.Unsetenv("GOFLAGS")
   302  	os.Unsetenv("GOBIN")
   303  	os.Unsetenv("GOPATH")
   304  	os.Unsetenv("GIT_ALLOW_PROTOCOL")
   305  	os.Setenv("HOME", "/test-go-home-does-not-exist")
   306  	// On some systems the default C compiler is ccache.
   307  	// Setting HOME to a non-existent directory will break
   308  	// those systems. Disable ccache and use real compiler. Issue 17668.
   309  	os.Setenv("CCACHE_DISABLE", "1")
   310  	if cfg.Getenv("GOCACHE") == "" {
   311  		os.Setenv("GOCACHE", testGOCACHE) // because $HOME is gone
   312  	}
   313  
   314  	if testenv.Builder() != "" || os.Getenv("GIT_TRACE_CURL") == "1" {
   315  		// To help diagnose https://go.dev/issue/52545,
   316  		// enable tracing for Git HTTPS requests.
   317  		os.Setenv("GIT_TRACE_CURL", "1")
   318  		os.Setenv("GIT_TRACE_CURL_NO_DATA", "1")
   319  		os.Setenv("GIT_REDACT_COOKIES", "o,SSO,GSSO_Uberproxy")
   320  	}
   321  
   322  	r := m.Run()
   323  	if !*testWork {
   324  		removeAll(testTmpDir) // os.Exit won't run defer
   325  	}
   326  
   327  	if !*testWork {
   328  		// There shouldn't be anything left in topTmpdir.
   329  		var extraFiles, extraDirs []string
   330  		err := filepath.WalkDir(topTmpdir, func(path string, d fs.DirEntry, err error) error {
   331  			if err != nil {
   332  				return err
   333  			}
   334  			if path == topTmpdir {
   335  				return nil
   336  			}
   337  
   338  			if rel, err := filepath.Rel(topTmpdir, path); err == nil {
   339  				path = rel
   340  			}
   341  			if d.IsDir() {
   342  				extraDirs = append(extraDirs, path)
   343  			} else {
   344  				extraFiles = append(extraFiles, path)
   345  			}
   346  			return nil
   347  		})
   348  		if err != nil {
   349  			log.Fatal(err)
   350  		}
   351  
   352  		if len(extraFiles) > 0 {
   353  			log.Fatalf("unexpected files left in tmpdir: %q", extraFiles)
   354  		} else if len(extraDirs) > 0 {
   355  			log.Fatalf("unexpected subdirectories left in tmpdir: %q", extraDirs)
   356  		}
   357  
   358  		removeAll(topTmpdir)
   359  	}
   360  
   361  	os.Exit(r)
   362  }
   363  
   364  func isAlpineLinux() bool {
   365  	if runtime.GOOS != "linux" {
   366  		return false
   367  	}
   368  	fi, err := os.Lstat("/etc/alpine-release")
   369  	return err == nil && fi.Mode().IsRegular()
   370  }
   371  
   372  // The length of an mtime tick on this system. This is an estimate of
   373  // how long we need to sleep to ensure that the mtime of two files is
   374  // different.
   375  // We used to try to be clever but that didn't always work (see golang.org/issue/12205).
   376  var mtimeTick time.Duration = 1 * time.Second
   377  
   378  // Manage a single run of the testgo binary.
   379  type testgoData struct {
   380  	t              *testing.T
   381  	temps          []string
   382  	env            []string
   383  	tempdir        string
   384  	ran            bool
   385  	inParallel     bool
   386  	stdout, stderr bytes.Buffer
   387  	execDir        string // dir for tg.run
   388  }
   389  
   390  // skipIfGccgo skips the test if using gccgo.
   391  func skipIfGccgo(t *testing.T, msg string) {
   392  	if runtime.Compiler == "gccgo" {
   393  		t.Skipf("skipping test not supported on gccgo: %s", msg)
   394  	}
   395  }
   396  
   397  // testgo sets up for a test that runs testgo.
   398  func testgo(t *testing.T) *testgoData {
   399  	t.Helper()
   400  	testenv.MustHaveGoBuild(t)
   401  	testenv.SkipIfShortAndSlow(t)
   402  
   403  	return &testgoData{t: t}
   404  }
   405  
   406  // must gives a fatal error if err is not nil.
   407  func (tg *testgoData) must(err error) {
   408  	tg.t.Helper()
   409  	if err != nil {
   410  		tg.t.Fatal(err)
   411  	}
   412  }
   413  
   414  // check gives a test non-fatal error if err is not nil.
   415  func (tg *testgoData) check(err error) {
   416  	tg.t.Helper()
   417  	if err != nil {
   418  		tg.t.Error(err)
   419  	}
   420  }
   421  
   422  // parallel runs the test in parallel by calling t.Parallel.
   423  func (tg *testgoData) parallel() {
   424  	tg.t.Helper()
   425  	if tg.ran {
   426  		tg.t.Fatal("internal testsuite error: call to parallel after run")
   427  	}
   428  	for _, e := range tg.env {
   429  		if strings.HasPrefix(e, "GOROOT=") || strings.HasPrefix(e, "GOPATH=") || strings.HasPrefix(e, "GOBIN=") {
   430  			val := e[strings.Index(e, "=")+1:]
   431  			if strings.HasPrefix(val, "testdata") || strings.HasPrefix(val, "./testdata") {
   432  				tg.t.Fatalf("internal testsuite error: call to parallel with testdata in environment (%s)", e)
   433  			}
   434  		}
   435  	}
   436  	tg.inParallel = true
   437  	tg.t.Parallel()
   438  }
   439  
   440  // pwd returns the current directory.
   441  func (tg *testgoData) pwd() string {
   442  	tg.t.Helper()
   443  	wd, err := os.Getwd()
   444  	if err != nil {
   445  		tg.t.Fatalf("could not get working directory: %v", err)
   446  	}
   447  	return wd
   448  }
   449  
   450  // sleep sleeps for one tick, where a tick is a conservative estimate
   451  // of how long it takes for a file modification to get a different
   452  // mtime.
   453  func (tg *testgoData) sleep() {
   454  	time.Sleep(mtimeTick)
   455  }
   456  
   457  // setenv sets an environment variable to use when running the test go
   458  // command.
   459  func (tg *testgoData) setenv(name, val string) {
   460  	tg.t.Helper()
   461  	tg.unsetenv(name)
   462  	tg.env = append(tg.env, name+"="+val)
   463  }
   464  
   465  // unsetenv removes an environment variable.
   466  func (tg *testgoData) unsetenv(name string) {
   467  	if tg.env == nil {
   468  		tg.env = append([]string(nil), os.Environ()...)
   469  		tg.env = append(tg.env, "GO111MODULE=off", "TESTGONETWORK=panic")
   470  		if testing.Short() {
   471  			tg.env = append(tg.env, "TESTGOVCSREMOTE=panic")
   472  		}
   473  	}
   474  	for i, v := range tg.env {
   475  		if strings.HasPrefix(v, name+"=") {
   476  			tg.env = slices.Delete(tg.env, i, i+1)
   477  			break
   478  		}
   479  	}
   480  }
   481  
   482  func (tg *testgoData) goTool() string {
   483  	return testGo
   484  }
   485  
   486  // doRun runs the test go command, recording stdout and stderr and
   487  // returning exit status.
   488  func (tg *testgoData) doRun(args []string) error {
   489  	tg.t.Helper()
   490  	if tg.inParallel {
   491  		for _, arg := range args {
   492  			if strings.HasPrefix(arg, "testdata") || strings.HasPrefix(arg, "./testdata") {
   493  				tg.t.Fatal("internal testsuite error: parallel run using testdata")
   494  			}
   495  		}
   496  	}
   497  
   498  	hasGoroot := false
   499  	for _, v := range tg.env {
   500  		if strings.HasPrefix(v, "GOROOT=") {
   501  			hasGoroot = true
   502  			break
   503  		}
   504  	}
   505  	prog := tg.goTool()
   506  	if !hasGoroot {
   507  		tg.setenv("GOROOT", testGOROOT)
   508  	}
   509  
   510  	tg.t.Logf("running testgo %v", args)
   511  	cmd := testenv.Command(tg.t, prog, args...)
   512  	tg.stdout.Reset()
   513  	tg.stderr.Reset()
   514  	cmd.Dir = tg.execDir
   515  	cmd.Stdout = &tg.stdout
   516  	cmd.Stderr = &tg.stderr
   517  	cmd.Env = tg.env
   518  	status := cmd.Run()
   519  	if tg.stdout.Len() > 0 {
   520  		tg.t.Log("standard output:")
   521  		tg.t.Log(tg.stdout.String())
   522  	}
   523  	if tg.stderr.Len() > 0 {
   524  		tg.t.Log("standard error:")
   525  		tg.t.Log(tg.stderr.String())
   526  	}
   527  	tg.ran = true
   528  	return status
   529  }
   530  
   531  // run runs the test go command, and expects it to succeed.
   532  func (tg *testgoData) run(args ...string) {
   533  	tg.t.Helper()
   534  	if status := tg.doRun(args); status != nil {
   535  		wd, _ := os.Getwd()
   536  		tg.t.Logf("go %v failed unexpectedly in %s: %v", args, wd, status)
   537  		tg.t.FailNow()
   538  	}
   539  }
   540  
   541  // runFail runs the test go command, and expects it to fail.
   542  func (tg *testgoData) runFail(args ...string) {
   543  	tg.t.Helper()
   544  	if status := tg.doRun(args); status == nil {
   545  		tg.t.Fatal("testgo succeeded unexpectedly")
   546  	} else {
   547  		tg.t.Log("testgo failed as expected:", status)
   548  	}
   549  }
   550  
   551  // getStdout returns standard output of the testgo run as a string.
   552  func (tg *testgoData) getStdout() string {
   553  	tg.t.Helper()
   554  	if !tg.ran {
   555  		tg.t.Fatal("internal testsuite error: stdout called before run")
   556  	}
   557  	return tg.stdout.String()
   558  }
   559  
   560  // getStderr returns standard error of the testgo run as a string.
   561  func (tg *testgoData) getStderr() string {
   562  	tg.t.Helper()
   563  	if !tg.ran {
   564  		tg.t.Fatal("internal testsuite error: stdout called before run")
   565  	}
   566  	return tg.stderr.String()
   567  }
   568  
   569  // doGrepMatch looks for a regular expression in a buffer, and returns
   570  // whether it is found. The regular expression is matched against
   571  // each line separately, as with the grep command.
   572  func (tg *testgoData) doGrepMatch(match string, b *bytes.Buffer) bool {
   573  	tg.t.Helper()
   574  	if !tg.ran {
   575  		tg.t.Fatal("internal testsuite error: grep called before run")
   576  	}
   577  	re := regexp.MustCompile(match)
   578  	for _, ln := range bytes.Split(b.Bytes(), []byte{'\n'}) {
   579  		if re.Match(ln) {
   580  			return true
   581  		}
   582  	}
   583  	return false
   584  }
   585  
   586  // doGrep looks for a regular expression in a buffer and fails if it
   587  // is not found. The name argument is the name of the output we are
   588  // searching, "output" or "error". The msg argument is logged on
   589  // failure.
   590  func (tg *testgoData) doGrep(match string, b *bytes.Buffer, name, msg string) {
   591  	tg.t.Helper()
   592  	if !tg.doGrepMatch(match, b) {
   593  		tg.t.Log(msg)
   594  		tg.t.Logf("pattern %v not found in standard %s", match, name)
   595  		tg.t.FailNow()
   596  	}
   597  }
   598  
   599  // grepStdout looks for a regular expression in the test run's
   600  // standard output and fails, logging msg, if it is not found.
   601  func (tg *testgoData) grepStdout(match, msg string) {
   602  	tg.t.Helper()
   603  	tg.doGrep(match, &tg.stdout, "output", msg)
   604  }
   605  
   606  // grepStderr looks for a regular expression in the test run's
   607  // standard error and fails, logging msg, if it is not found.
   608  func (tg *testgoData) grepStderr(match, msg string) {
   609  	tg.t.Helper()
   610  	tg.doGrep(match, &tg.stderr, "error", msg)
   611  }
   612  
   613  // grepBoth looks for a regular expression in the test run's standard
   614  // output or stand error and fails, logging msg, if it is not found.
   615  func (tg *testgoData) grepBoth(match, msg string) {
   616  	tg.t.Helper()
   617  	if !tg.doGrepMatch(match, &tg.stdout) && !tg.doGrepMatch(match, &tg.stderr) {
   618  		tg.t.Log(msg)
   619  		tg.t.Logf("pattern %v not found in standard output or standard error", match)
   620  		tg.t.FailNow()
   621  	}
   622  }
   623  
   624  // doGrepNot looks for a regular expression in a buffer and fails if
   625  // it is found. The name and msg arguments are as for doGrep.
   626  func (tg *testgoData) doGrepNot(match string, b *bytes.Buffer, name, msg string) {
   627  	tg.t.Helper()
   628  	if tg.doGrepMatch(match, b) {
   629  		tg.t.Log(msg)
   630  		tg.t.Logf("pattern %v found unexpectedly in standard %s", match, name)
   631  		tg.t.FailNow()
   632  	}
   633  }
   634  
   635  // grepStdoutNot looks for a regular expression in the test run's
   636  // standard output and fails, logging msg, if it is found.
   637  func (tg *testgoData) grepStdoutNot(match, msg string) {
   638  	tg.t.Helper()
   639  	tg.doGrepNot(match, &tg.stdout, "output", msg)
   640  }
   641  
   642  // grepStderrNot looks for a regular expression in the test run's
   643  // standard error and fails, logging msg, if it is found.
   644  func (tg *testgoData) grepStderrNot(match, msg string) {
   645  	tg.t.Helper()
   646  	tg.doGrepNot(match, &tg.stderr, "error", msg)
   647  }
   648  
   649  // grepBothNot looks for a regular expression in the test run's
   650  // standard output or standard error and fails, logging msg, if it is
   651  // found.
   652  func (tg *testgoData) grepBothNot(match, msg string) {
   653  	tg.t.Helper()
   654  	if tg.doGrepMatch(match, &tg.stdout) || tg.doGrepMatch(match, &tg.stderr) {
   655  		tg.t.Log(msg)
   656  		tg.t.Fatalf("pattern %v found unexpectedly in standard output or standard error", match)
   657  	}
   658  }
   659  
   660  // doGrepCount counts the number of times a regexp is seen in a buffer.
   661  func (tg *testgoData) doGrepCount(match string, b *bytes.Buffer) int {
   662  	tg.t.Helper()
   663  	if !tg.ran {
   664  		tg.t.Fatal("internal testsuite error: doGrepCount called before run")
   665  	}
   666  	re := regexp.MustCompile(match)
   667  	c := 0
   668  	for _, ln := range bytes.Split(b.Bytes(), []byte{'\n'}) {
   669  		if re.Match(ln) {
   670  			c++
   671  		}
   672  	}
   673  	return c
   674  }
   675  
   676  // grepCountBoth returns the number of times a regexp is seen in both
   677  // standard output and standard error.
   678  func (tg *testgoData) grepCountBoth(match string) int {
   679  	tg.t.Helper()
   680  	return tg.doGrepCount(match, &tg.stdout) + tg.doGrepCount(match, &tg.stderr)
   681  }
   682  
   683  // creatingTemp records that the test plans to create a temporary file
   684  // or directory. If the file or directory exists already, it will be
   685  // removed. When the test completes, the file or directory will be
   686  // removed if it exists.
   687  func (tg *testgoData) creatingTemp(path string) {
   688  	tg.t.Helper()
   689  	if filepath.IsAbs(path) && !strings.HasPrefix(path, tg.tempdir) {
   690  		tg.t.Fatalf("internal testsuite error: creatingTemp(%q) with absolute path not in temporary directory", path)
   691  	}
   692  	tg.must(robustio.RemoveAll(path))
   693  	tg.temps = append(tg.temps, path)
   694  }
   695  
   696  // makeTempdir makes a temporary directory for a run of testgo. If
   697  // the temporary directory was already created, this does nothing.
   698  func (tg *testgoData) makeTempdir() {
   699  	tg.t.Helper()
   700  	if tg.tempdir == "" {
   701  		var err error
   702  		tg.tempdir, err = os.MkdirTemp("", "gotest")
   703  		tg.must(err)
   704  	}
   705  }
   706  
   707  // tempFile adds a temporary file for a run of testgo.
   708  func (tg *testgoData) tempFile(path, contents string) {
   709  	tg.t.Helper()
   710  	tg.makeTempdir()
   711  	tg.must(os.MkdirAll(filepath.Join(tg.tempdir, filepath.Dir(path)), 0755))
   712  	bytes := []byte(contents)
   713  	if strings.HasSuffix(path, ".go") {
   714  		formatted, err := format.Source(bytes)
   715  		if err == nil {
   716  			bytes = formatted
   717  		}
   718  	}
   719  	tg.must(os.WriteFile(filepath.Join(tg.tempdir, path), bytes, 0644))
   720  }
   721  
   722  // tempDir adds a temporary directory for a run of testgo.
   723  func (tg *testgoData) tempDir(path string) {
   724  	tg.t.Helper()
   725  	tg.makeTempdir()
   726  	if err := os.MkdirAll(filepath.Join(tg.tempdir, path), 0755); err != nil && !os.IsExist(err) {
   727  		tg.t.Fatal(err)
   728  	}
   729  }
   730  
   731  // path returns the absolute pathname to file with the temporary
   732  // directory.
   733  func (tg *testgoData) path(name string) string {
   734  	tg.t.Helper()
   735  	if tg.tempdir == "" {
   736  		tg.t.Fatalf("internal testsuite error: path(%q) with no tempdir", name)
   737  	}
   738  	if name == "." {
   739  		return tg.tempdir
   740  	}
   741  	return filepath.Join(tg.tempdir, name)
   742  }
   743  
   744  // mustExist fails if path does not exist.
   745  func (tg *testgoData) mustExist(path string) {
   746  	tg.t.Helper()
   747  	if _, err := os.Stat(path); err != nil {
   748  		if os.IsNotExist(err) {
   749  			tg.t.Fatalf("%s does not exist but should", path)
   750  		}
   751  		tg.t.Fatalf("%s stat failed: %v", path, err)
   752  	}
   753  }
   754  
   755  // mustNotExist fails if path exists.
   756  func (tg *testgoData) mustNotExist(path string) {
   757  	tg.t.Helper()
   758  	if _, err := os.Stat(path); err == nil || !os.IsNotExist(err) {
   759  		tg.t.Fatalf("%s exists but should not (%v)", path, err)
   760  	}
   761  }
   762  
   763  // wantExecutable fails with msg if path is not executable.
   764  func (tg *testgoData) wantExecutable(path, msg string) {
   765  	tg.t.Helper()
   766  	if st, err := os.Stat(path); err != nil {
   767  		if !os.IsNotExist(err) {
   768  			tg.t.Log(err)
   769  		}
   770  		tg.t.Fatal(msg)
   771  	} else {
   772  		if runtime.GOOS != "windows" && st.Mode()&0111 == 0 {
   773  			tg.t.Fatalf("binary %s exists but is not executable", path)
   774  		}
   775  	}
   776  }
   777  
   778  // isStale reports whether pkg is stale, and why
   779  func (tg *testgoData) isStale(pkg string) (bool, string) {
   780  	tg.t.Helper()
   781  	tg.run("list", "-f", "{{.Stale}}:{{.StaleReason}}", pkg)
   782  	v := strings.TrimSpace(tg.getStdout())
   783  	f := strings.SplitN(v, ":", 2)
   784  	if len(f) == 2 {
   785  		switch f[0] {
   786  		case "true":
   787  			return true, f[1]
   788  		case "false":
   789  			return false, f[1]
   790  		}
   791  	}
   792  	tg.t.Fatalf("unexpected output checking staleness of package %v: %v", pkg, v)
   793  	panic("unreachable")
   794  }
   795  
   796  // wantStale fails with msg if pkg is not stale.
   797  func (tg *testgoData) wantStale(pkg, reason, msg string) {
   798  	tg.t.Helper()
   799  	stale, why := tg.isStale(pkg)
   800  	if !stale {
   801  		tg.t.Fatal(msg)
   802  	}
   803  	// We always accept the reason as being "not installed but
   804  	// available in build cache", because when that is the case go
   805  	// list doesn't try to sort out the underlying reason why the
   806  	// package is not installed.
   807  	if reason == "" && why != "" || !strings.Contains(why, reason) && !strings.Contains(why, "not installed but available in build cache") {
   808  		tg.t.Errorf("wrong reason for Stale=true: %q, want %q", why, reason)
   809  	}
   810  }
   811  
   812  // wantNotStale fails with msg if pkg is stale.
   813  func (tg *testgoData) wantNotStale(pkg, reason, msg string) {
   814  	tg.t.Helper()
   815  	stale, why := tg.isStale(pkg)
   816  	if stale {
   817  		tg.t.Fatal(msg)
   818  	}
   819  	if reason == "" && why != "" || !strings.Contains(why, reason) {
   820  		tg.t.Errorf("wrong reason for Stale=false: %q, want %q", why, reason)
   821  	}
   822  }
   823  
   824  // If -testwork is specified, the test prints the name of the temp directory
   825  // and does not remove it when done, so that a programmer can
   826  // poke at the test file tree afterward.
   827  var testWork = flag.Bool("testwork", false, "")
   828  
   829  // cleanup cleans up a test that runs testgo.
   830  func (tg *testgoData) cleanup() {
   831  	tg.t.Helper()
   832  	if *testWork {
   833  		if tg.tempdir != "" {
   834  			tg.t.Logf("TESTWORK=%s\n", tg.path("."))
   835  		}
   836  		return
   837  	}
   838  	for _, path := range tg.temps {
   839  		tg.check(removeAll(path))
   840  	}
   841  	if tg.tempdir != "" {
   842  		tg.check(removeAll(tg.tempdir))
   843  	}
   844  }
   845  
   846  func removeAll(dir string) error {
   847  	// module cache has 0444 directories;
   848  	// make them writable in order to remove content.
   849  	filepath.WalkDir(dir, func(path string, info fs.DirEntry, err error) error {
   850  		// chmod not only directories, but also things that we couldn't even stat
   851  		// due to permission errors: they may also be unreadable directories.
   852  		if err != nil || info.IsDir() {
   853  			os.Chmod(path, 0777)
   854  		}
   855  		return nil
   856  	})
   857  	return robustio.RemoveAll(dir)
   858  }
   859  
   860  func TestNewReleaseRebuildsStalePackagesInGOPATH(t *testing.T) {
   861  	if testing.Short() {
   862  		t.Skip("skipping lengthy test in short mode")
   863  	}
   864  
   865  	tg := testgo(t)
   866  	defer tg.cleanup()
   867  	tg.parallel()
   868  
   869  	// Set GOCACHE to an empty directory so that a previous run of
   870  	// this test does not affect the staleness of the packages it builds.
   871  	tg.tempDir("gocache")
   872  	tg.setenv("GOCACHE", tg.path("gocache"))
   873  
   874  	// Copy the runtime packages into a temporary GOROOT
   875  	// so that we can change files.
   876  	var dirs []string
   877  	tg.run("list", "-deps", "runtime")
   878  	pkgs := strings.Split(strings.TrimSpace(tg.getStdout()), "\n")
   879  	for _, pkg := range pkgs {
   880  		dirs = append(dirs, filepath.Join("src", pkg))
   881  	}
   882  	dirs = append(dirs,
   883  		filepath.Join("pkg/tool", goHostOS+"_"+goHostArch),
   884  		"pkg/include",
   885  	)
   886  	for _, copydir := range dirs {
   887  		srcdir := filepath.Join(testGOROOT, copydir)
   888  		tg.tempDir(filepath.Join("goroot", copydir))
   889  		err := filepath.WalkDir(srcdir,
   890  			func(path string, info fs.DirEntry, err error) error {
   891  				if err != nil {
   892  					return err
   893  				}
   894  				if info.IsDir() {
   895  					return nil
   896  				}
   897  				srcrel, err := filepath.Rel(srcdir, path)
   898  				if err != nil {
   899  					return err
   900  				}
   901  				dest := filepath.Join("goroot", copydir, srcrel)
   902  				if _, err := os.Stat(dest); err == nil {
   903  					return nil
   904  				}
   905  				data, err := os.ReadFile(path)
   906  				if err != nil {
   907  					return err
   908  				}
   909  				tg.tempFile(dest, string(data))
   910  				if strings.Contains(copydir, filepath.Join("pkg", "tool")) {
   911  					os.Chmod(tg.path(dest), 0777)
   912  				}
   913  				return nil
   914  			})
   915  		if err != nil {
   916  			t.Fatal(err)
   917  		}
   918  	}
   919  	tg.setenv("GOROOT", tg.path("goroot"))
   920  
   921  	addVar := func(name string, idx int) (restore func()) {
   922  		data, err := os.ReadFile(name)
   923  		if err != nil {
   924  			t.Fatal(err)
   925  		}
   926  		old := data
   927  		data = append(data, fmt.Sprintf("var DummyUnusedVar%d bool\n", idx)...)
   928  		if err := os.WriteFile(name, append(data, '\n'), 0666); err != nil {
   929  			t.Fatal(err)
   930  		}
   931  		tg.sleep()
   932  		return func() {
   933  			if err := os.WriteFile(name, old, 0666); err != nil {
   934  				t.Fatal(err)
   935  			}
   936  		}
   937  	}
   938  
   939  	// Every main package depends on the "runtime".
   940  	tg.tempFile("d1/src/p1/p1.go", `package main; func main(){}`)
   941  	tg.setenv("GOPATH", tg.path("d1"))
   942  	// Pass -i flag to rebuild everything outdated.
   943  	tg.run("install", "p1")
   944  	tg.wantNotStale("p1", "", "./testgo list claims p1 is stale, incorrectly, before any changes")
   945  
   946  	// Changing mtime of internal/runtime/sys/sys.go
   947  	// should have no effect: only the content matters.
   948  	// In fact this should be true even outside a release branch.
   949  	sys := tg.path("goroot/src/internal/runtime/sys/sys.go")
   950  	tg.sleep()
   951  	restore := addVar(sys, 0)
   952  	restore()
   953  	tg.wantNotStale("p1", "", "./testgo list claims p1 is stale, incorrectly, after updating mtime of internal/runtime/sys/sys.go")
   954  
   955  	// But changing content of any file should have an effect.
   956  	// Previously zversion.go was the only one that mattered;
   957  	// now they all matter, so keep using sys.go.
   958  	restore = addVar(sys, 1)
   959  	defer restore()
   960  	tg.wantStale("p1", "stale dependency: internal/runtime/sys", "./testgo list claims p1 is NOT stale, incorrectly, after changing sys.go")
   961  	restore()
   962  	tg.wantNotStale("p1", "", "./testgo list claims p1 is stale, incorrectly, after changing back to old release")
   963  	addVar(sys, 2)
   964  	tg.wantStale("p1", "stale dependency: internal/runtime/sys", "./testgo list claims p1 is NOT stale, incorrectly, after changing sys.go again")
   965  	tg.run("install", "p1")
   966  	tg.wantNotStale("p1", "", "./testgo list claims p1 is stale after building with new release")
   967  
   968  	// Restore to "old" release.
   969  	restore()
   970  	tg.wantStale("p1", "not installed but available in build cache", "./testgo list claims p1 is NOT stale, incorrectly, after restoring sys.go")
   971  	tg.run("install", "p1")
   972  	tg.wantNotStale("p1", "", "./testgo list claims p1 is stale after building with old release")
   973  }
   974  
   975  func TestPackageMainTestCompilerFlags(t *testing.T) {
   976  	tg := testgo(t)
   977  	defer tg.cleanup()
   978  	tg.parallel()
   979  	tg.makeTempdir()
   980  	tg.setenv("GOPATH", tg.path("."))
   981  	tg.tempFile("src/p1/p1.go", "package main\n")
   982  	tg.tempFile("src/p1/p1_test.go", "package main\nimport \"testing\"\nfunc Test(t *testing.T){}\n")
   983  	tg.run("test", "-c", "-n", "p1")
   984  	tg.grepBothNot(`([\\/]compile|gccgo).* (-p main|-fgo-pkgpath=main).*p1\.go`, "should not have run compile -p main p1.go")
   985  	tg.grepStderr(`([\\/]compile|gccgo).* (-p p1|-fgo-pkgpath=p1).*p1\.go`, "should have run compile -p p1 p1.go")
   986  }
   987  
   988  // Issue 4104.
   989  func TestGoTestWithPackageListedMultipleTimes(t *testing.T) {
   990  	tooSlow(t, "links and runs a test")
   991  
   992  	tg := testgo(t)
   993  	defer tg.cleanup()
   994  	tg.parallel()
   995  	tg.run("test", "errors", "errors", "errors", "errors", "errors")
   996  	if strings.Contains(strings.TrimSpace(tg.getStdout()), "\n") {
   997  		t.Error("go test errors errors errors errors errors tested the same package multiple times")
   998  	}
   999  }
  1000  
  1001  func TestGoListHasAConsistentOrder(t *testing.T) {
  1002  	tooSlow(t, "walks all of GOROOT/src twice")
  1003  
  1004  	tg := testgo(t)
  1005  	defer tg.cleanup()
  1006  	tg.parallel()
  1007  	tg.run("list", "std")
  1008  	first := tg.getStdout()
  1009  	tg.run("list", "std")
  1010  	if first != tg.getStdout() {
  1011  		t.Error("go list std ordering is inconsistent")
  1012  	}
  1013  }
  1014  
  1015  func TestGoListStdDoesNotIncludeCommands(t *testing.T) {
  1016  	tooSlow(t, "walks all of GOROOT/src")
  1017  
  1018  	tg := testgo(t)
  1019  	defer tg.cleanup()
  1020  	tg.parallel()
  1021  	tg.run("list", "std")
  1022  	tg.grepStdoutNot("cmd/", "go list std shows commands")
  1023  }
  1024  
  1025  func TestGoListCmdOnlyShowsCommands(t *testing.T) {
  1026  	skipIfGccgo(t, "gccgo does not have GOROOT")
  1027  	tooSlow(t, "walks all of GOROOT/src/cmd")
  1028  
  1029  	tg := testgo(t)
  1030  	defer tg.cleanup()
  1031  	tg.parallel()
  1032  	tg.run("list", "cmd")
  1033  	out := strings.TrimSpace(tg.getStdout())
  1034  	for _, line := range strings.Split(out, "\n") {
  1035  		if !strings.Contains(line, "cmd/") {
  1036  			t.Error("go list cmd shows non-commands")
  1037  			break
  1038  		}
  1039  	}
  1040  }
  1041  
  1042  func TestGoListDeps(t *testing.T) {
  1043  	tg := testgo(t)
  1044  	defer tg.cleanup()
  1045  	tg.parallel()
  1046  	tg.tempDir("src/p1/p2/p3/p4")
  1047  	tg.setenv("GOPATH", tg.path("."))
  1048  	tg.tempFile("src/p1/p.go", "package p1\nimport _ \"p1/p2\"\n")
  1049  	tg.tempFile("src/p1/p2/p.go", "package p2\nimport _ \"p1/p2/p3\"\n")
  1050  	tg.tempFile("src/p1/p2/p3/p.go", "package p3\nimport _ \"p1/p2/p3/p4\"\n")
  1051  	tg.tempFile("src/p1/p2/p3/p4/p.go", "package p4\n")
  1052  	tg.run("list", "-f", "{{.Deps}}", "p1")
  1053  	tg.grepStdout("p1/p2/p3/p4", "Deps(p1) does not mention p4")
  1054  
  1055  	tg.run("list", "-deps", "p1")
  1056  	tg.grepStdout("p1/p2/p3/p4", "-deps p1 does not mention p4")
  1057  
  1058  	if runtime.Compiler != "gccgo" {
  1059  		// Check the list is in dependency order.
  1060  		tg.run("list", "-deps", "math")
  1061  		want := "unsafe\ninternal/cpu\nmath/bits\nmath\n"
  1062  		out := tg.stdout.String()
  1063  		if !strings.Contains(out, "internal/cpu") {
  1064  			// Some systems don't use internal/cpu.
  1065  			want = "unsafe\nmath/bits\nmath\n"
  1066  		}
  1067  		if tg.stdout.String() != want {
  1068  			t.Fatalf("list -deps math: wrong order\nhave %q\nwant %q", tg.stdout.String(), want)
  1069  		}
  1070  	}
  1071  }
  1072  
  1073  func TestGoListTest(t *testing.T) {
  1074  	skipIfGccgo(t, "gccgo does not have standard packages")
  1075  	tg := testgo(t)
  1076  	defer tg.cleanup()
  1077  	tg.parallel()
  1078  	tg.makeTempdir()
  1079  	tg.setenv("GOCACHE", tg.tempdir)
  1080  
  1081  	tg.run("list", "-test", "-deps", "bytes")
  1082  	tg.grepStdout(`^bytes.test$`, "missing test main")
  1083  	tg.grepStdout(`^bytes$`, "missing real bytes")
  1084  	tg.grepStdout(`^bytes \[bytes.test\]$`, "missing test copy of bytes")
  1085  	tg.grepStdout(`^testing \[bytes.test\]$`, "missing test copy of testing")
  1086  	tg.grepStdoutNot(`^testing$`, "unexpected real copy of testing")
  1087  
  1088  	tg.run("list", "-test", "bytes")
  1089  	tg.grepStdout(`^bytes.test$`, "missing test main")
  1090  	tg.grepStdout(`^bytes$`, "missing real bytes")
  1091  	tg.grepStdout(`^bytes \[bytes.test\]$`, "unexpected test copy of bytes")
  1092  	tg.grepStdoutNot(`^testing \[bytes.test\]$`, "unexpected test copy of testing")
  1093  	tg.grepStdoutNot(`^testing$`, "unexpected real copy of testing")
  1094  
  1095  	tg.run("list", "-test", "cmd/buildid", "cmd/gofmt")
  1096  	tg.grepStdout(`^cmd/buildid$`, "missing cmd/buildid")
  1097  	tg.grepStdout(`^cmd/gofmt$`, "missing cmd/gofmt")
  1098  	tg.grepStdout(`^cmd/gofmt\.test$`, "missing cmd/gofmt test")
  1099  	tg.grepStdoutNot(`^cmd/buildid\.test$`, "unexpected cmd/buildid test")
  1100  	tg.grepStdoutNot(`^testing`, "unexpected testing")
  1101  
  1102  	tg.run("list", "-test", "runtime/cgo")
  1103  	tg.grepStdout(`^runtime/cgo$`, "missing runtime/cgo")
  1104  
  1105  	tg.run("list", "-deps", "-f", "{{if .DepOnly}}{{.ImportPath}}{{end}}", "sort")
  1106  	tg.grepStdout(`^internal/reflectlite$`, "missing internal/reflectlite")
  1107  	tg.grepStdoutNot(`^sort`, "unexpected sort")
  1108  }
  1109  
  1110  func TestGoListCompiledCgo(t *testing.T) {
  1111  	tooSlow(t, "compiles cgo files")
  1112  
  1113  	tg := testgo(t)
  1114  	defer tg.cleanup()
  1115  	tg.parallel()
  1116  	tg.makeTempdir()
  1117  	tg.setenv("GOCACHE", tg.tempdir)
  1118  
  1119  	tg.run("list", "-f", `{{join .CgoFiles "\n"}}`, "net")
  1120  	if tg.stdout.String() == "" {
  1121  		t.Skip("net does not use cgo")
  1122  	}
  1123  	if strings.Contains(tg.stdout.String(), tg.tempdir) {
  1124  		t.Fatalf(".CgoFiles unexpectedly mentioned cache %s", tg.tempdir)
  1125  	}
  1126  	tg.run("list", "-compiled", "-f", `{{.Dir}}{{"\n"}}{{join .CompiledGoFiles "\n"}}`, "net")
  1127  	if !strings.Contains(tg.stdout.String(), tg.tempdir) {
  1128  		t.Fatalf(".CompiledGoFiles with -compiled did not mention cache %s", tg.tempdir)
  1129  	}
  1130  	dir := ""
  1131  	for _, file := range strings.Split(tg.stdout.String(), "\n") {
  1132  		if file == "" {
  1133  			continue
  1134  		}
  1135  		if dir == "" {
  1136  			dir = file
  1137  			continue
  1138  		}
  1139  		if !strings.Contains(file, "/") && !strings.Contains(file, `\`) {
  1140  			file = filepath.Join(dir, file)
  1141  		}
  1142  		if _, err := os.Stat(file); err != nil {
  1143  			t.Fatalf("cannot find .CompiledGoFiles result %s: %v", file, err)
  1144  		}
  1145  	}
  1146  }
  1147  
  1148  func TestGoListExport(t *testing.T) {
  1149  	tooSlow(t, "runs build for -export")
  1150  
  1151  	skipIfGccgo(t, "gccgo does not have standard packages")
  1152  	tg := testgo(t)
  1153  	defer tg.cleanup()
  1154  	tg.parallel()
  1155  	tg.makeTempdir()
  1156  	tg.setenv("GOCACHE", tg.tempdir)
  1157  
  1158  	tg.run("list", "-f", "{{.Export}}", "strings")
  1159  	if tg.stdout.String() != "" {
  1160  		t.Fatalf(".Export without -export unexpectedly set")
  1161  	}
  1162  	tg.run("list", "-export", "-f", "{{.Export}}", "strings")
  1163  	file := strings.TrimSpace(tg.stdout.String())
  1164  	if file == "" {
  1165  		t.Fatalf(".Export with -export was empty")
  1166  	}
  1167  	if _, err := os.Stat(file); err != nil {
  1168  		t.Fatalf("cannot find .Export result %s: %v", file, err)
  1169  	}
  1170  
  1171  	tg.run("list", "-export", "-f", "{{.BuildID}}", "strings")
  1172  	buildID := strings.TrimSpace(tg.stdout.String())
  1173  	if buildID == "" {
  1174  		t.Fatalf(".BuildID with -export was empty")
  1175  	}
  1176  
  1177  	tg.run("tool", "buildid", file)
  1178  	toolBuildID := strings.TrimSpace(tg.stdout.String())
  1179  	if buildID != toolBuildID {
  1180  		t.Fatalf(".BuildID with -export %q disagrees with 'go tool buildid' %q", buildID, toolBuildID)
  1181  	}
  1182  }
  1183  
  1184  // Issue 4096. Validate the output of unsuccessful go install foo/quxx.
  1185  func TestUnsuccessfulGoInstallShouldMentionMissingPackage(t *testing.T) {
  1186  	tg := testgo(t)
  1187  	defer tg.cleanup()
  1188  	tg.parallel()
  1189  	tg.runFail("install", "foo/quxx")
  1190  	if tg.grepCountBoth(`cannot find package "foo/quxx" in any of`) != 1 {
  1191  		t.Error(`go install foo/quxx expected error: .*cannot find package "foo/quxx" in any of`)
  1192  	}
  1193  }
  1194  
  1195  func TestGOROOTSearchFailureReporting(t *testing.T) {
  1196  	tg := testgo(t)
  1197  	defer tg.cleanup()
  1198  	tg.parallel()
  1199  	tg.runFail("install", "foo/quxx")
  1200  	if tg.grepCountBoth(regexp.QuoteMeta(filepath.Join("foo", "quxx"))+` \(from \$GOROOT\)$`) != 1 {
  1201  		t.Error(`go install foo/quxx expected error: .*foo/quxx (from $GOROOT)`)
  1202  	}
  1203  }
  1204  
  1205  func TestMultipleGOPATHEntriesReportedSeparately(t *testing.T) {
  1206  	tg := testgo(t)
  1207  	defer tg.cleanup()
  1208  	tg.parallel()
  1209  	sep := string(filepath.ListSeparator)
  1210  	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata", "a")+sep+filepath.Join(tg.pwd(), "testdata", "b"))
  1211  	tg.runFail("install", "foo/quxx")
  1212  	if tg.grepCountBoth(`testdata[/\\].[/\\]src[/\\]foo[/\\]quxx`) != 2 {
  1213  		t.Error(`go install foo/quxx expected error: .*testdata/a/src/foo/quxx (from $GOPATH)\n.*testdata/b/src/foo/quxx`)
  1214  	}
  1215  }
  1216  
  1217  // Test (from $GOPATH) annotation is reported for the first GOPATH entry,
  1218  func TestMentionGOPATHInFirstGOPATHEntry(t *testing.T) {
  1219  	tg := testgo(t)
  1220  	defer tg.cleanup()
  1221  	tg.parallel()
  1222  	sep := string(filepath.ListSeparator)
  1223  	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata", "a")+sep+filepath.Join(tg.pwd(), "testdata", "b"))
  1224  	tg.runFail("install", "foo/quxx")
  1225  	if tg.grepCountBoth(regexp.QuoteMeta(filepath.Join("testdata", "a", "src", "foo", "quxx"))+` \(from \$GOPATH\)$`) != 1 {
  1226  		t.Error(`go install foo/quxx expected error: .*testdata/a/src/foo/quxx (from $GOPATH)`)
  1227  	}
  1228  }
  1229  
  1230  // but not on the second.
  1231  func TestMentionGOPATHNotOnSecondEntry(t *testing.T) {
  1232  	tg := testgo(t)
  1233  	defer tg.cleanup()
  1234  	tg.parallel()
  1235  	sep := string(filepath.ListSeparator)
  1236  	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata", "a")+sep+filepath.Join(tg.pwd(), "testdata", "b"))
  1237  	tg.runFail("install", "foo/quxx")
  1238  	if tg.grepCountBoth(regexp.QuoteMeta(filepath.Join("testdata", "b", "src", "foo", "quxx"))+`$`) != 1 {
  1239  		t.Error(`go install foo/quxx expected error: .*testdata/b/src/foo/quxx`)
  1240  	}
  1241  }
  1242  
  1243  func homeEnvName() string {
  1244  	switch runtime.GOOS {
  1245  	case "windows":
  1246  		return "USERPROFILE"
  1247  	case "plan9":
  1248  		return "home"
  1249  	default:
  1250  		return "HOME"
  1251  	}
  1252  }
  1253  
  1254  func tempEnvName() string {
  1255  	switch runtime.GOOS {
  1256  	case "windows":
  1257  		return "TMP"
  1258  	case "plan9":
  1259  		return "TMPDIR" // actually plan 9 doesn't have one at all but this is fine
  1260  	default:
  1261  		return "TMPDIR"
  1262  	}
  1263  }
  1264  
  1265  func pathEnvName() string {
  1266  	switch runtime.GOOS {
  1267  	case "plan9":
  1268  		return "path"
  1269  	default:
  1270  		return "PATH"
  1271  	}
  1272  }
  1273  
  1274  func TestDefaultGOPATH(t *testing.T) {
  1275  	tg := testgo(t)
  1276  	defer tg.cleanup()
  1277  	tg.parallel()
  1278  	tg.tempDir("home/go")
  1279  	tg.setenv(homeEnvName(), tg.path("home"))
  1280  	// Set TEST_TELEMETRY_DIR to a path that doesn't exist
  1281  	// so that the counter uploading code doesn't write
  1282  	// the counter token file to the temp dir after the test finishes.
  1283  	tg.setenv("TEST_TELEMETRY_DIR", "/no-telemetry-dir")
  1284  
  1285  	tg.run("env", "GOPATH")
  1286  	tg.grepStdout(regexp.QuoteMeta(tg.path("home/go")), "want GOPATH=$HOME/go")
  1287  
  1288  	tg.setenv("GOROOT", tg.path("home/go"))
  1289  	tg.run("env", "GOPATH")
  1290  	tg.grepStdoutNot(".", "want unset GOPATH because GOROOT=$HOME/go")
  1291  
  1292  	tg.setenv("GOROOT", tg.path("home/go")+"/")
  1293  	tg.run("env", "GOPATH")
  1294  	tg.grepStdoutNot(".", "want unset GOPATH because GOROOT=$HOME/go/")
  1295  }
  1296  
  1297  func TestDefaultGOPATHPrintedSearchList(t *testing.T) {
  1298  	tg := testgo(t)
  1299  	defer tg.cleanup()
  1300  	tg.parallel()
  1301  	tg.setenv("GOPATH", "")
  1302  	tg.tempDir("home")
  1303  	tg.setenv(homeEnvName(), tg.path("home"))
  1304  	// Set TEST_TELEMETRY_DIR to a path that doesn't exist
  1305  	// so that the counter uploading code doesn't write
  1306  	// the counter token file to the temp dir after the test finishes.
  1307  	tg.setenv("TEST_TELEMETRY_DIR", "/no-telemetry-dir")
  1308  
  1309  	tg.runFail("install", "github.com/golang/example/hello")
  1310  	tg.grepStderr(regexp.QuoteMeta(tg.path("home/go/src/github.com/golang/example/hello"))+`.*from \$GOPATH`, "expected default GOPATH")
  1311  }
  1312  
  1313  func TestLdflagsArgumentsWithSpacesIssue3941(t *testing.T) {
  1314  	skipIfGccgo(t, "gccgo does not support -ldflags -X")
  1315  	tooSlow(t, "compiles and links a binary")
  1316  
  1317  	tg := testgo(t)
  1318  	defer tg.cleanup()
  1319  	tg.parallel()
  1320  	tg.tempFile("main.go", `package main
  1321  		var extern string
  1322  		func main() {
  1323  			println(extern)
  1324  		}`)
  1325  	tg.run("run", "-ldflags", `-X "main.extern=hello world"`, tg.path("main.go"))
  1326  	tg.grepStderr("^hello world", `ldflags -X "main.extern=hello world"' failed`)
  1327  }
  1328  
  1329  func TestLdFlagsLongArgumentsIssue42295(t *testing.T) {
  1330  	// Test the extremely long command line arguments that contain '\n' characters
  1331  	// get encoded and passed correctly.
  1332  	skipIfGccgo(t, "gccgo does not support -ldflags -X")
  1333  	tooSlow(t, "compiles and links a binary")
  1334  
  1335  	tg := testgo(t)
  1336  	defer tg.cleanup()
  1337  	tg.parallel()
  1338  	tg.tempFile("main.go", `package main
  1339  		var extern string
  1340  		func main() {
  1341  			print(extern)
  1342  		}`)
  1343  	testStr := "test test test test test \n\\ "
  1344  	var buf strings.Builder
  1345  	for buf.Len() < sys.ExecArgLengthLimit+1 {
  1346  		buf.WriteString(testStr)
  1347  	}
  1348  	tg.run("run", "-ldflags", fmt.Sprintf(`-X "main.extern=%s"`, buf.String()), tg.path("main.go"))
  1349  	if tg.stderr.String() != buf.String() {
  1350  		t.Errorf("strings differ")
  1351  	}
  1352  }
  1353  
  1354  func TestGoTestDashCDashOControlsBinaryLocation(t *testing.T) {
  1355  	skipIfGccgo(t, "gccgo has no standard packages")
  1356  	tooSlow(t, "compiles and links a test binary")
  1357  
  1358  	tg := testgo(t)
  1359  	defer tg.cleanup()
  1360  	tg.parallel()
  1361  	tg.makeTempdir()
  1362  	tg.run("test", "-c", "-o", tg.path("myerrors.test"+exeSuffix), "errors")
  1363  	tg.wantExecutable(tg.path("myerrors.test"+exeSuffix), "go test -c -o myerrors.test did not create myerrors.test")
  1364  }
  1365  
  1366  func TestGoTestDashOWritesBinary(t *testing.T) {
  1367  	skipIfGccgo(t, "gccgo has no standard packages")
  1368  	tooSlow(t, "compiles and runs a test binary")
  1369  
  1370  	tg := testgo(t)
  1371  	defer tg.cleanup()
  1372  	tg.parallel()
  1373  	tg.makeTempdir()
  1374  	tg.run("test", "-o", tg.path("myerrors.test"+exeSuffix), "errors")
  1375  	tg.wantExecutable(tg.path("myerrors.test"+exeSuffix), "go test -o myerrors.test did not create myerrors.test")
  1376  }
  1377  
  1378  // Issue 4515.
  1379  func TestInstallWithTags(t *testing.T) {
  1380  	tooSlow(t, "compiles and links binaries")
  1381  
  1382  	tg := testgo(t)
  1383  	defer tg.cleanup()
  1384  	tg.parallel()
  1385  	tg.tempDir("bin")
  1386  	tg.tempFile("src/example/a/main.go", `package main
  1387  		func main() {}`)
  1388  	tg.tempFile("src/example/b/main.go", `// +build mytag
  1389  
  1390  		package main
  1391  		func main() {}`)
  1392  	tg.setenv("GOPATH", tg.path("."))
  1393  	tg.run("install", "-tags", "mytag", "example/a", "example/b")
  1394  	tg.wantExecutable(tg.path("bin/a"+exeSuffix), "go install example/a example/b did not install binaries")
  1395  	tg.wantExecutable(tg.path("bin/b"+exeSuffix), "go install example/a example/b did not install binaries")
  1396  	tg.must(os.Remove(tg.path("bin/a" + exeSuffix)))
  1397  	tg.must(os.Remove(tg.path("bin/b" + exeSuffix)))
  1398  	tg.run("install", "-tags", "mytag", "example/...")
  1399  	tg.wantExecutable(tg.path("bin/a"+exeSuffix), "go install example/... did not install binaries")
  1400  	tg.wantExecutable(tg.path("bin/b"+exeSuffix), "go install example/... did not install binaries")
  1401  	tg.run("list", "-tags", "mytag", "example/b...")
  1402  	if strings.TrimSpace(tg.getStdout()) != "example/b" {
  1403  		t.Error("go list example/b did not find example/b")
  1404  	}
  1405  }
  1406  
  1407  // Issue 17451, 17662.
  1408  func TestSymlinkWarning(t *testing.T) {
  1409  	tg := testgo(t)
  1410  	defer tg.cleanup()
  1411  	tg.parallel()
  1412  	tg.makeTempdir()
  1413  	tg.setenv("GOPATH", tg.path("."))
  1414  
  1415  	tg.tempDir("src/example/xx")
  1416  	tg.tempDir("yy/zz")
  1417  	tg.tempFile("yy/zz/zz.go", "package zz\n")
  1418  	if err := os.Symlink(tg.path("yy"), tg.path("src/example/xx/yy")); err != nil {
  1419  		t.Skipf("symlink failed: %v", err)
  1420  	}
  1421  	tg.run("list", "example/xx/z...")
  1422  	tg.grepStdoutNot(".", "list should not have matched anything")
  1423  	tg.grepStderr("matched no packages", "list should have reported that pattern matched no packages")
  1424  	tg.grepStderrNot("symlink", "list should not have reported symlink")
  1425  
  1426  	tg.run("list", "example/xx/...")
  1427  	tg.grepStdoutNot(".", "list should not have matched anything")
  1428  	tg.grepStderr("matched no packages", "list should have reported that pattern matched no packages")
  1429  	tg.grepStderr("ignoring symlink", "list should have reported symlink")
  1430  }
  1431  
  1432  func TestCgoShowsFullPathNames(t *testing.T) {
  1433  	testenv.MustHaveCGO(t)
  1434  
  1435  	tg := testgo(t)
  1436  	defer tg.cleanup()
  1437  	tg.parallel()
  1438  	tg.tempFile("src/x/y/dirname/foo.go", `
  1439  		package foo
  1440  		import "C"
  1441  		func f() {`)
  1442  	tg.setenv("GOPATH", tg.path("."))
  1443  	tg.runFail("build", "x/y/dirname")
  1444  	tg.grepBoth("x/y/dirname", "error did not use full path")
  1445  }
  1446  
  1447  func TestCgoHandlesWlORIGIN(t *testing.T) {
  1448  	tooSlow(t, "compiles cgo files")
  1449  	testenv.MustHaveCGO(t)
  1450  
  1451  	tg := testgo(t)
  1452  	defer tg.cleanup()
  1453  	tg.parallel()
  1454  	tg.tempFile("src/origin/origin.go", `package origin
  1455  		// #cgo !darwin,!windows LDFLAGS: -Wl,-rpath,$ORIGIN
  1456  		// void f(void) {}
  1457  		import "C"
  1458  		func f() { C.f() }`)
  1459  	tg.setenv("GOPATH", tg.path("."))
  1460  	tg.run("build", "origin")
  1461  }
  1462  
  1463  func TestCgoPkgConfig(t *testing.T) {
  1464  	tooSlow(t, "compiles cgo files")
  1465  	testenv.MustHaveCGO(t)
  1466  
  1467  	tg := testgo(t)
  1468  	defer tg.cleanup()
  1469  	tg.parallel()
  1470  
  1471  	tg.run("env", "PKG_CONFIG")
  1472  	pkgConfig := strings.TrimSpace(tg.getStdout())
  1473  	testenv.MustHaveExecPath(t, pkgConfig)
  1474  	if out, err := testenv.Command(t, pkgConfig, "--atleast-pkgconfig-version", "0.24").CombinedOutput(); err != nil {
  1475  		t.Skipf("%s --atleast-pkgconfig-version 0.24: %v\n%s", pkgConfig, err, out)
  1476  	}
  1477  
  1478  	// OpenBSD's pkg-config is strict about whitespace and only
  1479  	// supports backslash-escaped whitespace. It does not support
  1480  	// quotes, which the normal freedesktop.org pkg-config does
  1481  	// support. See https://man.openbsd.org/pkg-config.1
  1482  	tg.tempFile("foo.pc", `
  1483  Name: foo
  1484  Description: The foo library
  1485  Version: 1.0.0
  1486  Cflags: -Dhello=10 -Dworld=+32 -DDEFINED_FROM_PKG_CONFIG=hello\ world
  1487  `)
  1488  	tg.tempFile("foo.go", `package main
  1489  
  1490  /*
  1491  #cgo pkg-config: foo
  1492  int value() {
  1493  	return DEFINED_FROM_PKG_CONFIG;
  1494  }
  1495  */
  1496  import "C"
  1497  import "os"
  1498  
  1499  func main() {
  1500  	if C.value() != 42 {
  1501  		println("value() =", C.value(), "wanted 42")
  1502  		os.Exit(1)
  1503  	}
  1504  }
  1505  `)
  1506  	tg.setenv("PKG_CONFIG_PATH", tg.path("."))
  1507  	tg.run("run", tg.path("foo.go"))
  1508  
  1509  	if runtime.GOOS != "darwin" { // darwin doesn't like these ldflags
  1510  		// test for ldflags
  1511  		tg.tempFile("bar.pc", `
  1512  Name: bar
  1513  Description: The bar library
  1514  Version: 1.0.0
  1515  Libs: -Wl,-rpath=/path\ with\ spaces/bin
  1516  `)
  1517  	}
  1518  
  1519  	tg.tempFile("bar.go", `package main
  1520  /*
  1521  #cgo pkg-config: bar
  1522  */
  1523  import "C"
  1524  func main() {}
  1525  `)
  1526  	tg.run("run", tg.path("bar.go"))
  1527  }
  1528  
  1529  func TestListTemplateContextFunction(t *testing.T) {
  1530  	t.Parallel()
  1531  	for _, tt := range []struct {
  1532  		v    string
  1533  		want string
  1534  	}{
  1535  		{"GOARCH", runtime.GOARCH},
  1536  		{"GOOS", runtime.GOOS},
  1537  		{"GOROOT", testGOROOT},
  1538  		{"GOPATH", os.Getenv("GOPATH")},
  1539  		{"CgoEnabled", ""},
  1540  		{"UseAllFiles", ""},
  1541  		{"Compiler", ""},
  1542  		{"BuildTags", ""},
  1543  		{"ReleaseTags", ""},
  1544  		{"InstallSuffix", ""},
  1545  	} {
  1546  		tt := tt
  1547  		t.Run(tt.v, func(t *testing.T) {
  1548  			tg := testgo(t)
  1549  			tg.parallel()
  1550  			defer tg.cleanup()
  1551  			tmpl := "{{context." + tt.v + "}}"
  1552  			tg.run("list", "-f", tmpl)
  1553  			if tt.want == "" {
  1554  				return
  1555  			}
  1556  			if got := strings.TrimSpace(tg.getStdout()); got != tt.want {
  1557  				t.Errorf("go list -f %q: got %q; want %q", tmpl, got, tt.want)
  1558  			}
  1559  		})
  1560  	}
  1561  }
  1562  
  1563  // Test that you cannot use a local import in a package
  1564  // accessed by a non-local import (found in a GOPATH/GOROOT).
  1565  // See golang.org/issue/17475.
  1566  func TestImportLocal(t *testing.T) {
  1567  	tooSlow(t, "builds a lot of sequential packages")
  1568  
  1569  	tg := testgo(t)
  1570  	tg.parallel()
  1571  	defer tg.cleanup()
  1572  
  1573  	tg.tempFile("src/dir/x/x.go", `package x
  1574  		var X int
  1575  	`)
  1576  	tg.setenv("GOPATH", tg.path("."))
  1577  	tg.run("build", "dir/x")
  1578  
  1579  	// Ordinary import should work.
  1580  	tg.tempFile("src/dir/p0/p.go", `package p0
  1581  		import "dir/x"
  1582  		var _ = x.X
  1583  	`)
  1584  	tg.run("build", "dir/p0")
  1585  
  1586  	// Relative import should not.
  1587  	tg.tempFile("src/dir/p1/p.go", `package p1
  1588  		import "../x"
  1589  		var _ = x.X
  1590  	`)
  1591  	tg.runFail("build", "dir/p1")
  1592  	tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
  1593  
  1594  	// ... even in a test.
  1595  	tg.tempFile("src/dir/p2/p.go", `package p2
  1596  	`)
  1597  	tg.tempFile("src/dir/p2/p_test.go", `package p2
  1598  		import "../x"
  1599  		import "testing"
  1600  		var _ = x.X
  1601  		func TestFoo(t *testing.T) {}
  1602  	`)
  1603  	tg.run("build", "dir/p2")
  1604  	tg.runFail("test", "dir/p2")
  1605  	tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
  1606  
  1607  	// ... even in an xtest.
  1608  	tg.tempFile("src/dir/p2/p_test.go", `package p2_test
  1609  		import "../x"
  1610  		import "testing"
  1611  		var _ = x.X
  1612  		func TestFoo(t *testing.T) {}
  1613  	`)
  1614  	tg.run("build", "dir/p2")
  1615  	tg.runFail("test", "dir/p2")
  1616  	tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
  1617  
  1618  	// Relative import starting with ./ should not work either.
  1619  	tg.tempFile("src/dir/d.go", `package dir
  1620  		import "./x"
  1621  		var _ = x.X
  1622  	`)
  1623  	tg.runFail("build", "dir")
  1624  	tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
  1625  
  1626  	// ... even in a test.
  1627  	tg.tempFile("src/dir/d.go", `package dir
  1628  	`)
  1629  	tg.tempFile("src/dir/d_test.go", `package dir
  1630  		import "./x"
  1631  		import "testing"
  1632  		var _ = x.X
  1633  		func TestFoo(t *testing.T) {}
  1634  	`)
  1635  	tg.run("build", "dir")
  1636  	tg.runFail("test", "dir")
  1637  	tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
  1638  
  1639  	// ... even in an xtest.
  1640  	tg.tempFile("src/dir/d_test.go", `package dir_test
  1641  		import "./x"
  1642  		import "testing"
  1643  		var _ = x.X
  1644  		func TestFoo(t *testing.T) {}
  1645  	`)
  1646  	tg.run("build", "dir")
  1647  	tg.runFail("test", "dir")
  1648  	tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
  1649  
  1650  	// Relative import plain ".." should not work.
  1651  	tg.tempFile("src/dir/x/y/y.go", `package dir
  1652  		import ".."
  1653  		var _ = x.X
  1654  	`)
  1655  	tg.runFail("build", "dir/x/y")
  1656  	tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
  1657  
  1658  	// ... even in a test.
  1659  	tg.tempFile("src/dir/x/y/y.go", `package y
  1660  	`)
  1661  	tg.tempFile("src/dir/x/y/y_test.go", `package y
  1662  		import ".."
  1663  		import "testing"
  1664  		var _ = x.X
  1665  		func TestFoo(t *testing.T) {}
  1666  	`)
  1667  	tg.run("build", "dir/x/y")
  1668  	tg.runFail("test", "dir/x/y")
  1669  	tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
  1670  
  1671  	// ... even in an x test.
  1672  	tg.tempFile("src/dir/x/y/y_test.go", `package y_test
  1673  		import ".."
  1674  		import "testing"
  1675  		var _ = x.X
  1676  		func TestFoo(t *testing.T) {}
  1677  	`)
  1678  	tg.run("build", "dir/x/y")
  1679  	tg.runFail("test", "dir/x/y")
  1680  	tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
  1681  
  1682  	// Relative import "." should not work.
  1683  	tg.tempFile("src/dir/x/xx.go", `package x
  1684  		import "."
  1685  		var _ = x.X
  1686  	`)
  1687  	tg.runFail("build", "dir/x")
  1688  	tg.grepStderr("cannot import current directory", "did not diagnose import current directory")
  1689  
  1690  	// ... even in a test.
  1691  	tg.tempFile("src/dir/x/xx.go", `package x
  1692  	`)
  1693  	tg.tempFile("src/dir/x/xx_test.go", `package x
  1694  		import "."
  1695  		import "testing"
  1696  		var _ = x.X
  1697  		func TestFoo(t *testing.T) {}
  1698  	`)
  1699  	tg.run("build", "dir/x")
  1700  	tg.runFail("test", "dir/x")
  1701  	tg.grepStderr("cannot import current directory", "did not diagnose import current directory")
  1702  
  1703  	// ... even in an xtest.
  1704  	tg.tempFile("src/dir/x/xx.go", `package x
  1705  	`)
  1706  	tg.tempFile("src/dir/x/xx_test.go", `package x_test
  1707  		import "."
  1708  		import "testing"
  1709  		var _ = x.X
  1710  		func TestFoo(t *testing.T) {}
  1711  	`)
  1712  	tg.run("build", "dir/x")
  1713  	tg.runFail("test", "dir/x")
  1714  	tg.grepStderr("cannot import current directory", "did not diagnose import current directory")
  1715  }
  1716  
  1717  func TestGoInstallPkgdir(t *testing.T) {
  1718  	skipIfGccgo(t, "gccgo has no standard packages")
  1719  	tooSlow(t, "builds a package with cgo dependencies")
  1720  	// Only the stdlib packages that use cgo have install
  1721  	// targets, (we're using net below) so cgo is required
  1722  	// for the install.
  1723  	testenv.MustHaveCGO(t)
  1724  
  1725  	tg := testgo(t)
  1726  	tg.parallel()
  1727  	tg.setenv("GODEBUG", "installgoroot=all")
  1728  	defer tg.cleanup()
  1729  	tg.makeTempdir()
  1730  	pkg := tg.path(".")
  1731  	tg.run("install", "-pkgdir", pkg, "net")
  1732  	tg.mustExist(filepath.Join(pkg, "net.a"))
  1733  	tg.mustNotExist(filepath.Join(pkg, "runtime/cgo.a"))
  1734  }
  1735  
  1736  // For issue 14337.
  1737  func TestParallelTest(t *testing.T) {
  1738  	tooSlow(t, "links and runs test binaries")
  1739  
  1740  	tg := testgo(t)
  1741  	tg.parallel()
  1742  	defer tg.cleanup()
  1743  	tg.makeTempdir()
  1744  	const testSrc = `package package_test
  1745  		import (
  1746  			"testing"
  1747  		)
  1748  		func TestTest(t *testing.T) {
  1749  		}`
  1750  	tg.tempFile("src/p1/p1_test.go", strings.Replace(testSrc, "package_test", "p1_test", 1))
  1751  	tg.tempFile("src/p2/p2_test.go", strings.Replace(testSrc, "package_test", "p2_test", 1))
  1752  	tg.tempFile("src/p3/p3_test.go", strings.Replace(testSrc, "package_test", "p3_test", 1))
  1753  	tg.tempFile("src/p4/p4_test.go", strings.Replace(testSrc, "package_test", "p4_test", 1))
  1754  	tg.setenv("GOPATH", tg.path("."))
  1755  	tg.run("test", "-p=4", "p1", "p2", "p3", "p4")
  1756  }
  1757  
  1758  func TestBinaryOnlyPackages(t *testing.T) {
  1759  	tooSlow(t, "compiles several packages sequentially")
  1760  
  1761  	tg := testgo(t)
  1762  	defer tg.cleanup()
  1763  	tg.parallel()
  1764  	tg.makeTempdir()
  1765  	tg.setenv("GOPATH", tg.path("."))
  1766  
  1767  	tg.tempFile("src/p1/p1.go", `//go:binary-only-package
  1768  
  1769  		package p1
  1770  	`)
  1771  	tg.wantStale("p1", "binary-only packages are no longer supported", "p1 is binary-only, and this message should always be printed")
  1772  	tg.runFail("install", "p1")
  1773  	tg.grepStderr("binary-only packages are no longer supported", "did not report attempt to compile binary-only package")
  1774  
  1775  	tg.tempFile("src/p1/p1.go", `
  1776  		package p1
  1777  		import "fmt"
  1778  		func F(b bool) { fmt.Printf("hello from p1\n"); if b { F(false) } }
  1779  	`)
  1780  	tg.run("install", "p1")
  1781  	os.Remove(tg.path("src/p1/p1.go"))
  1782  	tg.mustNotExist(tg.path("src/p1/p1.go"))
  1783  
  1784  	tg.tempFile("src/p2/p2.go", `//go:binary-only-packages-are-not-great
  1785  
  1786  		package p2
  1787  		import "p1"
  1788  		func F() { p1.F(true) }
  1789  	`)
  1790  	tg.runFail("install", "p2")
  1791  	tg.grepStderr("no Go files", "did not complain about missing sources")
  1792  
  1793  	tg.tempFile("src/p1/missing.go", `//go:binary-only-package
  1794  
  1795  		package p1
  1796  		import _ "fmt"
  1797  		func G()
  1798  	`)
  1799  	tg.wantStale("p1", "binary-only package", "should NOT want to rebuild p1 (first)")
  1800  	tg.runFail("install", "p2")
  1801  	tg.grepStderr("p1: binary-only packages are no longer supported", "did not report error for binary-only p1")
  1802  
  1803  	tg.run("list", "-deps", "-f", "{{.ImportPath}}: {{.BinaryOnly}}", "p2")
  1804  	tg.grepStdout("p1: true", "p1 not listed as BinaryOnly")
  1805  	tg.grepStdout("p2: false", "p2 listed as BinaryOnly")
  1806  }
  1807  
  1808  // Issue 16050 and 21884.
  1809  func TestLinkSysoFiles(t *testing.T) {
  1810  	if runtime.GOOS != "linux" || runtime.GOARCH != "amd64" {
  1811  		t.Skip("not linux/amd64")
  1812  	}
  1813  
  1814  	tg := testgo(t)
  1815  	defer tg.cleanup()
  1816  	tg.parallel()
  1817  	tg.tempDir("src/syso")
  1818  	tg.tempFile("src/syso/a.syso", ``)
  1819  	tg.tempFile("src/syso/b.go", `package syso`)
  1820  	tg.setenv("GOPATH", tg.path("."))
  1821  
  1822  	// We should see the .syso file regardless of the setting of
  1823  	// CGO_ENABLED.
  1824  
  1825  	tg.setenv("CGO_ENABLED", "1")
  1826  	tg.run("list", "-f", "{{.SysoFiles}}", "syso")
  1827  	tg.grepStdout("a.syso", "missing syso file with CGO_ENABLED=1")
  1828  
  1829  	tg.setenv("CGO_ENABLED", "0")
  1830  	tg.run("list", "-f", "{{.SysoFiles}}", "syso")
  1831  	tg.grepStdout("a.syso", "missing syso file with CGO_ENABLED=0")
  1832  
  1833  	tg.setenv("CGO_ENABLED", "1")
  1834  	tg.run("list", "-msan", "-f", "{{.SysoFiles}}", "syso")
  1835  	tg.grepStdoutNot("a.syso", "unexpected syso file with -msan")
  1836  }
  1837  
  1838  // Issue 16120.
  1839  func TestGenerateUsesBuildContext(t *testing.T) {
  1840  	if runtime.GOOS == "windows" {
  1841  		t.Skip("this test won't run under Windows")
  1842  	}
  1843  
  1844  	tg := testgo(t)
  1845  	defer tg.cleanup()
  1846  	tg.parallel()
  1847  	tg.tempDir("src/gen")
  1848  	tg.tempFile("src/gen/gen.go", "package gen\n//go:generate echo $GOOS $GOARCH\n")
  1849  	tg.setenv("GOPATH", tg.path("."))
  1850  
  1851  	tg.setenv("GOOS", "linux")
  1852  	tg.setenv("GOARCH", "amd64")
  1853  	tg.run("generate", "gen")
  1854  	tg.grepStdout("linux amd64", "unexpected GOOS/GOARCH combination")
  1855  
  1856  	tg.setenv("GOOS", "darwin")
  1857  	tg.setenv("GOARCH", "arm64")
  1858  	tg.run("generate", "gen")
  1859  	tg.grepStdout("darwin arm64", "unexpected GOOS/GOARCH combination")
  1860  }
  1861  
  1862  func TestGoEnv(t *testing.T) {
  1863  	tg := testgo(t)
  1864  	tg.parallel()
  1865  	defer tg.cleanup()
  1866  	tg.setenv("GOOS", "freebsd") // to avoid invalid pair errors
  1867  	tg.setenv("GOARCH", "arm")
  1868  	tg.run("env", "GOARCH")
  1869  	tg.grepStdout("^arm$", "GOARCH not honored")
  1870  
  1871  	tg.run("env", "GCCGO")
  1872  	tg.grepStdout(".", "GCCGO unexpectedly empty")
  1873  
  1874  	tg.run("env", "CGO_CFLAGS")
  1875  	tg.grepStdout(".", "default CGO_CFLAGS unexpectedly empty")
  1876  
  1877  	tg.setenv("CGO_CFLAGS", "-foobar")
  1878  	tg.run("env", "CGO_CFLAGS")
  1879  	tg.grepStdout("^-foobar$", "CGO_CFLAGS not honored")
  1880  
  1881  	tg.setenv("CC", "gcc -fmust -fgo -ffaster")
  1882  	tg.run("env", "CC")
  1883  	tg.grepStdout("gcc", "CC not found")
  1884  	tg.run("env", "GOGCCFLAGS")
  1885  	tg.grepStdout("-ffaster", "CC arguments not found")
  1886  
  1887  	tg.run("env", "GOVERSION")
  1888  	envVersion := strings.TrimSpace(tg.stdout.String())
  1889  
  1890  	tg.run("version")
  1891  	cmdVersion := strings.TrimSpace(tg.stdout.String())
  1892  
  1893  	// If 'go version' is "go version <version> <goos>/<goarch>", then
  1894  	// 'go env GOVERSION' is just "<version>".
  1895  	if cmdVersion == envVersion || !strings.Contains(cmdVersion, envVersion) {
  1896  		t.Fatalf("'go env GOVERSION' %q should be a shorter substring of 'go version' %q", envVersion, cmdVersion)
  1897  	}
  1898  }
  1899  
  1900  const (
  1901  	noMatchesPattern = `(?m)^ok.*\[no tests to run\]`
  1902  	okPattern        = `(?m)^ok`
  1903  )
  1904  
  1905  // Issue 18044.
  1906  func TestLdBindNow(t *testing.T) {
  1907  	tg := testgo(t)
  1908  	defer tg.cleanup()
  1909  	tg.parallel()
  1910  	tg.setenv("LD_BIND_NOW", "1")
  1911  	tg.run("help")
  1912  }
  1913  
  1914  // Issue 18225.
  1915  // This is really a cmd/asm issue but this is a convenient place to test it.
  1916  func TestConcurrentAsm(t *testing.T) {
  1917  	skipIfGccgo(t, "gccgo does not use cmd/asm")
  1918  	tg := testgo(t)
  1919  	defer tg.cleanup()
  1920  	tg.parallel()
  1921  	asm := `DATA ·constants<>+0x0(SB)/8,$0
  1922  GLOBL ·constants<>(SB),8,$8
  1923  `
  1924  	tg.tempFile("go/src/p/a.s", asm)
  1925  	tg.tempFile("go/src/p/b.s", asm)
  1926  	tg.tempFile("go/src/p/p.go", `package p`)
  1927  	tg.setenv("GOPATH", tg.path("go"))
  1928  	tg.run("build", "p")
  1929  }
  1930  
  1931  // Issue 18975.
  1932  func TestFFLAGS(t *testing.T) {
  1933  	testenv.MustHaveCGO(t)
  1934  
  1935  	tg := testgo(t)
  1936  	defer tg.cleanup()
  1937  	tg.parallel()
  1938  
  1939  	tg.tempFile("p/src/p/main.go", `package main
  1940  		// #cgo FFLAGS: -no-such-fortran-flag
  1941  		import "C"
  1942  		func main() {}
  1943  	`)
  1944  	tg.tempFile("p/src/p/a.f", `! comment`)
  1945  	tg.setenv("GOPATH", tg.path("p"))
  1946  
  1947  	// This should normally fail because we are passing an unknown flag,
  1948  	// but issue #19080 points to Fortran compilers that succeed anyhow.
  1949  	// To work either way we call doRun directly rather than run or runFail.
  1950  	tg.doRun([]string{"build", "-x", "p"})
  1951  
  1952  	tg.grepStderr("no-such-fortran-flag", `missing expected "-no-such-fortran-flag"`)
  1953  }
  1954  
  1955  // Issue 19198.
  1956  // This is really a cmd/link issue but this is a convenient place to test it.
  1957  func TestDuplicateGlobalAsmSymbols(t *testing.T) {
  1958  	skipIfGccgo(t, "gccgo does not use cmd/asm")
  1959  	tooSlow(t, "links a binary with cgo dependencies")
  1960  	if runtime.GOARCH != "386" && runtime.GOARCH != "amd64" {
  1961  		t.Skipf("skipping test on %s", runtime.GOARCH)
  1962  	}
  1963  	testenv.MustHaveCGO(t)
  1964  
  1965  	tg := testgo(t)
  1966  	defer tg.cleanup()
  1967  	tg.parallel()
  1968  
  1969  	asm := `
  1970  #include "textflag.h"
  1971  
  1972  DATA sym<>+0x0(SB)/8,$0
  1973  GLOBL sym<>(SB),(NOPTR+RODATA),$8
  1974  
  1975  TEXT ·Data(SB),NOSPLIT,$0
  1976  	MOVB sym<>(SB), AX
  1977  	MOVB AX, ret+0(FP)
  1978  	RET
  1979  `
  1980  	tg.tempFile("go/src/a/a.s", asm)
  1981  	tg.tempFile("go/src/a/a.go", `package a; func Data() uint8`)
  1982  	tg.tempFile("go/src/b/b.s", asm)
  1983  	tg.tempFile("go/src/b/b.go", `package b; func Data() uint8`)
  1984  	tg.tempFile("go/src/p/p.go", `
  1985  package main
  1986  import "a"
  1987  import "b"
  1988  import "C"
  1989  func main() {
  1990  	_ = a.Data() + b.Data()
  1991  }
  1992  `)
  1993  	tg.setenv("GOPATH", tg.path("go"))
  1994  	exe := tg.path("p.exe")
  1995  	tg.creatingTemp(exe)
  1996  	tg.run("build", "-o", exe, "p")
  1997  }
  1998  
  1999  func copyFile(src, dst string, perm fs.FileMode) error {
  2000  	sf, err := os.Open(src)
  2001  	if err != nil {
  2002  		return err
  2003  	}
  2004  	defer sf.Close()
  2005  
  2006  	df, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
  2007  	if err != nil {
  2008  		return err
  2009  	}
  2010  
  2011  	_, err = io.Copy(df, sf)
  2012  	err2 := df.Close()
  2013  	if err != nil {
  2014  		return err
  2015  	}
  2016  	return err2
  2017  }
  2018  
  2019  func TestNeedVersion(t *testing.T) {
  2020  	skipIfGccgo(t, "gccgo does not use cmd/compile")
  2021  	tg := testgo(t)
  2022  	defer tg.cleanup()
  2023  	tg.parallel()
  2024  	tg.tempFile("goversion.go", `package main; func main() {}`)
  2025  	path := tg.path("goversion.go")
  2026  	tg.setenv("TESTGO_TOOLCHAIN_VERSION", "go1.testgo")
  2027  	tg.runFail("run", path)
  2028  	tg.grepStderr("compile", "does not match go tool version")
  2029  }
  2030  
  2031  func TestBuildmodePIE(t *testing.T) {
  2032  	tooSlow(t, "links binaries")
  2033  
  2034  	if !platform.BuildModeSupported(runtime.Compiler, "pie", runtime.GOOS, runtime.GOARCH) {
  2035  		t.Skipf("skipping test because buildmode=pie is not supported on %s/%s", runtime.GOOS, runtime.GOARCH)
  2036  	}
  2037  	// Skip on alpine until https://go.dev/issues/54354 resolved.
  2038  	if strings.HasSuffix(testenv.Builder(), "-alpine") {
  2039  		t.Skip("skipping PIE tests on alpine; see https://go.dev/issues/54354")
  2040  	}
  2041  	t.Run("non-cgo", func(t *testing.T) {
  2042  		testBuildmodePIE(t, false, true)
  2043  	})
  2044  	t.Run("cgo", func(t *testing.T) {
  2045  		testenv.MustHaveCGO(t)
  2046  		testBuildmodePIE(t, true, true)
  2047  	})
  2048  }
  2049  
  2050  func TestWindowsDefaultBuildmodIsPIE(t *testing.T) {
  2051  	if runtime.GOOS != "windows" {
  2052  		t.Skip("skipping windows only test")
  2053  	}
  2054  	tooSlow(t, "links binaries")
  2055  
  2056  	t.Run("non-cgo", func(t *testing.T) {
  2057  		testBuildmodePIE(t, false, false)
  2058  	})
  2059  	t.Run("cgo", func(t *testing.T) {
  2060  		testenv.MustHaveCGO(t)
  2061  		testBuildmodePIE(t, true, false)
  2062  	})
  2063  }
  2064  
  2065  func testBuildmodePIE(t *testing.T, useCgo, setBuildmodeToPIE bool) {
  2066  	tg := testgo(t)
  2067  	defer tg.cleanup()
  2068  	tg.parallel()
  2069  
  2070  	var s string
  2071  	if useCgo {
  2072  		s = `import "C";`
  2073  	}
  2074  	tg.tempFile("main.go", fmt.Sprintf(`package main;%s func main() { print("hello") }`, s))
  2075  	src := tg.path("main.go")
  2076  	obj := tg.path("main.exe")
  2077  	args := []string{"build"}
  2078  	if setBuildmodeToPIE {
  2079  		args = append(args, "-buildmode=pie")
  2080  	}
  2081  	args = append(args, "-o", obj, src)
  2082  	tg.run(args...)
  2083  
  2084  	switch runtime.GOOS {
  2085  	case "linux", "android", "freebsd":
  2086  		f, err := elf.Open(obj)
  2087  		if err != nil {
  2088  			t.Fatal(err)
  2089  		}
  2090  		defer f.Close()
  2091  		if f.Type != elf.ET_DYN {
  2092  			t.Errorf("PIE type must be ET_DYN, but %s", f.Type)
  2093  		}
  2094  	case "darwin", "ios":
  2095  		f, err := macho.Open(obj)
  2096  		if err != nil {
  2097  			t.Fatal(err)
  2098  		}
  2099  		defer f.Close()
  2100  		if f.Flags&macho.FlagDyldLink == 0 {
  2101  			t.Error("PIE must have DyldLink flag, but not")
  2102  		}
  2103  		if f.Flags&macho.FlagPIE == 0 {
  2104  			t.Error("PIE must have PIE flag, but not")
  2105  		}
  2106  	case "windows":
  2107  		f, err := pe.Open(obj)
  2108  		if err != nil {
  2109  			t.Fatal(err)
  2110  		}
  2111  		defer f.Close()
  2112  		if f.Section(".reloc") == nil {
  2113  			t.Error(".reloc section is not present")
  2114  		}
  2115  		if (f.FileHeader.Characteristics & pe.IMAGE_FILE_RELOCS_STRIPPED) != 0 {
  2116  			t.Error("IMAGE_FILE_RELOCS_STRIPPED flag is set")
  2117  		}
  2118  		var dc uint16
  2119  		switch oh := f.OptionalHeader.(type) {
  2120  		case *pe.OptionalHeader32:
  2121  			dc = oh.DllCharacteristics
  2122  		case *pe.OptionalHeader64:
  2123  			dc = oh.DllCharacteristics
  2124  			if (dc & pe.IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA) == 0 {
  2125  				t.Error("IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA flag is not set")
  2126  			}
  2127  		default:
  2128  			t.Fatalf("unexpected optional header type of %T", f.OptionalHeader)
  2129  		}
  2130  		if (dc & pe.IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE) == 0 {
  2131  			t.Error("IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE flag is not set")
  2132  		}
  2133  	default:
  2134  		// testBuildmodePIE opens object files, so it needs to understand the object
  2135  		// file format.
  2136  		t.Skipf("skipping test: test helper does not support %s", runtime.GOOS)
  2137  	}
  2138  
  2139  	out, err := testenv.Command(t, obj).CombinedOutput()
  2140  	if err != nil {
  2141  		t.Fatal(err)
  2142  	}
  2143  
  2144  	if string(out) != "hello" {
  2145  		t.Errorf("got %q; want %q", out, "hello")
  2146  	}
  2147  }
  2148  
  2149  func TestUpxCompression(t *testing.T) {
  2150  	if runtime.GOOS != "linux" ||
  2151  		(runtime.GOARCH != "amd64" && runtime.GOARCH != "386") {
  2152  		t.Skipf("skipping upx test on %s/%s", runtime.GOOS, runtime.GOARCH)
  2153  	}
  2154  
  2155  	testenv.MustHaveExecPath(t, "upx")
  2156  	out, err := testenv.Command(t, "upx", "--version").CombinedOutput()
  2157  	if err != nil {
  2158  		t.Fatalf("upx --version failed: %v", err)
  2159  	}
  2160  
  2161  	// upx --version prints `upx <version>` in the first line of output:
  2162  	//   upx 3.94
  2163  	//   [...]
  2164  	re := regexp.MustCompile(`([[:digit:]]+)\.([[:digit:]]+)`)
  2165  	upxVersion := re.FindStringSubmatch(string(out))
  2166  	if len(upxVersion) != 3 {
  2167  		t.Fatalf("bad upx version string: %s", upxVersion)
  2168  	}
  2169  
  2170  	major, err1 := strconv.Atoi(upxVersion[1])
  2171  	minor, err2 := strconv.Atoi(upxVersion[2])
  2172  	if err1 != nil || err2 != nil {
  2173  		t.Fatalf("bad upx version string: %s", upxVersion[0])
  2174  	}
  2175  
  2176  	// Anything below 3.94 is known not to work with go binaries
  2177  	if (major < 3) || (major == 3 && minor < 94) {
  2178  		t.Skipf("skipping because upx version %v.%v is too old", major, minor)
  2179  	}
  2180  
  2181  	tg := testgo(t)
  2182  	defer tg.cleanup()
  2183  	tg.parallel()
  2184  
  2185  	tg.tempFile("main.go", `package main; import "fmt"; func main() { fmt.Print("hello upx") }`)
  2186  	src := tg.path("main.go")
  2187  	obj := tg.path("main")
  2188  	tg.run("build", "-o", obj, src)
  2189  
  2190  	out, err = testenv.Command(t, "upx", obj).CombinedOutput()
  2191  	if err != nil {
  2192  		t.Logf("executing upx\n%s\n", out)
  2193  		t.Fatalf("upx failed with %v", err)
  2194  	}
  2195  
  2196  	out, err = testenv.Command(t, obj).CombinedOutput()
  2197  	if err != nil {
  2198  		t.Logf("%s", out)
  2199  		t.Fatalf("running compressed go binary failed with error %s", err)
  2200  	}
  2201  	if string(out) != "hello upx" {
  2202  		t.Fatalf("bad output from compressed go binary:\ngot %q; want %q", out, "hello upx")
  2203  	}
  2204  }
  2205  
  2206  var gocacheverify = godebug.New("#gocacheverify")
  2207  
  2208  func TestCacheListStale(t *testing.T) {
  2209  	tooSlow(t, "links a binary")
  2210  	if gocacheverify.Value() == "1" {
  2211  		t.Skip("GODEBUG gocacheverify")
  2212  	}
  2213  
  2214  	tg := testgo(t)
  2215  	defer tg.cleanup()
  2216  	tg.parallel()
  2217  	tg.makeTempdir()
  2218  	tg.setenv("GOCACHE", tg.path("cache"))
  2219  	tg.tempFile("gopath/src/p/p.go", "package p; import _ \"q\"; func F(){}\n")
  2220  	tg.tempFile("gopath/src/q/q.go", "package q; func F(){}\n")
  2221  	tg.tempFile("gopath/src/m/m.go", "package main; import _ \"q\"; func main(){}\n")
  2222  
  2223  	tg.setenv("GOPATH", tg.path("gopath"))
  2224  	tg.run("install", "p", "m")
  2225  	tg.run("list", "-f={{.ImportPath}} {{.Stale}}", "m", "q", "p")
  2226  	tg.grepStdout("^m false", "m should not be stale")
  2227  	tg.grepStdout("^q true", "q should be stale")
  2228  	tg.grepStdout("^p false", "p should not be stale")
  2229  }
  2230  
  2231  func TestCacheCoverage(t *testing.T) {
  2232  	tooSlow(t, "links and runs a test binary with coverage enabled")
  2233  	if gocacheverify.Value() == "1" {
  2234  		t.Skip("GODEBUG gocacheverify")
  2235  	}
  2236  
  2237  	tg := testgo(t)
  2238  	defer tg.cleanup()
  2239  	tg.parallel()
  2240  	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
  2241  	tg.makeTempdir()
  2242  
  2243  	tg.setenv("GOCACHE", tg.path("c1"))
  2244  	tg.run("test", "-cover", "-short", "strings")
  2245  	tg.run("test", "-cover", "-short", "math", "strings")
  2246  }
  2247  
  2248  func TestIssue22588(t *testing.T) {
  2249  	// Don't get confused by stderr coming from tools.
  2250  	tg := testgo(t)
  2251  	defer tg.cleanup()
  2252  	tg.parallel()
  2253  
  2254  	tg.wantNotStale("runtime", "", "must be non-stale to compare staleness under -toolexec")
  2255  
  2256  	if _, err := os.Stat("/usr/bin/time"); err != nil {
  2257  		t.Skip(err)
  2258  	}
  2259  
  2260  	tg.run("list", "-f={{.Stale}}", "runtime")
  2261  	tg.run("list", "-toolexec=/usr/bin/time", "-f={{.Stale}}", "runtime")
  2262  	tg.grepStdout("false", "incorrectly reported runtime as stale")
  2263  }
  2264  
  2265  func TestIssue22531(t *testing.T) {
  2266  	tooSlow(t, "links binaries")
  2267  	if gocacheverify.Value() == "1" {
  2268  		t.Skip("GODEBUG gocacheverify")
  2269  	}
  2270  
  2271  	tg := testgo(t)
  2272  	defer tg.cleanup()
  2273  	tg.parallel()
  2274  	tg.makeTempdir()
  2275  	tg.setenv("GOPATH", tg.tempdir)
  2276  	tg.setenv("GOCACHE", tg.path("cache"))
  2277  	tg.tempFile("src/m/main.go", "package main /* c1 */; func main() {}\n")
  2278  	tg.run("install", "-x", "m")
  2279  	tg.run("list", "-f", "{{.Stale}}", "m")
  2280  	tg.grepStdout("false", "reported m as stale after install")
  2281  	tg.run("tool", "buildid", tg.path("bin/m"+exeSuffix))
  2282  
  2283  	// The link action ID did not include the full main build ID,
  2284  	// even though the full main build ID is written into the
  2285  	// eventual binary. That caused the following install to
  2286  	// be a no-op, thinking the gofmt binary was up-to-date,
  2287  	// even though .Stale could see it was not.
  2288  	tg.tempFile("src/m/main.go", "package main /* c2 */; func main() {}\n")
  2289  	tg.run("install", "-x", "m")
  2290  	tg.run("list", "-f", "{{.Stale}}", "m")
  2291  	tg.grepStdout("false", "reported m as stale after reinstall")
  2292  	tg.run("tool", "buildid", tg.path("bin/m"+exeSuffix))
  2293  }
  2294  
  2295  func TestIssue22596(t *testing.T) {
  2296  	tooSlow(t, "links binaries")
  2297  	if gocacheverify.Value() == "1" {
  2298  		t.Skip("GODEBUG gocacheverify")
  2299  	}
  2300  
  2301  	tg := testgo(t)
  2302  	defer tg.cleanup()
  2303  	tg.parallel()
  2304  	tg.makeTempdir()
  2305  	tg.setenv("GOCACHE", tg.path("cache"))
  2306  	tg.tempFile("gopath1/src/p/p.go", "package p; func F(){}\n")
  2307  	tg.tempFile("gopath2/src/p/p.go", "package p; func F(){}\n")
  2308  
  2309  	tg.setenv("GOPATH", tg.path("gopath1"))
  2310  	tg.run("list", "-f={{.Target}}", "p")
  2311  	target1 := strings.TrimSpace(tg.getStdout())
  2312  	tg.run("install", "p")
  2313  	tg.wantNotStale("p", "", "p stale after install")
  2314  
  2315  	tg.setenv("GOPATH", tg.path("gopath2"))
  2316  	tg.run("list", "-f={{.Target}}", "p")
  2317  	target2 := strings.TrimSpace(tg.getStdout())
  2318  	tg.must(os.MkdirAll(filepath.Dir(target2), 0777))
  2319  	tg.must(copyFile(target1, target2, 0666))
  2320  	tg.wantStale("p", "build ID mismatch", "p not stale after copy from gopath1")
  2321  	tg.run("install", "p")
  2322  	tg.wantNotStale("p", "", "p stale after install2")
  2323  }
  2324  
  2325  func TestTestCache(t *testing.T) {
  2326  	tooSlow(t, "links and runs test binaries")
  2327  	if gocacheverify.Value() == "1" {
  2328  		t.Skip("GODEBUG gocacheverify")
  2329  	}
  2330  
  2331  	tg := testgo(t)
  2332  	defer tg.cleanup()
  2333  	tg.parallel()
  2334  	tg.makeTempdir()
  2335  	tg.setenv("GOPATH", tg.tempdir)
  2336  	tg.setenv("GOCACHE", tg.path("cache"))
  2337  
  2338  	// The -p=1 in the commands below just makes the -x output easier to read.
  2339  
  2340  	t.Log("\n\nINITIAL\n\n")
  2341  
  2342  	tg.tempFile("src/p1/p1.go", "package p1\nvar X =  1\n")
  2343  	tg.tempFile("src/p2/p2.go", "package p2\nimport _ \"p1\"\nvar X = 1\n")
  2344  	tg.tempFile("src/t/t1/t1_test.go", "package t\nimport \"testing\"\nfunc Test1(*testing.T) {}\n")
  2345  	tg.tempFile("src/t/t2/t2_test.go", "package t\nimport _ \"p1\"\nimport \"testing\"\nfunc Test2(*testing.T) {}\n")
  2346  	tg.tempFile("src/t/t3/t3_test.go", "package t\nimport \"p1\"\nimport \"testing\"\nfunc Test3(t *testing.T) {t.Log(p1.X)}\n")
  2347  	tg.tempFile("src/t/t4/t4_test.go", "package t\nimport \"p2\"\nimport \"testing\"\nfunc Test4(t *testing.T) {t.Log(p2.X)}")
  2348  	tg.run("test", "-x", "-v", "-short", "t/...")
  2349  
  2350  	t.Log("\n\nREPEAT\n\n")
  2351  
  2352  	tg.run("test", "-x", "-v", "-short", "t/...")
  2353  	tg.grepStdout(`ok  \tt/t1\t\(cached\)`, "did not cache t1")
  2354  	tg.grepStdout(`ok  \tt/t2\t\(cached\)`, "did not cache t2")
  2355  	tg.grepStdout(`ok  \tt/t3\t\(cached\)`, "did not cache t3")
  2356  	tg.grepStdout(`ok  \tt/t4\t\(cached\)`, "did not cache t4")
  2357  	tg.grepStderrNot(`[\\/](compile|gccgo) `, "incorrectly ran compiler")
  2358  	tg.grepStderrNot(`[\\/](link|gccgo) `, "incorrectly ran linker")
  2359  	tg.grepStderrNot(`p[0-9]\.test`, "incorrectly ran test")
  2360  
  2361  	t.Log("\n\nCOMMENT\n\n")
  2362  
  2363  	// Changing the program text without affecting the compiled package
  2364  	// should result in the package being rebuilt but nothing more.
  2365  	tg.tempFile("src/p1/p1.go", "package p1\nvar X = 01\n")
  2366  	tg.run("test", "-p=1", "-x", "-v", "-short", "t/...")
  2367  	tg.grepStdout(`ok  \tt/t1\t\(cached\)`, "did not cache t1")
  2368  	tg.grepStdout(`ok  \tt/t2\t\(cached\)`, "did not cache t2")
  2369  	tg.grepStdout(`ok  \tt/t3\t\(cached\)`, "did not cache t3")
  2370  	tg.grepStdout(`ok  \tt/t4\t\(cached\)`, "did not cache t4")
  2371  	tg.grepStderrNot(`([\\/](compile|gccgo) ).*t[0-9]_test\.go`, "incorrectly ran compiler")
  2372  	tg.grepStderrNot(`[\\/](link|gccgo) `, "incorrectly ran linker")
  2373  	tg.grepStderrNot(`t[0-9]\.test.*test\.short`, "incorrectly ran test")
  2374  
  2375  	t.Log("\n\nCHANGE\n\n")
  2376  
  2377  	// Changing the actual package should have limited effects.
  2378  	tg.tempFile("src/p1/p1.go", "package p1\nvar X = 02\n")
  2379  	tg.run("test", "-p=1", "-x", "-v", "-short", "t/...")
  2380  
  2381  	// p2 should have been rebuilt.
  2382  	tg.grepStderr(`([\\/]compile|gccgo).*p2.go`, "did not recompile p2")
  2383  
  2384  	// t1 does not import anything, should not have been rebuilt.
  2385  	tg.grepStderrNot(`([\\/]compile|gccgo).*t1_test.go`, "incorrectly recompiled t1")
  2386  	tg.grepStderrNot(`([\\/]link|gccgo).*t1_test`, "incorrectly relinked t1_test")
  2387  	tg.grepStdout(`ok  \tt/t1\t\(cached\)`, "did not cache t/t1")
  2388  
  2389  	// t2 imports p1 and must be rebuilt and relinked,
  2390  	// but the change should not have any effect on the test binary,
  2391  	// so the test should not have been rerun.
  2392  	tg.grepStderr(`([\\/]compile|gccgo).*t2_test.go`, "did not recompile t2")
  2393  	tg.grepStderr(`([\\/]link|gccgo).*t2\.test`, "did not relink t2_test")
  2394  	// This check does not currently work with gccgo, as garbage
  2395  	// collection of unused variables is not turned on by default.
  2396  	if runtime.Compiler != "gccgo" {
  2397  		tg.grepStdout(`ok  \tt/t2\t\(cached\)`, "did not cache t/t2")
  2398  	}
  2399  
  2400  	// t3 imports p1, and changing X changes t3's test binary.
  2401  	tg.grepStderr(`([\\/]compile|gccgo).*t3_test.go`, "did not recompile t3")
  2402  	tg.grepStderr(`([\\/]link|gccgo).*t3\.test`, "did not relink t3_test")
  2403  	tg.grepStderr(`t3\.test.*-test.short`, "did not rerun t3_test")
  2404  	tg.grepStdoutNot(`ok  \tt/t3\t\(cached\)`, "reported cached t3_test result")
  2405  
  2406  	// t4 imports p2, but p2 did not change, so t4 should be relinked, not recompiled,
  2407  	// and not rerun.
  2408  	tg.grepStderrNot(`([\\/]compile|gccgo).*t4_test.go`, "incorrectly recompiled t4")
  2409  	tg.grepStderr(`([\\/]link|gccgo).*t4\.test`, "did not relink t4_test")
  2410  	// This check does not currently work with gccgo, as garbage
  2411  	// collection of unused variables is not turned on by default.
  2412  	if runtime.Compiler != "gccgo" {
  2413  		tg.grepStdout(`ok  \tt/t4\t\(cached\)`, "did not cache t/t4")
  2414  	}
  2415  }
  2416  
  2417  func TestTestSkipVetAfterFailedBuild(t *testing.T) {
  2418  	tg := testgo(t)
  2419  	defer tg.cleanup()
  2420  	tg.parallel()
  2421  
  2422  	tg.tempFile("x_test.go", `package x
  2423  		func f() {
  2424  			return 1
  2425  		}
  2426  	`)
  2427  
  2428  	tg.runFail("test", tg.path("x_test.go"))
  2429  	tg.grepStderrNot(`vet`, "vet should be skipped after the failed build")
  2430  }
  2431  
  2432  func TestTestVetRebuild(t *testing.T) {
  2433  	tooSlow(t, "links and runs test binaries")
  2434  
  2435  	tg := testgo(t)
  2436  	defer tg.cleanup()
  2437  	tg.parallel()
  2438  
  2439  	// golang.org/issue/23701.
  2440  	// b_test imports b with augmented method from export_test.go.
  2441  	// b_test also imports a, which imports b.
  2442  	// Must not accidentally see un-augmented b propagate through a to b_test.
  2443  	tg.tempFile("src/a/a.go", `package a
  2444  		import "b"
  2445  		type Type struct{}
  2446  		func (*Type) M() b.T {return 0}
  2447  	`)
  2448  	tg.tempFile("src/b/b.go", `package b
  2449  		type T int
  2450  		type I interface {M() T}
  2451  	`)
  2452  	tg.tempFile("src/b/export_test.go", `package b
  2453  		func (*T) Method() *T { return nil }
  2454  	`)
  2455  	tg.tempFile("src/b/b_test.go", `package b_test
  2456  		import (
  2457  			"testing"
  2458  			"a"
  2459  			. "b"
  2460  		)
  2461  		func TestBroken(t *testing.T) {
  2462  			x := new(T)
  2463  			x.Method()
  2464  			_ = new(a.Type)
  2465  		}
  2466  	`)
  2467  
  2468  	tg.setenv("GOPATH", tg.path("."))
  2469  	tg.run("test", "b")
  2470  	tg.run("vet", "b")
  2471  }
  2472  
  2473  func TestInstallDeps(t *testing.T) {
  2474  	tooSlow(t, "links a binary")
  2475  
  2476  	tg := testgo(t)
  2477  	defer tg.cleanup()
  2478  	tg.parallel()
  2479  	tg.makeTempdir()
  2480  	tg.setenv("GOPATH", tg.tempdir)
  2481  
  2482  	tg.tempFile("src/p1/p1.go", "package p1\nvar X =  1\n")
  2483  	tg.tempFile("src/p2/p2.go", "package p2\nimport _ \"p1\"\n")
  2484  	tg.tempFile("src/main1/main.go", "package main\nimport _ \"p2\"\nfunc main() {}\n")
  2485  
  2486  	tg.run("list", "-f={{.Target}}", "p1")
  2487  	p1 := strings.TrimSpace(tg.getStdout())
  2488  	tg.run("list", "-f={{.Target}}", "p2")
  2489  	p2 := strings.TrimSpace(tg.getStdout())
  2490  	tg.run("list", "-f={{.Target}}", "main1")
  2491  	main1 := strings.TrimSpace(tg.getStdout())
  2492  
  2493  	tg.run("install", "main1")
  2494  
  2495  	tg.mustExist(main1)
  2496  	tg.mustNotExist(p2)
  2497  	tg.mustNotExist(p1)
  2498  
  2499  	tg.run("install", "p2")
  2500  	tg.mustExist(p2)
  2501  	tg.mustNotExist(p1)
  2502  }
  2503  
  2504  // Issue 22986.
  2505  func TestImportPath(t *testing.T) {
  2506  	tooSlow(t, "links and runs a test binary")
  2507  
  2508  	tg := testgo(t)
  2509  	defer tg.cleanup()
  2510  	tg.parallel()
  2511  
  2512  	tg.tempFile("src/a/a.go", `
  2513  package main
  2514  
  2515  import (
  2516  	"log"
  2517  	p "a/p-1.0"
  2518  )
  2519  
  2520  func main() {
  2521  	if !p.V {
  2522  		log.Fatal("false")
  2523  	}
  2524  }`)
  2525  
  2526  	tg.tempFile("src/a/a_test.go", `
  2527  package main_test
  2528  
  2529  import (
  2530  	p "a/p-1.0"
  2531  	"testing"
  2532  )
  2533  
  2534  func TestV(t *testing.T) {
  2535  	if !p.V {
  2536  		t.Fatal("false")
  2537  	}
  2538  }`)
  2539  
  2540  	tg.tempFile("src/a/p-1.0/p.go", `
  2541  package p
  2542  
  2543  var V = true
  2544  
  2545  func init() {}
  2546  `)
  2547  
  2548  	tg.setenv("GOPATH", tg.path("."))
  2549  	tg.run("build", "-o", tg.path("a.exe"), "a")
  2550  	tg.run("test", "a")
  2551  }
  2552  
  2553  func TestBadCommandLines(t *testing.T) {
  2554  	tg := testgo(t)
  2555  	defer tg.cleanup()
  2556  	tg.parallel()
  2557  
  2558  	tg.tempFile("src/x/x.go", "package x\n")
  2559  	tg.setenv("GOPATH", tg.path("."))
  2560  
  2561  	tg.run("build", "x")
  2562  
  2563  	tg.tempFile("src/x/@y.go", "package x\n")
  2564  	tg.runFail("build", "x")
  2565  	tg.grepStderr("invalid input file name \"@y.go\"", "did not reject @y.go")
  2566  	tg.must(os.Remove(tg.path("src/x/@y.go")))
  2567  
  2568  	tg.tempFile("src/x/-y.go", "package x\n")
  2569  	tg.runFail("build", "x")
  2570  	tg.grepStderr("invalid input file name \"-y.go\"", "did not reject -y.go")
  2571  	tg.must(os.Remove(tg.path("src/x/-y.go")))
  2572  
  2573  	if runtime.Compiler == "gccgo" {
  2574  		tg.runFail("build", "-gccgoflags=all=@x", "x")
  2575  	} else {
  2576  		tg.runFail("build", "-gcflags=all=@x", "x")
  2577  	}
  2578  	tg.grepStderr("invalid command-line argument @x in command", "did not reject @x during exec")
  2579  
  2580  	tg.tempFile("src/@x/x.go", "package x\n")
  2581  	tg.setenv("GOPATH", tg.path("."))
  2582  	tg.runFail("build", "@x")
  2583  	tg.grepStderr("invalid input directory name \"@x\"|can only use path@version syntax with 'go get' and 'go install' in module-aware mode", "did not reject @x directory")
  2584  
  2585  	tg.tempFile("src/@x/y/y.go", "package y\n")
  2586  	tg.setenv("GOPATH", tg.path("."))
  2587  	tg.runFail("build", "@x/y")
  2588  	tg.grepStderr("invalid import path \"@x/y\"|can only use path@version syntax with 'go get' and 'go install' in module-aware mode", "did not reject @x/y import path")
  2589  
  2590  	tg.tempFile("src/-x/x.go", "package x\n")
  2591  	tg.setenv("GOPATH", tg.path("."))
  2592  	tg.runFail("build", "--", "-x")
  2593  	tg.grepStderr("invalid import path \"-x\"", "did not reject -x import path")
  2594  
  2595  	tg.tempFile("src/-x/y/y.go", "package y\n")
  2596  	tg.setenv("GOPATH", tg.path("."))
  2597  	tg.runFail("build", "--", "-x/y")
  2598  	tg.grepStderr("invalid import path \"-x/y\"", "did not reject -x/y import path")
  2599  }
  2600  
  2601  func TestTwoPkgConfigs(t *testing.T) {
  2602  	testenv.MustHaveCGO(t)
  2603  	if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
  2604  		t.Skipf("no shell scripts on %s", runtime.GOOS)
  2605  	}
  2606  	tooSlow(t, "builds a package with cgo dependencies")
  2607  
  2608  	tg := testgo(t)
  2609  	defer tg.cleanup()
  2610  	tg.parallel()
  2611  	tg.tempFile("src/x/a.go", `package x
  2612  		// #cgo pkg-config: --static a
  2613  		import "C"
  2614  	`)
  2615  	tg.tempFile("src/x/b.go", `package x
  2616  		// #cgo pkg-config: --static a
  2617  		import "C"
  2618  	`)
  2619  	tg.tempFile("pkg-config.sh", `#!/bin/sh
  2620  echo $* >>`+tg.path("pkg-config.out"))
  2621  	tg.must(os.Chmod(tg.path("pkg-config.sh"), 0755))
  2622  	tg.setenv("GOPATH", tg.path("."))
  2623  	tg.setenv("PKG_CONFIG", tg.path("pkg-config.sh"))
  2624  	tg.run("build", "x")
  2625  	out, err := os.ReadFile(tg.path("pkg-config.out"))
  2626  	tg.must(err)
  2627  	out = bytes.TrimSpace(out)
  2628  	want := "--cflags --static --static -- a a\n--libs --static --static -- a a"
  2629  	if !bytes.Equal(out, []byte(want)) {
  2630  		t.Errorf("got %q want %q", out, want)
  2631  	}
  2632  }
  2633  
  2634  func TestCgoCache(t *testing.T) {
  2635  	testenv.MustHaveCGO(t)
  2636  	tooSlow(t, "builds a package with cgo dependencies")
  2637  
  2638  	tg := testgo(t)
  2639  	defer tg.cleanup()
  2640  	tg.parallel()
  2641  	tg.tempFile("src/x/a.go", `package main
  2642  		// #ifndef VAL
  2643  		// #define VAL 0
  2644  		// #endif
  2645  		// int val = VAL;
  2646  		import "C"
  2647  		import "fmt"
  2648  		func main() { fmt.Println(C.val) }
  2649  	`)
  2650  	tg.setenv("GOPATH", tg.path("."))
  2651  	exe := tg.path("x.exe")
  2652  	tg.run("build", "-o", exe, "x")
  2653  	tg.setenv("CGO_LDFLAGS", "-lnosuchlibraryexists")
  2654  	tg.runFail("build", "-o", exe, "x")
  2655  	tg.grepStderr(`nosuchlibraryexists`, "did not run linker with changed CGO_LDFLAGS")
  2656  }
  2657  
  2658  // Issue 23982
  2659  func TestFilepathUnderCwdFormat(t *testing.T) {
  2660  	tg := testgo(t)
  2661  	defer tg.cleanup()
  2662  	tg.parallel()
  2663  	tg.run("test", "-x", "-cover", "log")
  2664  	tg.grepStderrNot(`\.log\.cover\.go`, "-x output should contain correctly formatted filepath under cwd")
  2665  }
  2666  
  2667  // Issue 24396.
  2668  func TestDontReportRemoveOfEmptyDir(t *testing.T) {
  2669  	tg := testgo(t)
  2670  	defer tg.cleanup()
  2671  	tg.parallel()
  2672  	tg.tempFile("src/a/a.go", `package a`)
  2673  	tg.setenv("GOPATH", tg.path("."))
  2674  	tg.run("install", "-x", "a")
  2675  	tg.run("install", "-x", "a")
  2676  	// The second install should have printed only a WORK= line,
  2677  	// nothing else.
  2678  	if bytes.Count(tg.stdout.Bytes(), []byte{'\n'})+bytes.Count(tg.stderr.Bytes(), []byte{'\n'}) > 1 {
  2679  		t.Error("unnecessary output when installing installed package")
  2680  	}
  2681  }
  2682  
  2683  // Issue 24704.
  2684  func TestLinkerTmpDirIsDeleted(t *testing.T) {
  2685  	skipIfGccgo(t, "gccgo does not use cmd/link")
  2686  	testenv.MustHaveCGO(t)
  2687  	tooSlow(t, "builds a package with cgo dependencies")
  2688  
  2689  	tg := testgo(t)
  2690  	defer tg.cleanup()
  2691  	tg.parallel()
  2692  	tg.tempFile("a.go", `package main; import "C"; func main() {}`)
  2693  	tg.run("build", "-ldflags", "-v", "-o", os.DevNull, tg.path("a.go"))
  2694  	// Find line that has "host link:" in linker output.
  2695  	stderr := tg.getStderr()
  2696  	var hostLinkLine string
  2697  	for _, line := range strings.Split(stderr, "\n") {
  2698  		if !strings.Contains(line, "host link:") {
  2699  			continue
  2700  		}
  2701  		hostLinkLine = line
  2702  		break
  2703  	}
  2704  	if hostLinkLine == "" {
  2705  		t.Fatal(`fail to find with "host link:" string in linker output`)
  2706  	}
  2707  	// Find parameter, like "/tmp/go-link-408556474/go.o" inside of
  2708  	// "host link:" line, and extract temp directory /tmp/go-link-408556474
  2709  	// out of it.
  2710  	tmpdir := hostLinkLine
  2711  	i := strings.Index(tmpdir, `go.o"`)
  2712  	if i == -1 {
  2713  		t.Fatalf(`fail to find "go.o" in "host link:" line %q`, hostLinkLine)
  2714  	}
  2715  	tmpdir = tmpdir[:i-1]
  2716  	i = strings.LastIndex(tmpdir, `"`)
  2717  	if i == -1 {
  2718  		t.Fatalf(`fail to find " in "host link:" line %q`, hostLinkLine)
  2719  	}
  2720  	tmpdir = tmpdir[i+1:]
  2721  	// Verify that temp directory has been removed.
  2722  	_, err := os.Stat(tmpdir)
  2723  	if err == nil {
  2724  		t.Fatalf("temp directory %q has not been removed", tmpdir)
  2725  	}
  2726  	if !os.IsNotExist(err) {
  2727  		t.Fatalf("Stat(%q) returns unexpected error: %v", tmpdir, err)
  2728  	}
  2729  }
  2730  
  2731  // Issue 25093.
  2732  func TestCoverpkgTestOnly(t *testing.T) {
  2733  	skipIfGccgo(t, "gccgo has no cover tool")
  2734  	tooSlow(t, "links and runs a test binary with coverage enabled")
  2735  
  2736  	tg := testgo(t)
  2737  	defer tg.cleanup()
  2738  	tg.parallel()
  2739  	tg.tempFile("src/a/a.go", `package a
  2740  		func F(i int) int {
  2741  			return i*i
  2742  		}`)
  2743  	tg.tempFile("src/atest/a_test.go", `
  2744  		package a_test
  2745  		import ( "a"; "testing" )
  2746  		func TestF(t *testing.T) { a.F(2) }
  2747  	`)
  2748  	tg.setenv("GOPATH", tg.path("."))
  2749  	tg.run("test", "-coverpkg=a", "atest")
  2750  	tg.grepStderrNot("no packages being tested depend on matches", "bad match message")
  2751  	tg.grepStdout("coverage: 100", "no coverage")
  2752  }
  2753  
  2754  // Regression test for golang.org/issue/34499: version command should not crash
  2755  // when executed in a deleted directory on Linux.
  2756  func TestExecInDeletedDir(t *testing.T) {
  2757  	switch runtime.GOOS {
  2758  	case "windows", "plan9",
  2759  		"aix",                // Fails with "device busy".
  2760  		"solaris", "illumos": // Fails with "invalid argument".
  2761  		t.Skipf("%v does not support removing the current working directory", runtime.GOOS)
  2762  	}
  2763  	tg := testgo(t)
  2764  	defer tg.cleanup()
  2765  
  2766  	tg.makeTempdir()
  2767  	t.Chdir(tg.tempdir)
  2768  
  2769  	tg.check(os.Remove(tg.tempdir))
  2770  
  2771  	// `go version` should not fail
  2772  	tg.run("version")
  2773  }
  2774  

View as plain text