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

View as plain text