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