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

View as plain text