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

View as plain text