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
5package main_test
6
7import (
8	"bytes"
9	"debug/elf"
10	"debug/macho"
11	"fmt"
12	"go/format"
13	"internal/race"
14	"internal/testenv"
15	"io"
16	"io/ioutil"
17	"os"
18	"os/exec"
19	"path/filepath"
20	"regexp"
21	"runtime"
22	"strconv"
23	"strings"
24	"testing"
25	"time"
26)
27
28var (
29	canRun  = true  // whether we can run go or ./testgo
30	canRace = false // whether we can run the race detector
31	canCgo  = false // whether we can use cgo
32	canMSan = false // whether we can run the memory sanitizer
33
34	exeSuffix string // ".exe" on Windows
35
36	skipExternal = false // skip external tests
37)
38
39func tooSlow(t *testing.T) {
40	if testing.Short() {
41		// In -short mode; skip test, except run it on the {darwin,linux,windows}/amd64 builders.
42		if testenv.Builder() != "" && runtime.GOARCH == "amd64" && (runtime.GOOS == "linux" || runtime.GOOS == "darwin" || runtime.GOOS == "windows") {
43			return
44		}
45		t.Skip("skipping test in -short mode")
46	}
47}
48
49func init() {
50	switch runtime.GOOS {
51	case "android", "nacl":
52		canRun = false
53	case "darwin":
54		switch runtime.GOARCH {
55		case "arm", "arm64":
56			canRun = false
57		}
58	case "linux":
59		switch runtime.GOARCH {
60		case "arm":
61			// many linux/arm machines are too slow to run
62			// the full set of external tests.
63			skipExternal = true
64		case "mips", "mipsle", "mips64", "mips64le":
65			// Also slow.
66			skipExternal = true
67			if testenv.Builder() != "" {
68				// On the builders, skip the cmd/go
69				// tests. They're too slow and already
70				// covered by other ports. There's
71				// nothing os/arch specific in the
72				// tests.
73				canRun = false
74			}
75		}
76	case "freebsd":
77		switch runtime.GOARCH {
78		case "arm":
79			// many freebsd/arm machines are too slow to run
80			// the full set of external tests.
81			skipExternal = true
82			canRun = false
83		}
84	case "plan9":
85		switch runtime.GOARCH {
86		case "arm":
87			// many plan9/arm machines are too slow to run
88			// the full set of external tests.
89			skipExternal = true
90		}
91	case "windows":
92		exeSuffix = ".exe"
93	}
94}
95
96// testGOROOT is the GOROOT to use when running testgo, a cmd/go binary
97// build from this process's current GOROOT, but run from a different
98// (temp) directory.
99var testGOROOT string
100
101var testCC string
102
103// The TestMain function creates a go command for testing purposes and
104// deletes it after the tests have been run.
105func TestMain(m *testing.M) {
106	if os.Getenv("GO_GCFLAGS") != "" {
107		fmt.Fprintf(os.Stderr, "testing: warning: no tests to run\n") // magic string for cmd/go
108		fmt.Printf("cmd/go test is not compatible with $GO_GCFLAGS being set\n")
109		fmt.Printf("SKIP\n")
110		return
111	}
112	os.Unsetenv("GOROOT_FINAL")
113
114	if canRun {
115		args := []string{"build", "-tags", "testgo", "-o", "testgo" + exeSuffix}
116		if race.Enabled {
117			args = append(args, "-race")
118		}
119		gotool, err := testenv.GoTool()
120		if err != nil {
121			fmt.Fprintln(os.Stderr, err)
122			os.Exit(2)
123		}
124
125		goEnv := func(name string) string {
126			out, err := exec.Command(gotool, "env", name).CombinedOutput()
127			if err != nil {
128				fmt.Fprintf(os.Stderr, "go env %s: %v\n%s", name, err, out)
129				os.Exit(2)
130			}
131			return strings.TrimSpace(string(out))
132		}
133		testGOROOT = goEnv("GOROOT")
134
135		// The whole GOROOT/pkg tree was installed using the GOHOSTOS/GOHOSTARCH
136		// toolchain (installed in GOROOT/pkg/tool/GOHOSTOS_GOHOSTARCH).
137		// The testgo.exe we are about to create will be built for GOOS/GOARCH,
138		// which means it will use the GOOS/GOARCH toolchain
139		// (installed in GOROOT/pkg/tool/GOOS_GOARCH).
140		// If these are not the same toolchain, then the entire standard library
141		// will look out of date (the compilers in those two different tool directories
142		// are built for different architectures and have different buid IDs),
143		// which will cause many tests to do unnecessary rebuilds and some
144		// tests to attempt to overwrite the installed standard library.
145		// Bail out entirely in this case.
146		hostGOOS := goEnv("GOHOSTOS")
147		hostGOARCH := goEnv("GOHOSTARCH")
148		if hostGOOS != runtime.GOOS || hostGOARCH != runtime.GOARCH {
149			fmt.Fprintf(os.Stderr, "testing: warning: no tests to run\n") // magic string for cmd/go
150			fmt.Printf("cmd/go test is not compatible with GOOS/GOARCH != GOHOSTOS/GOHOSTARCH (%s/%s != %s/%s)\n", runtime.GOOS, runtime.GOARCH, hostGOOS, hostGOARCH)
151			fmt.Printf("SKIP\n")
152			return
153		}
154
155		out, err := exec.Command(gotool, args...).CombinedOutput()
156		if err != nil {
157			fmt.Fprintf(os.Stderr, "building testgo failed: %v\n%s", err, out)
158			os.Exit(2)
159		}
160
161		out, err = exec.Command(gotool, "env", "CC").CombinedOutput()
162		if err != nil {
163			fmt.Fprintf(os.Stderr, "could not find testing CC: %v\n%s", err, out)
164			os.Exit(2)
165		}
166		testCC = strings.TrimSpace(string(out))
167
168		if out, err := exec.Command("./testgo"+exeSuffix, "env", "CGO_ENABLED").Output(); err != nil {
169			fmt.Fprintf(os.Stderr, "running testgo failed: %v\n", err)
170			canRun = false
171		} else {
172			canCgo, err = strconv.ParseBool(strings.TrimSpace(string(out)))
173			if err != nil {
174				fmt.Fprintf(os.Stderr, "can't parse go env CGO_ENABLED output: %v\n", strings.TrimSpace(string(out)))
175			}
176		}
177
178		// As of Sept 2017, MSan is only supported on linux/amd64.
179		// https://github.com/google/sanitizers/wiki/MemorySanitizer#getting-memorysanitizer
180		canMSan = canCgo && runtime.GOOS == "linux" && runtime.GOARCH == "amd64"
181
182		switch runtime.GOOS {
183		case "linux", "darwin", "freebsd", "windows":
184			// The race detector doesn't work on Alpine Linux:
185			// golang.org/issue/14481
186			canRace = canCgo && runtime.GOARCH == "amd64" && !isAlpineLinux() && runtime.Compiler != "gccgo"
187		}
188	}
189	// Don't let these environment variables confuse the test.
190	os.Unsetenv("GOBIN")
191	os.Unsetenv("GOPATH")
192	os.Unsetenv("GIT_ALLOW_PROTOCOL")
193	if home, ccacheDir := os.Getenv("HOME"), os.Getenv("CCACHE_DIR"); home != "" && ccacheDir == "" {
194		// On some systems the default C compiler is ccache.
195		// Setting HOME to a non-existent directory will break
196		// those systems. Set CCACHE_DIR to cope. Issue 17668.
197		os.Setenv("CCACHE_DIR", filepath.Join(home, ".ccache"))
198	}
199	os.Setenv("HOME", "/test-go-home-does-not-exist")
200	if os.Getenv("GOCACHE") == "" {
201		os.Setenv("GOCACHE", "off") // because $HOME is gone
202	}
203
204	r := m.Run()
205
206	if canRun {
207		os.Remove("testgo" + exeSuffix)
208	}
209
210	os.Exit(r)
211}
212
213func isAlpineLinux() bool {
214	if runtime.GOOS != "linux" {
215		return false
216	}
217	fi, err := os.Lstat("/etc/alpine-release")
218	return err == nil && fi.Mode().IsRegular()
219}
220
221// The length of an mtime tick on this system. This is an estimate of
222// how long we need to sleep to ensure that the mtime of two files is
223// different.
224// We used to try to be clever but that didn't always work (see golang.org/issue/12205).
225var mtimeTick time.Duration = 1 * time.Second
226
227// Manage a single run of the testgo binary.
228type testgoData struct {
229	t              *testing.T
230	temps          []string
231	wd             string
232	env            []string
233	tempdir        string
234	ran            bool
235	inParallel     bool
236	stdout, stderr bytes.Buffer
237}
238
239// skipIfGccgo skips the test if using gccgo.
240func skipIfGccgo(t *testing.T, msg string) {
241	if runtime.Compiler == "gccgo" {
242		t.Skipf("skipping test not supported on gccgo: %s", msg)
243	}
244}
245
246// testgo sets up for a test that runs testgo.
247func testgo(t *testing.T) *testgoData {
248	t.Helper()
249	testenv.MustHaveGoBuild(t)
250
251	if skipExternal {
252		t.Skipf("skipping external tests on %s/%s", runtime.GOOS, runtime.GOARCH)
253	}
254
255	return &testgoData{t: t}
256}
257
258// must gives a fatal error if err is not nil.
259func (tg *testgoData) must(err error) {
260	tg.t.Helper()
261	if err != nil {
262		tg.t.Fatal(err)
263	}
264}
265
266// check gives a test non-fatal error if err is not nil.
267func (tg *testgoData) check(err error) {
268	tg.t.Helper()
269	if err != nil {
270		tg.t.Error(err)
271	}
272}
273
274// parallel runs the test in parallel by calling t.Parallel.
275func (tg *testgoData) parallel() {
276	tg.t.Helper()
277	if tg.ran {
278		tg.t.Fatal("internal testsuite error: call to parallel after run")
279	}
280	if tg.wd != "" {
281		tg.t.Fatal("internal testsuite error: call to parallel after cd")
282	}
283	for _, e := range tg.env {
284		if strings.HasPrefix(e, "GOROOT=") || strings.HasPrefix(e, "GOPATH=") || strings.HasPrefix(e, "GOBIN=") {
285			val := e[strings.Index(e, "=")+1:]
286			if strings.HasPrefix(val, "testdata") || strings.HasPrefix(val, "./testdata") {
287				tg.t.Fatalf("internal testsuite error: call to parallel with testdata in environment (%s)", e)
288			}
289		}
290	}
291	tg.inParallel = true
292	tg.t.Parallel()
293}
294
295// pwd returns the current directory.
296func (tg *testgoData) pwd() string {
297	tg.t.Helper()
298	wd, err := os.Getwd()
299	if err != nil {
300		tg.t.Fatalf("could not get working directory: %v", err)
301	}
302	return wd
303}
304
305// cd changes the current directory to the named directory. Note that
306// using this means that the test must not be run in parallel with any
307// other tests.
308func (tg *testgoData) cd(dir string) {
309	tg.t.Helper()
310	if tg.inParallel {
311		tg.t.Fatal("internal testsuite error: changing directory when running in parallel")
312	}
313	if tg.wd == "" {
314		tg.wd = tg.pwd()
315	}
316	abs, err := filepath.Abs(dir)
317	tg.must(os.Chdir(dir))
318	if err == nil {
319		tg.setenv("PWD", abs)
320	}
321}
322
323// sleep sleeps for one tick, where a tick is a conservative estimate
324// of how long it takes for a file modification to get a different
325// mtime.
326func (tg *testgoData) sleep() {
327	time.Sleep(mtimeTick)
328}
329
330// setenv sets an environment variable to use when running the test go
331// command.
332func (tg *testgoData) setenv(name, val string) {
333	tg.t.Helper()
334	if tg.inParallel && (name == "GOROOT" || name == "GOPATH" || name == "GOBIN") && (strings.HasPrefix(val, "testdata") || strings.HasPrefix(val, "./testdata")) {
335		tg.t.Fatalf("internal testsuite error: call to setenv with testdata (%s=%s) after parallel", name, val)
336	}
337	tg.unsetenv(name)
338	tg.env = append(tg.env, name+"="+val)
339}
340
341// unsetenv removes an environment variable.
342func (tg *testgoData) unsetenv(name string) {
343	if tg.env == nil {
344		tg.env = append([]string(nil), os.Environ()...)
345	}
346	for i, v := range tg.env {
347		if strings.HasPrefix(v, name+"=") {
348			tg.env = append(tg.env[:i], tg.env[i+1:]...)
349			break
350		}
351	}
352}
353
354func (tg *testgoData) goTool() string {
355	if tg.wd == "" {
356		return "./testgo" + exeSuffix
357	}
358	return filepath.Join(tg.wd, "testgo"+exeSuffix)
359}
360
361// doRun runs the test go command, recording stdout and stderr and
362// returning exit status.
363func (tg *testgoData) doRun(args []string) error {
364	tg.t.Helper()
365	if !canRun {
366		panic("testgoData.doRun called but canRun false")
367	}
368	if tg.inParallel {
369		for _, arg := range args {
370			if strings.HasPrefix(arg, "testdata") || strings.HasPrefix(arg, "./testdata") {
371				tg.t.Fatal("internal testsuite error: parallel run using testdata")
372			}
373		}
374	}
375
376	hasGoroot := false
377	for _, v := range tg.env {
378		if strings.HasPrefix(v, "GOROOT=") {
379			hasGoroot = true
380			break
381		}
382	}
383	prog := tg.goTool()
384	if !hasGoroot {
385		tg.setenv("GOROOT", testGOROOT)
386	}
387
388	tg.t.Logf("running testgo %v", args)
389	cmd := exec.Command(prog, args...)
390	tg.stdout.Reset()
391	tg.stderr.Reset()
392	cmd.Stdout = &tg.stdout
393	cmd.Stderr = &tg.stderr
394	cmd.Env = tg.env
395	status := cmd.Run()
396	if tg.stdout.Len() > 0 {
397		tg.t.Log("standard output:")
398		tg.t.Log(tg.stdout.String())
399	}
400	if tg.stderr.Len() > 0 {
401		tg.t.Log("standard error:")
402		tg.t.Log(tg.stderr.String())
403	}
404	tg.ran = true
405	return status
406}
407
408// run runs the test go command, and expects it to succeed.
409func (tg *testgoData) run(args ...string) {
410	tg.t.Helper()
411	if status := tg.doRun(args); status != nil {
412		tg.t.Logf("go %v failed unexpectedly: %v", args, status)
413		tg.t.FailNow()
414	}
415}
416
417// runFail runs the test go command, and expects it to fail.
418func (tg *testgoData) runFail(args ...string) {
419	tg.t.Helper()
420	if status := tg.doRun(args); status == nil {
421		tg.t.Fatal("testgo succeeded unexpectedly")
422	} else {
423		tg.t.Log("testgo failed as expected:", status)
424	}
425}
426
427// runGit runs a git command, and expects it to succeed.
428func (tg *testgoData) runGit(dir string, args ...string) {
429	tg.t.Helper()
430	cmd := exec.Command("git", args...)
431	tg.stdout.Reset()
432	tg.stderr.Reset()
433	cmd.Stdout = &tg.stdout
434	cmd.Stderr = &tg.stderr
435	cmd.Dir = dir
436	cmd.Env = tg.env
437	status := cmd.Run()
438	if tg.stdout.Len() > 0 {
439		tg.t.Log("git standard output:")
440		tg.t.Log(tg.stdout.String())
441	}
442	if tg.stderr.Len() > 0 {
443		tg.t.Log("git standard error:")
444		tg.t.Log(tg.stderr.String())
445	}
446	if status != nil {
447		tg.t.Logf("git %v failed unexpectedly: %v", args, status)
448		tg.t.FailNow()
449	}
450}
451
452// getStdout returns standard output of the testgo run as a string.
453func (tg *testgoData) getStdout() string {
454	tg.t.Helper()
455	if !tg.ran {
456		tg.t.Fatal("internal testsuite error: stdout called before run")
457	}
458	return tg.stdout.String()
459}
460
461// getStderr returns standard error of the testgo run as a string.
462func (tg *testgoData) getStderr() string {
463	tg.t.Helper()
464	if !tg.ran {
465		tg.t.Fatal("internal testsuite error: stdout called before run")
466	}
467	return tg.stderr.String()
468}
469
470// doGrepMatch looks for a regular expression in a buffer, and returns
471// whether it is found. The regular expression is matched against
472// each line separately, as with the grep command.
473func (tg *testgoData) doGrepMatch(match string, b *bytes.Buffer) bool {
474	tg.t.Helper()
475	if !tg.ran {
476		tg.t.Fatal("internal testsuite error: grep called before run")
477	}
478	re := regexp.MustCompile(match)
479	for _, ln := range bytes.Split(b.Bytes(), []byte{'\n'}) {
480		if re.Match(ln) {
481			return true
482		}
483	}
484	return false
485}
486
487// doGrep looks for a regular expression in a buffer and fails if it
488// is not found. The name argument is the name of the output we are
489// searching, "output" or "error". The msg argument is logged on
490// failure.
491func (tg *testgoData) doGrep(match string, b *bytes.Buffer, name, msg string) {
492	tg.t.Helper()
493	if !tg.doGrepMatch(match, b) {
494		tg.t.Log(msg)
495		tg.t.Logf("pattern %v not found in standard %s", match, name)
496		tg.t.FailNow()
497	}
498}
499
500// grepStdout looks for a regular expression in the test run's
501// standard output and fails, logging msg, if it is not found.
502func (tg *testgoData) grepStdout(match, msg string) {
503	tg.t.Helper()
504	tg.doGrep(match, &tg.stdout, "output", msg)
505}
506
507// grepStderr looks for a regular expression in the test run's
508// standard error and fails, logging msg, if it is not found.
509func (tg *testgoData) grepStderr(match, msg string) {
510	tg.t.Helper()
511	tg.doGrep(match, &tg.stderr, "error", msg)
512}
513
514// grepBoth looks for a regular expression in the test run's standard
515// output or stand error and fails, logging msg, if it is not found.
516func (tg *testgoData) grepBoth(match, msg string) {
517	tg.t.Helper()
518	if !tg.doGrepMatch(match, &tg.stdout) && !tg.doGrepMatch(match, &tg.stderr) {
519		tg.t.Log(msg)
520		tg.t.Logf("pattern %v not found in standard output or standard error", match)
521		tg.t.FailNow()
522	}
523}
524
525// doGrepNot looks for a regular expression in a buffer and fails if
526// it is found. The name and msg arguments are as for doGrep.
527func (tg *testgoData) doGrepNot(match string, b *bytes.Buffer, name, msg string) {
528	tg.t.Helper()
529	if tg.doGrepMatch(match, b) {
530		tg.t.Log(msg)
531		tg.t.Logf("pattern %v found unexpectedly in standard %s", match, name)
532		tg.t.FailNow()
533	}
534}
535
536// grepStdoutNot looks for a regular expression in the test run's
537// standard output and fails, logging msg, if it is found.
538func (tg *testgoData) grepStdoutNot(match, msg string) {
539	tg.t.Helper()
540	tg.doGrepNot(match, &tg.stdout, "output", msg)
541}
542
543// grepStderrNot looks for a regular expression in the test run's
544// standard error and fails, logging msg, if it is found.
545func (tg *testgoData) grepStderrNot(match, msg string) {
546	tg.t.Helper()
547	tg.doGrepNot(match, &tg.stderr, "error", msg)
548}
549
550// grepBothNot looks for a regular expression in the test run's
551// standard output or stand error and fails, logging msg, if it is
552// found.
553func (tg *testgoData) grepBothNot(match, msg string) {
554	tg.t.Helper()
555	if tg.doGrepMatch(match, &tg.stdout) || tg.doGrepMatch(match, &tg.stderr) {
556		tg.t.Log(msg)
557		tg.t.Fatalf("pattern %v found unexpectedly in standard output or standard error", match)
558	}
559}
560
561// doGrepCount counts the number of times a regexp is seen in a buffer.
562func (tg *testgoData) doGrepCount(match string, b *bytes.Buffer) int {
563	tg.t.Helper()
564	if !tg.ran {
565		tg.t.Fatal("internal testsuite error: doGrepCount called before run")
566	}
567	re := regexp.MustCompile(match)
568	c := 0
569	for _, ln := range bytes.Split(b.Bytes(), []byte{'\n'}) {
570		if re.Match(ln) {
571			c++
572		}
573	}
574	return c
575}
576
577// grepCountBoth returns the number of times a regexp is seen in both
578// standard output and standard error.
579func (tg *testgoData) grepCountBoth(match string) int {
580	tg.t.Helper()
581	return tg.doGrepCount(match, &tg.stdout) + tg.doGrepCount(match, &tg.stderr)
582}
583
584// creatingTemp records that the test plans to create a temporary file
585// or directory. If the file or directory exists already, it will be
586// removed. When the test completes, the file or directory will be
587// removed if it exists.
588func (tg *testgoData) creatingTemp(path string) {
589	tg.t.Helper()
590	if filepath.IsAbs(path) && !strings.HasPrefix(path, tg.tempdir) {
591		tg.t.Fatalf("internal testsuite error: creatingTemp(%q) with absolute path not in temporary directory", path)
592	}
593	// If we have changed the working directory, make sure we have
594	// an absolute path, because we are going to change directory
595	// back before we remove the temporary.
596	if tg.wd != "" && !filepath.IsAbs(path) {
597		path = filepath.Join(tg.pwd(), path)
598	}
599	tg.must(os.RemoveAll(path))
600	tg.temps = append(tg.temps, path)
601}
602
603// makeTempdir makes a temporary directory for a run of testgo. If
604// the temporary directory was already created, this does nothing.
605func (tg *testgoData) makeTempdir() {
606	tg.t.Helper()
607	if tg.tempdir == "" {
608		var err error
609		tg.tempdir, err = ioutil.TempDir("", "gotest")
610		tg.must(err)
611	}
612}
613
614// tempFile adds a temporary file for a run of testgo.
615func (tg *testgoData) tempFile(path, contents string) {
616	tg.t.Helper()
617	tg.makeTempdir()
618	tg.must(os.MkdirAll(filepath.Join(tg.tempdir, filepath.Dir(path)), 0755))
619	bytes := []byte(contents)
620	if strings.HasSuffix(path, ".go") {
621		formatted, err := format.Source(bytes)
622		if err == nil {
623			bytes = formatted
624		}
625	}
626	tg.must(ioutil.WriteFile(filepath.Join(tg.tempdir, path), bytes, 0644))
627}
628
629// tempDir adds a temporary directory for a run of testgo.
630func (tg *testgoData) tempDir(path string) {
631	tg.t.Helper()
632	tg.makeTempdir()
633	if err := os.MkdirAll(filepath.Join(tg.tempdir, path), 0755); err != nil && !os.IsExist(err) {
634		tg.t.Fatal(err)
635	}
636}
637
638// path returns the absolute pathname to file with the temporary
639// directory.
640func (tg *testgoData) path(name string) string {
641	tg.t.Helper()
642	if tg.tempdir == "" {
643		tg.t.Fatalf("internal testsuite error: path(%q) with no tempdir", name)
644	}
645	if name == "." {
646		return tg.tempdir
647	}
648	return filepath.Join(tg.tempdir, name)
649}
650
651// mustExist fails if path does not exist.
652func (tg *testgoData) mustExist(path string) {
653	tg.t.Helper()
654	if _, err := os.Stat(path); err != nil {
655		if os.IsNotExist(err) {
656			tg.t.Fatalf("%s does not exist but should", path)
657		}
658		tg.t.Fatalf("%s stat failed: %v", path, err)
659	}
660}
661
662// mustNotExist fails if path exists.
663func (tg *testgoData) mustNotExist(path string) {
664	tg.t.Helper()
665	if _, err := os.Stat(path); err == nil || !os.IsNotExist(err) {
666		tg.t.Fatalf("%s exists but should not (%v)", path, err)
667	}
668}
669
670// mustHaveContent succeeds if filePath is a path to a file,
671// and that file is readable and not empty.
672func (tg *testgoData) mustHaveContent(filePath string) {
673	tg.mustExist(filePath)
674	f, err := os.Stat(filePath)
675	if err != nil {
676		tg.t.Fatal(err)
677	}
678	if f.Size() == 0 {
679		tg.t.Fatalf("expected %s to have data, but is empty", filePath)
680	}
681}
682
683// wantExecutable fails with msg if path is not executable.
684func (tg *testgoData) wantExecutable(path, msg string) {
685	tg.t.Helper()
686	if st, err := os.Stat(path); err != nil {
687		if !os.IsNotExist(err) {
688			tg.t.Log(err)
689		}
690		tg.t.Fatal(msg)
691	} else {
692		if runtime.GOOS != "windows" && st.Mode()&0111 == 0 {
693			tg.t.Fatalf("binary %s exists but is not executable", path)
694		}
695	}
696}
697
698// wantArchive fails if path is not an archive.
699func (tg *testgoData) wantArchive(path string) {
700	tg.t.Helper()
701	f, err := os.Open(path)
702	if err != nil {
703		tg.t.Fatal(err)
704	}
705	buf := make([]byte, 100)
706	io.ReadFull(f, buf)
707	f.Close()
708	if !bytes.HasPrefix(buf, []byte("!<arch>\n")) {
709		tg.t.Fatalf("file %s exists but is not an archive", path)
710	}
711}
712
713// isStale reports whether pkg is stale, and why
714func (tg *testgoData) isStale(pkg string) (bool, string) {
715	tg.t.Helper()
716	tg.run("list", "-f", "{{.Stale}}:{{.StaleReason}}", pkg)
717	v := strings.TrimSpace(tg.getStdout())
718	f := strings.SplitN(v, ":", 2)
719	if len(f) == 2 {
720		switch f[0] {
721		case "true":
722			return true, f[1]
723		case "false":
724			return false, f[1]
725		}
726	}
727	tg.t.Fatalf("unexpected output checking staleness of package %v: %v", pkg, v)
728	panic("unreachable")
729}
730
731// wantStale fails with msg if pkg is not stale.
732func (tg *testgoData) wantStale(pkg, reason, msg string) {
733	tg.t.Helper()
734	stale, why := tg.isStale(pkg)
735	if !stale {
736		tg.t.Fatal(msg)
737	}
738	if reason == "" && why != "" || !strings.Contains(why, reason) {
739		tg.t.Errorf("wrong reason for Stale=true: %q, want %q", why, reason)
740	}
741}
742
743// wantNotStale fails with msg if pkg is stale.
744func (tg *testgoData) wantNotStale(pkg, reason, msg string) {
745	tg.t.Helper()
746	stale, why := tg.isStale(pkg)
747	if stale {
748		tg.t.Fatal(msg)
749	}
750	if reason == "" && why != "" || !strings.Contains(why, reason) {
751		tg.t.Errorf("wrong reason for Stale=false: %q, want %q", why, reason)
752	}
753}
754
755// cleanup cleans up a test that runs testgo.
756func (tg *testgoData) cleanup() {
757	tg.t.Helper()
758	if tg.wd != "" {
759		if err := os.Chdir(tg.wd); err != nil {
760			// We are unlikely to be able to continue.
761			fmt.Fprintln(os.Stderr, "could not restore working directory, crashing:", err)
762			os.Exit(2)
763		}
764	}
765	for _, path := range tg.temps {
766		tg.check(os.RemoveAll(path))
767	}
768	if tg.tempdir != "" {
769		tg.check(os.RemoveAll(tg.tempdir))
770	}
771}
772
773// failSSH puts an ssh executable in the PATH that always fails.
774// This is to stub out uses of ssh by go get.
775func (tg *testgoData) failSSH() {
776	tg.t.Helper()
777	wd, err := os.Getwd()
778	if err != nil {
779		tg.t.Fatal(err)
780	}
781	fail := filepath.Join(wd, "testdata/failssh")
782	tg.setenv("PATH", fmt.Sprintf("%v%c%v", fail, filepath.ListSeparator, os.Getenv("PATH")))
783}
784
785func TestBuildComplex(t *testing.T) {
786	// Simple smoke test for build configuration.
787	tg := testgo(t)
788	defer tg.cleanup()
789	tg.parallel()
790	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
791	tg.run("build", "-x", "-o", os.DevNull, "complex")
792
793	if _, err := exec.LookPath("gccgo"); err == nil {
794		t.Skip("golang.org/issue/22472")
795		tg.run("build", "-x", "-o", os.DevNull, "-compiler=gccgo", "complex")
796	}
797}
798
799func TestFileLineInErrorMessages(t *testing.T) {
800	tg := testgo(t)
801	defer tg.cleanup()
802	tg.parallel()
803	tg.tempFile("err.go", `package main; import "bar"`)
804	path := tg.path("err.go")
805	tg.runFail("run", path)
806	shortPath := path
807	if rel, err := filepath.Rel(tg.pwd(), path); err == nil && len(rel) < len(path) {
808		shortPath = rel
809	}
810	tg.grepStderr("^"+regexp.QuoteMeta(shortPath)+":", "missing file:line in error message")
811}
812
813func TestProgramNameInCrashMessages(t *testing.T) {
814	skipIfGccgo(t, "gccgo does not use cmd/link")
815	tg := testgo(t)
816	defer tg.cleanup()
817	tg.parallel()
818	tg.tempFile("triv.go", `package main; func main() {}`)
819	tg.runFail("build", "-ldflags", "-crash_for_testing", tg.path("triv.go"))
820	tg.grepStderr(`[/\\]tool[/\\].*[/\\]link`, "missing linker name in error message")
821}
822
823func TestBrokenTestsWithoutTestFunctionsAllFail(t *testing.T) {
824	tg := testgo(t)
825	defer tg.cleanup()
826	// TODO: tg.parallel()
827	tg.runFail("test", "./testdata/src/badtest/...")
828	tg.grepBothNot("^ok", "test passed unexpectedly")
829	tg.grepBoth("FAIL.*badtest/badexec", "test did not run everything")
830	tg.grepBoth("FAIL.*badtest/badsyntax", "test did not run everything")
831	tg.grepBoth("FAIL.*badtest/badvar", "test did not run everything")
832}
833
834func TestGoBuildDashAInDevBranch(t *testing.T) {
835	if testing.Short() {
836		t.Skip("don't rebuild the standard library in short mode")
837	}
838
839	tg := testgo(t)
840	defer tg.cleanup()
841	tg.run("install", "math") // should be up to date already but just in case
842	tg.setenv("TESTGO_IS_GO_RELEASE", "0")
843	tg.run("build", "-v", "-a", "math")
844	tg.grepStderr("runtime", "testgo build -a math in dev branch DID NOT build runtime, but should have")
845
846	// Everything is out of date. Rebuild to leave things in a better state.
847	tg.run("install", "std")
848}
849
850func TestGoBuildDashAInReleaseBranch(t *testing.T) {
851	if testing.Short() {
852		t.Skip("don't rebuild the standard library in short mode")
853	}
854
855	tg := testgo(t)
856	defer tg.cleanup()
857	tg.run("install", "math", "net/http") // should be up to date already but just in case
858	tg.setenv("TESTGO_IS_GO_RELEASE", "1")
859	tg.run("install", "-v", "-a", "math")
860	tg.grepStderr("runtime", "testgo build -a math in release branch DID NOT build runtime, but should have")
861
862	// Now runtime.a is updated (newer mtime), so everything would look stale if not for being a release.
863	tg.run("build", "-v", "net/http")
864	tg.grepStderrNot("strconv", "testgo build -v net/http in release branch with newer runtime.a DID build strconv but should not have")
865	tg.grepStderrNot("golang.org/x/net/http2/hpack", "testgo build -v net/http in release branch with newer runtime.a DID build .../golang.org/x/net/http2/hpack but should not have")
866	tg.grepStderrNot("net/http", "testgo build -v net/http in release branch with newer runtime.a DID build net/http but should not have")
867
868	// Everything is out of date. Rebuild to leave things in a better state.
869	tg.run("install", "std")
870}
871
872func TestNewReleaseRebuildsStalePackagesInGOPATH(t *testing.T) {
873	if testing.Short() {
874		t.Skip("don't rebuild the standard library in short mode")
875	}
876
877	tg := testgo(t)
878	defer tg.cleanup()
879
880	addNL := func(name string) (restore func()) {
881		data, err := ioutil.ReadFile(name)
882		if err != nil {
883			t.Fatal(err)
884		}
885		old := data
886		data = append(data, '\n')
887		if err := ioutil.WriteFile(name, append(data, '\n'), 0666); err != nil {
888			t.Fatal(err)
889		}
890		tg.sleep()
891		return func() {
892			if err := ioutil.WriteFile(name, old, 0666); err != nil {
893				t.Fatal(err)
894			}
895		}
896	}
897
898	tg.tempFile("d1/src/p1/p1.go", `package p1`)
899	tg.setenv("GOPATH", tg.path("d1"))
900	tg.run("install", "-a", "p1")
901	tg.wantNotStale("p1", "", "./testgo list claims p1 is stale, incorrectly, before any changes")
902
903	// Changing mtime of runtime/internal/sys/sys.go
904	// should have no effect: only the content matters.
905	// In fact this should be true even outside a release branch.
906	sys := runtime.GOROOT() + "/src/runtime/internal/sys/sys.go"
907	tg.sleep()
908	restore := addNL(sys)
909	restore()
910	tg.wantNotStale("p1", "", "./testgo list claims p1 is stale, incorrectly, after updating mtime of runtime/internal/sys/sys.go")
911
912	// But changing content of any file should have an effect.
913	// Previously zversion.go was the only one that mattered;
914	// now they all matter, so keep using sys.go.
915	restore = addNL(sys)
916	defer restore()
917	tg.wantStale("p1", "stale dependency: runtime/internal/sys", "./testgo list claims p1 is NOT stale, incorrectly, after changing sys.go")
918	restore()
919	tg.wantNotStale("p1", "", "./testgo list claims p1 is stale, incorrectly, after changing back to old release")
920	addNL(sys)
921	tg.wantStale("p1", "stale dependency: runtime/internal/sys", "./testgo list claims p1 is NOT stale, incorrectly, after changing sys.go again")
922	tg.run("install", "p1")
923	tg.wantNotStale("p1", "", "./testgo list claims p1 is stale after building with new release")
924
925	// Restore to "old" release.
926	restore()
927	tg.wantStale("p1", "stale dependency: runtime/internal/sys", "./testgo list claims p1 is NOT stale, incorrectly, after restoring sys.go")
928	tg.run("install", "p1")
929	tg.wantNotStale("p1", "", "./testgo list claims p1 is stale after building with old release")
930
931	// Everything is out of date. Rebuild to leave things in a better state.
932	tg.run("install", "std")
933}
934
935func TestGoListStandard(t *testing.T) {
936	skipIfGccgo(t, "gccgo does not GOROOT")
937	tooSlow(t)
938	tg := testgo(t)
939	defer tg.cleanup()
940	// TODO: tg.parallel()
941	tg.cd(runtime.GOROOT() + "/src")
942	tg.run("list", "-f", "{{if not .Standard}}{{.ImportPath}}{{end}}", "./...")
943	stdout := tg.getStdout()
944	for _, line := range strings.Split(stdout, "\n") {
945		if strings.HasPrefix(line, "_/") && strings.HasSuffix(line, "/src") {
946			// $GOROOT/src shows up if there are any .go files there.
947			// We don't care.
948			continue
949		}
950		if line == "" {
951			continue
952		}
953		t.Errorf("package in GOROOT not listed as standard: %v", line)
954	}
955
956	// Similarly, expanding std should include some of our vendored code.
957	tg.run("list", "std", "cmd")
958	tg.grepStdout("golang.org/x/net/http2/hpack", "list std cmd did not mention vendored hpack")
959	tg.grepStdout("golang.org/x/arch/x86/x86asm", "list std cmd did not mention vendored x86asm")
960}
961
962func TestGoInstallCleansUpAfterGoBuild(t *testing.T) {
963	tooSlow(t)
964	tg := testgo(t)
965	defer tg.cleanup()
966	// TODO: tg.parallel()
967	tg.tempFile("src/mycmd/main.go", `package main; func main(){}`)
968	tg.setenv("GOPATH", tg.path("."))
969	tg.cd(tg.path("src/mycmd"))
970
971	doesNotExist := func(file, msg string) {
972		if _, err := os.Stat(file); err == nil {
973			t.Fatal(msg)
974		} else if !os.IsNotExist(err) {
975			t.Fatal(msg, "error:", err)
976		}
977	}
978
979	tg.run("build")
980	tg.wantExecutable("mycmd"+exeSuffix, "testgo build did not write command binary")
981	tg.run("install")
982	doesNotExist("mycmd"+exeSuffix, "testgo install did not remove command binary")
983	tg.run("build")
984	tg.wantExecutable("mycmd"+exeSuffix, "testgo build did not write command binary (second time)")
985	// Running install with arguments does not remove the target,
986	// even in the same directory.
987	tg.run("install", "mycmd")
988	tg.wantExecutable("mycmd"+exeSuffix, "testgo install mycmd removed command binary when run in mycmd")
989	tg.run("build")
990	tg.wantExecutable("mycmd"+exeSuffix, "testgo build did not write command binary (third time)")
991	// And especially not outside the directory.
992	tg.cd(tg.path("."))
993	if data, err := ioutil.ReadFile("src/mycmd/mycmd" + exeSuffix); err != nil {
994		t.Fatal("could not read file:", err)
995	} else {
996		if err := ioutil.WriteFile("mycmd"+exeSuffix, data, 0555); err != nil {
997			t.Fatal("could not write file:", err)
998		}
999	}
1000	tg.run("install", "mycmd")
1001	tg.wantExecutable("src/mycmd/mycmd"+exeSuffix, "testgo install mycmd removed command binary from its source dir when run outside mycmd")
1002	tg.wantExecutable("mycmd"+exeSuffix, "testgo install mycmd removed command binary from current dir when run outside mycmd")
1003}
1004
1005func TestGoInstallRebuildsStalePackagesInOtherGOPATH(t *testing.T) {
1006	tooSlow(t)
1007	tg := testgo(t)
1008	defer tg.cleanup()
1009	tg.parallel()
1010	tg.tempFile("d1/src/p1/p1.go", `package p1
1011		import "p2"
1012		func F() { p2.F() }`)
1013	tg.tempFile("d2/src/p2/p2.go", `package p2
1014		func F() {}`)
1015	sep := string(filepath.ListSeparator)
1016	tg.setenv("GOPATH", tg.path("d1")+sep+tg.path("d2"))
1017	tg.run("install", "-i", "p1")
1018	tg.wantNotStale("p1", "", "./testgo list claims p1 is stale, incorrectly")
1019	tg.wantNotStale("p2", "", "./testgo list claims p2 is stale, incorrectly")
1020	tg.sleep()
1021	if f, err := os.OpenFile(tg.path("d2/src/p2/p2.go"), os.O_WRONLY|os.O_APPEND, 0); err != nil {
1022		t.Fatal(err)
1023	} else if _, err = f.WriteString(`func G() {}`); err != nil {
1024		t.Fatal(err)
1025	} else {
1026		tg.must(f.Close())
1027	}
1028	tg.wantStale("p2", "build ID mismatch", "./testgo list claims p2 is NOT stale, incorrectly")
1029	tg.wantStale("p1", "stale dependency: p2", "./testgo list claims p1 is NOT stale, incorrectly")
1030
1031	tg.run("install", "-i", "p1")
1032	tg.wantNotStale("p2", "", "./testgo list claims p2 is stale after reinstall, incorrectly")
1033	tg.wantNotStale("p1", "", "./testgo list claims p1 is stale after reinstall, incorrectly")
1034}
1035
1036func TestGoInstallDetectsRemovedFiles(t *testing.T) {
1037	skipIfGccgo(t, "gccgo does not yet support package build IDs")
1038	tg := testgo(t)
1039	defer tg.cleanup()
1040	tg.parallel()
1041	tg.tempFile("src/mypkg/x.go", `package mypkg`)
1042	tg.tempFile("src/mypkg/y.go", `package mypkg`)
1043	tg.tempFile("src/mypkg/z.go", `// +build missingtag
1044
1045		package mypkg`)
1046	tg.setenv("GOPATH", tg.path("."))
1047	tg.run("install", "mypkg")
1048	tg.wantNotStale("mypkg", "", "./testgo list mypkg claims mypkg is stale, incorrectly")
1049	// z.go was not part of the build; removing it is okay.
1050	tg.must(os.Remove(tg.path("src/mypkg/z.go")))
1051	tg.wantNotStale("mypkg", "", "./testgo list mypkg claims mypkg is stale after removing z.go; should not be stale")
1052	// y.go was part of the package; removing it should be detected.
1053	tg.must(os.Remove(tg.path("src/mypkg/y.go")))
1054	tg.wantStale("mypkg", "build ID mismatch", "./testgo list mypkg claims mypkg is NOT stale after removing y.go; should be stale")
1055}
1056
1057func TestWildcardMatchesSyntaxErrorDirs(t *testing.T) {
1058	tg := testgo(t)
1059	defer tg.cleanup()
1060	// TODO: tg.parallel()
1061	tg.tempFile("src/mypkg/x.go", `package mypkg`)
1062	tg.tempFile("src/mypkg/y.go", `pkg mypackage`)
1063	tg.setenv("GOPATH", tg.path("."))
1064	tg.cd(tg.path("src/mypkg"))
1065	tg.runFail("list", "./...")
1066	tg.runFail("build", "./...")
1067	tg.runFail("install", "./...")
1068}
1069
1070func TestGoListWithTags(t *testing.T) {
1071	tg := testgo(t)
1072	defer tg.cleanup()
1073	tg.tempFile("src/mypkg/x.go", "// +build thetag\n\npackage mypkg\n")
1074	tg.setenv("GOPATH", tg.path("."))
1075	tg.cd(tg.path("./src"))
1076	tg.run("list", "-tags=thetag", "./my...")
1077	tg.grepStdout("mypkg", "did not find mypkg")
1078}
1079
1080func TestGoInstallErrorOnCrossCompileToBin(t *testing.T) {
1081	if testing.Short() {
1082		t.Skip("don't install into GOROOT in short mode")
1083	}
1084
1085	tg := testgo(t)
1086	defer tg.cleanup()
1087	tg.tempFile("src/mycmd/x.go", `package main
1088		func main() {}`)
1089	tg.setenv("GOPATH", tg.path("."))
1090	tg.cd(tg.path("src/mycmd"))
1091
1092	tg.run("build", "mycmd")
1093
1094	goarch := "386"
1095	if runtime.GOARCH == "386" {
1096		goarch = "amd64"
1097	}
1098	tg.setenv("GOOS", "linux")
1099	tg.setenv("GOARCH", goarch)
1100	tg.run("install", "mycmd")
1101	tg.setenv("GOBIN", tg.path("."))
1102	tg.runFail("install", "mycmd")
1103	tg.run("install", "cmd/pack")
1104}
1105
1106func TestGoInstallDetectsRemovedFilesInPackageMain(t *testing.T) {
1107	skipIfGccgo(t, "gccgo does not yet support package build IDs")
1108	tooSlow(t)
1109	tg := testgo(t)
1110	defer tg.cleanup()
1111	tg.parallel()
1112	tg.tempFile("src/mycmd/x.go", `package main
1113		func main() {}`)
1114	tg.tempFile("src/mycmd/y.go", `package main`)
1115	tg.tempFile("src/mycmd/z.go", `// +build missingtag
1116
1117		package main`)
1118	tg.setenv("GOPATH", tg.path("."))
1119	tg.run("install", "mycmd")
1120	tg.wantNotStale("mycmd", "", "./testgo list mypkg claims mycmd is stale, incorrectly")
1121	// z.go was not part of the build; removing it is okay.
1122	tg.must(os.Remove(tg.path("src/mycmd/z.go")))
1123	tg.wantNotStale("mycmd", "", "./testgo list mycmd claims mycmd is stale after removing z.go; should not be stale")
1124	// y.go was part of the package; removing it should be detected.
1125	tg.must(os.Remove(tg.path("src/mycmd/y.go")))
1126	tg.wantStale("mycmd", "build ID mismatch", "./testgo list mycmd claims mycmd is NOT stale after removing y.go; should be stale")
1127}
1128
1129func testLocalRun(tg *testgoData, exepath, local, match string) {
1130	tg.t.Helper()
1131	out, err := exec.Command(exepath).Output()
1132	if err != nil {
1133		tg.t.Fatalf("error running %v: %v", exepath, err)
1134	}
1135	if !regexp.MustCompile(match).Match(out) {
1136		tg.t.Log(string(out))
1137		tg.t.Errorf("testdata/%s/easy.go did not generate expected output", local)
1138	}
1139}
1140
1141func testLocalEasy(tg *testgoData, local string) {
1142	tg.t.Helper()
1143	exepath := "./easy" + exeSuffix
1144	tg.creatingTemp(exepath)
1145	tg.run("build", "-o", exepath, filepath.Join("testdata", local, "easy.go"))
1146	testLocalRun(tg, exepath, local, `(?m)^easysub\.Hello`)
1147}
1148
1149func testLocalEasySub(tg *testgoData, local string) {
1150	tg.t.Helper()
1151	exepath := "./easysub" + exeSuffix
1152	tg.creatingTemp(exepath)
1153	tg.run("build", "-o", exepath, filepath.Join("testdata", local, "easysub", "main.go"))
1154	testLocalRun(tg, exepath, local, `(?m)^easysub\.Hello`)
1155}
1156
1157func testLocalHard(tg *testgoData, local string) {
1158	tg.t.Helper()
1159	exepath := "./hard" + exeSuffix
1160	tg.creatingTemp(exepath)
1161	tg.run("build", "-o", exepath, filepath.Join("testdata", local, "hard.go"))
1162	testLocalRun(tg, exepath, local, `(?m)^sub\.Hello`)
1163}
1164
1165func testLocalInstall(tg *testgoData, local string) {
1166	tg.t.Helper()
1167	tg.runFail("install", filepath.Join("testdata", local, "easy.go"))
1168}
1169
1170func TestLocalImportsEasy(t *testing.T) {
1171	tg := testgo(t)
1172	defer tg.cleanup()
1173	testLocalEasy(tg, "local")
1174}
1175
1176func TestLocalImportsEasySub(t *testing.T) {
1177	tg := testgo(t)
1178	defer tg.cleanup()
1179	testLocalEasySub(tg, "local")
1180}
1181
1182func TestLocalImportsHard(t *testing.T) {
1183	tg := testgo(t)
1184	defer tg.cleanup()
1185	testLocalHard(tg, "local")
1186}
1187
1188func TestLocalImportsGoInstallShouldFail(t *testing.T) {
1189	tg := testgo(t)
1190	defer tg.cleanup()
1191	testLocalInstall(tg, "local")
1192}
1193
1194const badDirName = `#$%:, &()*;<=>?\^{}`
1195
1196func copyBad(tg *testgoData) {
1197	tg.t.Helper()
1198	if runtime.GOOS == "windows" {
1199		tg.t.Skipf("skipping test because %q is an invalid directory name", badDirName)
1200	}
1201
1202	tg.must(filepath.Walk("testdata/local",
1203		func(path string, info os.FileInfo, err error) error {
1204			if err != nil {
1205				return err
1206			}
1207			if info.IsDir() {
1208				return nil
1209			}
1210			var data []byte
1211			data, err = ioutil.ReadFile(path)
1212			if err != nil {
1213				return err
1214			}
1215			newpath := strings.Replace(path, "local", badDirName, 1)
1216			tg.tempFile(newpath, string(data))
1217			return nil
1218		}))
1219	tg.cd(tg.path("."))
1220}
1221
1222func TestBadImportsEasy(t *testing.T) {
1223	tg := testgo(t)
1224	defer tg.cleanup()
1225	// TODO: tg.parallel()
1226	copyBad(tg)
1227	testLocalEasy(tg, badDirName)
1228}
1229
1230func TestBadImportsEasySub(t *testing.T) {
1231	tg := testgo(t)
1232	defer tg.cleanup()
1233	copyBad(tg)
1234	testLocalEasySub(tg, badDirName)
1235}
1236
1237func TestBadImportsHard(t *testing.T) {
1238	tg := testgo(t)
1239	defer tg.cleanup()
1240	copyBad(tg)
1241	testLocalHard(tg, badDirName)
1242}
1243
1244func TestBadImportsGoInstallShouldFail(t *testing.T) {
1245	tg := testgo(t)
1246	defer tg.cleanup()
1247	copyBad(tg)
1248	testLocalInstall(tg, badDirName)
1249}
1250
1251func TestInternalPackagesInGOROOTAreRespected(t *testing.T) {
1252	skipIfGccgo(t, "gccgo does not have GOROOT")
1253	tg := testgo(t)
1254	defer tg.cleanup()
1255	tg.runFail("build", "-v", "./testdata/testinternal")
1256	tg.grepBoth(`testinternal(\/|\\)p\.go\:3\:8\: use of internal package not allowed`, "wrong error message for testdata/testinternal")
1257}
1258
1259func TestInternalPackagesOutsideGOROOTAreRespected(t *testing.T) {
1260	tg := testgo(t)
1261	defer tg.cleanup()
1262	tg.runFail("build", "-v", "./testdata/testinternal2")
1263	tg.grepBoth(`testinternal2(\/|\\)p\.go\:3\:8\: use of internal package not allowed`, "wrote error message for testdata/testinternal2")
1264}
1265
1266func TestRunInternal(t *testing.T) {
1267	tg := testgo(t)
1268	defer tg.cleanup()
1269	dir := filepath.Join(tg.pwd(), "testdata")
1270	tg.setenv("GOPATH", dir)
1271	tg.run("run", filepath.Join(dir, "src/run/good.go"))
1272	tg.runFail("run", filepath.Join(dir, "src/run/bad.go"))
1273	tg.grepStderr(`testdata(\/|\\)src(\/|\\)run(\/|\\)bad\.go\:3\:8\: use of internal package not allowed`, "unexpected error for run/bad.go")
1274}
1275
1276func testMove(t *testing.T, vcs, url, base, config string) {
1277	testenv.MustHaveExternalNetwork(t)
1278
1279	tg := testgo(t)
1280	defer tg.cleanup()
1281	tg.parallel()
1282	tg.tempDir("src")
1283	tg.setenv("GOPATH", tg.path("."))
1284	tg.run("get", "-d", url)
1285	tg.run("get", "-d", "-u", url)
1286	switch vcs {
1287	case "svn":
1288		// SVN doesn't believe in text files so we can't just edit the config.
1289		// Check out a different repo into the wrong place.
1290		tg.must(os.RemoveAll(tg.path("src/code.google.com/p/rsc-svn")))
1291		tg.run("get", "-d", "-u", "code.google.com/p/rsc-svn2/trunk")
1292		tg.must(os.Rename(tg.path("src/code.google.com/p/rsc-svn2"), tg.path("src/code.google.com/p/rsc-svn")))
1293	default:
1294		path := tg.path(filepath.Join("src", config))
1295		data, err := ioutil.ReadFile(path)
1296		tg.must(err)
1297		data = bytes.Replace(data, []byte(base), []byte(base+"XXX"), -1)
1298		tg.must(ioutil.WriteFile(path, data, 0644))
1299	}
1300	if vcs == "git" {
1301		// git will ask for a username and password when we
1302		// run go get -d -f -u. An empty username and
1303		// password will work. Prevent asking by setting
1304		// GIT_ASKPASS.
1305		tg.creatingTemp("sink" + exeSuffix)
1306		tg.tempFile("src/sink/sink.go", `package main; func main() {}`)
1307		tg.run("build", "-o", "sink"+exeSuffix, "sink")
1308		tg.setenv("GIT_ASKPASS", filepath.Join(tg.pwd(), "sink"+exeSuffix))
1309	}
1310	tg.runFail("get", "-d", "-u", url)
1311	tg.grepStderr("is a custom import path for", "go get -d -u "+url+" failed for wrong reason")
1312	tg.runFail("get", "-d", "-f", "-u", url)
1313	tg.grepStderr("validating server certificate|[nN]ot [fF]ound", "go get -d -f -u "+url+" failed for wrong reason")
1314}
1315
1316func TestInternalPackageErrorsAreHandled(t *testing.T) {
1317	tg := testgo(t)
1318	defer tg.cleanup()
1319	tg.run("list", "./testdata/testinternal3")
1320}
1321
1322func TestInternalCache(t *testing.T) {
1323	tg := testgo(t)
1324	defer tg.cleanup()
1325	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/testinternal4"))
1326	tg.runFail("build", "p")
1327	tg.grepStderr("internal", "did not fail to build p")
1328}
1329
1330func TestMoveGit(t *testing.T) {
1331	testMove(t, "git", "rsc.io/pdf", "pdf", "rsc.io/pdf/.git/config")
1332}
1333
1334func TestMoveHG(t *testing.T) {
1335	testMove(t, "hg", "vcs-test.golang.org/go/custom-hg-hello", "custom-hg-hello", "vcs-test.golang.org/go/custom-hg-hello/.hg/hgrc")
1336}
1337
1338// TODO(rsc): Set up a test case on SourceForge (?) for svn.
1339// func testMoveSVN(t *testing.T) {
1340//	testMove(t, "svn", "code.google.com/p/rsc-svn/trunk", "-", "-")
1341// }
1342
1343func TestImportCommandMatch(t *testing.T) {
1344	tg := testgo(t)
1345	defer tg.cleanup()
1346	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/importcom"))
1347	tg.run("build", "./testdata/importcom/works.go")
1348}
1349
1350func TestImportCommentMismatch(t *testing.T) {
1351	tg := testgo(t)
1352	defer tg.cleanup()
1353	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/importcom"))
1354	tg.runFail("build", "./testdata/importcom/wrongplace.go")
1355	tg.grepStderr(`wrongplace expects import "my/x"`, "go build did not mention incorrect import")
1356}
1357
1358func TestImportCommentSyntaxError(t *testing.T) {
1359	tg := testgo(t)
1360	defer tg.cleanup()
1361	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/importcom"))
1362	tg.runFail("build", "./testdata/importcom/bad.go")
1363	tg.grepStderr("cannot parse import comment", "go build did not mention syntax error")
1364}
1365
1366func TestImportCommentConflict(t *testing.T) {
1367	tg := testgo(t)
1368	defer tg.cleanup()
1369	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/importcom"))
1370	tg.runFail("build", "./testdata/importcom/conflict.go")
1371	tg.grepStderr("found import comments", "go build did not mention comment conflict")
1372}
1373
1374// cmd/go: custom import path checking should not apply to Go packages without import comment.
1375func TestIssue10952(t *testing.T) {
1376	testenv.MustHaveExternalNetwork(t)
1377	if _, err := exec.LookPath("git"); err != nil {
1378		t.Skip("skipping because git binary not found")
1379	}
1380
1381	tg := testgo(t)
1382	defer tg.cleanup()
1383	tg.parallel()
1384	tg.tempDir("src")
1385	tg.setenv("GOPATH", tg.path("."))
1386	const importPath = "github.com/zombiezen/go-get-issue-10952"
1387	tg.run("get", "-d", "-u", importPath)
1388	repoDir := tg.path("src/" + importPath)
1389	tg.runGit(repoDir, "remote", "set-url", "origin", "https://"+importPath+".git")
1390	tg.run("get", "-d", "-u", importPath)
1391}
1392
1393func TestIssue16471(t *testing.T) {
1394	testenv.MustHaveExternalNetwork(t)
1395	if _, err := exec.LookPath("git"); err != nil {
1396		t.Skip("skipping because git binary not found")
1397	}
1398
1399	tg := testgo(t)
1400	defer tg.cleanup()
1401	tg.parallel()
1402	tg.tempDir("src")
1403	tg.setenv("GOPATH", tg.path("."))
1404	tg.must(os.MkdirAll(tg.path("src/rsc.io/go-get-issue-10952"), 0755))
1405	tg.runGit(tg.path("src/rsc.io"), "clone", "https://github.com/zombiezen/go-get-issue-10952")
1406	tg.runFail("get", "-u", "rsc.io/go-get-issue-10952")
1407	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")
1408}
1409
1410// Test git clone URL that uses SCP-like syntax and custom import path checking.
1411func TestIssue11457(t *testing.T) {
1412	testenv.MustHaveExternalNetwork(t)
1413	if _, err := exec.LookPath("git"); err != nil {
1414		t.Skip("skipping because git binary not found")
1415	}
1416
1417	tg := testgo(t)
1418	defer tg.cleanup()
1419	tg.parallel()
1420	tg.tempDir("src")
1421	tg.setenv("GOPATH", tg.path("."))
1422	const importPath = "rsc.io/go-get-issue-11457"
1423	tg.run("get", "-d", "-u", importPath)
1424	repoDir := tg.path("src/" + importPath)
1425	tg.runGit(repoDir, "remote", "set-url", "origin", "git@github.com:rsc/go-get-issue-11457")
1426
1427	// At this time, custom import path checking compares remotes verbatim (rather than
1428	// just the host and path, skipping scheme and user), so we expect go get -u to fail.
1429	// However, the goal of this test is to verify that gitRemoteRepo correctly parsed
1430	// the SCP-like syntax, and we expect it to appear in the error message.
1431	tg.runFail("get", "-d", "-u", importPath)
1432	want := " is checked out from ssh://git@github.com/rsc/go-get-issue-11457"
1433	if !strings.HasSuffix(strings.TrimSpace(tg.getStderr()), want) {
1434		t.Error("expected clone URL to appear in stderr")
1435	}
1436}
1437
1438func TestGetGitDefaultBranch(t *testing.T) {
1439	testenv.MustHaveExternalNetwork(t)
1440	if _, err := exec.LookPath("git"); err != nil {
1441		t.Skip("skipping because git binary not found")
1442	}
1443
1444	tg := testgo(t)
1445	defer tg.cleanup()
1446	tg.parallel()
1447	tg.tempDir("src")
1448	tg.setenv("GOPATH", tg.path("."))
1449
1450	// This repo has two branches, master and another-branch.
1451	// The another-branch is the default that you get from 'git clone'.
1452	// The go get command variants should not override this.
1453	const importPath = "github.com/rsc/go-get-default-branch"
1454
1455	tg.run("get", "-d", importPath)
1456	repoDir := tg.path("src/" + importPath)
1457	tg.runGit(repoDir, "branch", "--contains", "HEAD")
1458	tg.grepStdout(`\* another-branch`, "not on correct default branch")
1459
1460	tg.run("get", "-d", "-u", importPath)
1461	tg.runGit(repoDir, "branch", "--contains", "HEAD")
1462	tg.grepStdout(`\* another-branch`, "not on correct default branch")
1463}
1464
1465func TestAccidentalGitCheckout(t *testing.T) {
1466	testenv.MustHaveExternalNetwork(t)
1467	if _, err := exec.LookPath("git"); err != nil {
1468		t.Skip("skipping because git binary not found")
1469	}
1470
1471	tg := testgo(t)
1472	defer tg.cleanup()
1473	tg.parallel()
1474	tg.tempDir("src")
1475	tg.setenv("GOPATH", tg.path("."))
1476
1477	tg.runFail("get", "-u", "vcs-test.golang.org/go/test1-svn-git")
1478	tg.grepStderr("src[\\\\/]vcs-test.* uses git, but parent .*src[\\\\/]vcs-test.* uses svn", "get did not fail for right reason")
1479
1480	tg.runFail("get", "-u", "vcs-test.golang.org/go/test2-svn-git/test2main")
1481	tg.grepStderr("src[\\\\/]vcs-test.* uses git, but parent .*src[\\\\/]vcs-test.* uses svn", "get did not fail for right reason")
1482}
1483
1484func TestErrorMessageForSyntaxErrorInTestGoFileSaysFAIL(t *testing.T) {
1485	tg := testgo(t)
1486	defer tg.cleanup()
1487	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
1488	tg.runFail("test", "syntaxerror")
1489	tg.grepStderr("FAIL", "go test did not say FAIL")
1490}
1491
1492func TestWildcardsDoNotLookInUselessDirectories(t *testing.T) {
1493	tg := testgo(t)
1494	defer tg.cleanup()
1495	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
1496	tg.runFail("list", "...")
1497	tg.grepBoth("badpkg", "go list ... failure does not mention badpkg")
1498	tg.run("list", "m...")
1499}
1500
1501func TestRelativeImportsGoTest(t *testing.T) {
1502	tg := testgo(t)
1503	defer tg.cleanup()
1504	tg.run("test", "./testdata/testimport")
1505}
1506
1507func TestRelativeImportsGoTestDashI(t *testing.T) {
1508	tg := testgo(t)
1509	defer tg.cleanup()
1510
1511	// don't let test -i overwrite runtime
1512	tg.wantNotStale("runtime", "", "must be non-stale before test -i")
1513
1514	tg.run("test", "-i", "./testdata/testimport")
1515}
1516
1517func TestRelativeImportsInCommandLinePackage(t *testing.T) {
1518	tg := testgo(t)
1519	defer tg.cleanup()
1520	// TODO: tg.parallel()
1521	files, err := filepath.Glob("./testdata/testimport/*.go")
1522	tg.must(err)
1523	tg.run(append([]string{"test"}, files...)...)
1524}
1525
1526func TestNonCanonicalImportPaths(t *testing.T) {
1527	tg := testgo(t)
1528	defer tg.cleanup()
1529	tg.parallel()
1530	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
1531	tg.runFail("build", "canonical/d")
1532	tg.grepStderr("package canonical/d", "did not report canonical/d")
1533	tg.grepStderr("imports canonical/b", "did not report canonical/b")
1534	tg.grepStderr("imports canonical/a/: non-canonical", "did not report canonical/a/")
1535}
1536
1537func TestVersionControlErrorMessageIncludesCorrectDirectory(t *testing.T) {
1538	tg := testgo(t)
1539	defer tg.cleanup()
1540	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/shadow/root1"))
1541	tg.runFail("get", "-u", "foo")
1542
1543	// TODO(iant): We should not have to use strconv.Quote here.
1544	// The code in vcs.go should be changed so that it is not required.
1545	quoted := strconv.Quote(filepath.Join("testdata", "shadow", "root1", "src", "foo"))
1546	quoted = quoted[1 : len(quoted)-1]
1547
1548	tg.grepStderr(regexp.QuoteMeta(quoted), "go get -u error does not mention shadow/root1/src/foo")
1549}
1550
1551func TestInstallFailsWithNoBuildableFiles(t *testing.T) {
1552	tg := testgo(t)
1553	defer tg.cleanup()
1554	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
1555	tg.setenv("CGO_ENABLED", "0")
1556	tg.runFail("install", "cgotest")
1557	tg.grepStderr("build constraints exclude all Go files", "go install cgotest did not report 'build constraints exclude all Go files'")
1558}
1559
1560// Issue 21895
1561func TestMSanAndRaceRequireCgo(t *testing.T) {
1562	if !canMSan && !canRace {
1563		t.Skip("skipping because both msan and the race detector are not supported")
1564	}
1565
1566	tg := testgo(t)
1567	defer tg.cleanup()
1568	tg.tempFile("triv.go", `package main; func main() {}`)
1569	tg.setenv("CGO_ENABLED", "0")
1570	if canRace {
1571		tg.runFail("install", "-race", "triv.go")
1572		tg.grepStderr("-race requires cgo", "did not correctly report that -race requires cgo")
1573		tg.grepStderrNot("-msan", "reported that -msan instead of -race requires cgo")
1574	}
1575	if canMSan {
1576		tg.runFail("install", "-msan", "triv.go")
1577		tg.grepStderr("-msan requires cgo", "did not correctly report that -msan requires cgo")
1578		tg.grepStderrNot("-race", "reported that -race instead of -msan requires cgo")
1579	}
1580}
1581
1582func TestRelativeGOBINFail(t *testing.T) {
1583	tg := testgo(t)
1584	defer tg.cleanup()
1585	tg.tempFile("triv.go", `package main; func main() {}`)
1586	tg.setenv("GOBIN", ".")
1587	tg.runFail("install")
1588	tg.grepStderr("cannot install, GOBIN must be an absolute path", "go install must fail if $GOBIN is a relative path")
1589}
1590
1591// Test that without $GOBIN set, binaries get installed
1592// into the GOPATH bin directory.
1593func TestInstallIntoGOPATH(t *testing.T) {
1594	tg := testgo(t)
1595	defer tg.cleanup()
1596	tg.creatingTemp("testdata/bin/go-cmd-test" + exeSuffix)
1597	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
1598	tg.run("install", "go-cmd-test")
1599	tg.wantExecutable("testdata/bin/go-cmd-test"+exeSuffix, "go install go-cmd-test did not write to testdata/bin/go-cmd-test")
1600}
1601
1602// Issue 12407
1603func TestBuildOutputToDevNull(t *testing.T) {
1604	tg := testgo(t)
1605	defer tg.cleanup()
1606	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
1607	tg.run("build", "-o", os.DevNull, "go-cmd-test")
1608}
1609
1610func TestPackageMainTestImportsArchiveNotBinary(t *testing.T) {
1611	tooSlow(t)
1612	tg := testgo(t)
1613	defer tg.cleanup()
1614	tg.parallel()
1615	gobin := filepath.Join(tg.pwd(), "testdata", "bin")
1616	tg.creatingTemp(gobin)
1617	tg.setenv("GOBIN", gobin)
1618	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
1619	tg.must(os.Chtimes("./testdata/src/main_test/m.go", time.Now(), time.Now()))
1620	tg.sleep()
1621	tg.run("test", "main_test")
1622	tg.run("install", "main_test")
1623	tg.wantNotStale("main_test", "", "after go install, main listed as stale")
1624	tg.run("test", "main_test")
1625}
1626
1627func TestPackageMainTestCompilerFlags(t *testing.T) {
1628	tg := testgo(t)
1629	defer tg.cleanup()
1630	tg.parallel()
1631	tg.makeTempdir()
1632	tg.setenv("GOPATH", tg.path("."))
1633	tg.tempFile("src/p1/p1.go", "package main\n")
1634	tg.tempFile("src/p1/p1_test.go", "package main\nimport \"testing\"\nfunc Test(t *testing.T){}\n")
1635	tg.run("test", "-c", "-n", "p1")
1636	tg.grepBothNot(`([\\/]compile|gccgo).* (-p main|-fgo-pkgpath=main).*p1\.go`, "should not have run compile -p main p1.go")
1637	tg.grepStderr(`([\\/]compile|gccgo).* (-p p1|-fgo-pkgpath=p1).*p1\.go`, "should have run compile -p p1 p1.go")
1638}
1639
1640// The runtime version string takes one of two forms:
1641// "go1.X[.Y]" for Go releases, and "devel +hash" at tip.
1642// Determine whether we are in a released copy by
1643// inspecting the version.
1644var isGoRelease = strings.HasPrefix(runtime.Version(), "go1")
1645
1646// Issue 12690
1647func TestPackageNotStaleWithTrailingSlash(t *testing.T) {
1648	skipIfGccgo(t, "gccgo does not have GOROOT")
1649	tg := testgo(t)
1650	defer tg.cleanup()
1651
1652	// Make sure the packages below are not stale.
1653	tg.wantNotStale("runtime", "", "must be non-stale before test runs")
1654	tg.wantNotStale("os", "", "must be non-stale before test runs")
1655	tg.wantNotStale("io", "", "must be non-stale before test runs")
1656
1657	goroot := runtime.GOROOT()
1658	tg.setenv("GOROOT", goroot+"/")
1659
1660	tg.wantNotStale("runtime", "", "with trailing slash in GOROOT, runtime listed as stale")
1661	tg.wantNotStale("os", "", "with trailing slash in GOROOT, os listed as stale")
1662	tg.wantNotStale("io", "", "with trailing slash in GOROOT, io listed as stale")
1663}
1664
1665// With $GOBIN set, binaries get installed to $GOBIN.
1666func TestInstallIntoGOBIN(t *testing.T) {
1667	tg := testgo(t)
1668	defer tg.cleanup()
1669	gobin := filepath.Join(tg.pwd(), "testdata", "bin1")
1670	tg.creatingTemp(gobin)
1671	tg.setenv("GOBIN", gobin)
1672	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
1673	tg.run("install", "go-cmd-test")
1674	tg.wantExecutable("testdata/bin1/go-cmd-test"+exeSuffix, "go install go-cmd-test did not write to testdata/bin1/go-cmd-test")
1675}
1676
1677// Issue 11065
1678func TestInstallToCurrentDirectoryCreatesExecutable(t *testing.T) {
1679	tg := testgo(t)
1680	defer tg.cleanup()
1681	pkg := filepath.Join(tg.pwd(), "testdata", "src", "go-cmd-test")
1682	tg.creatingTemp(filepath.Join(pkg, "go-cmd-test"+exeSuffix))
1683	tg.setenv("GOBIN", pkg)
1684	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
1685	tg.cd(pkg)
1686	tg.run("install")
1687	tg.wantExecutable("go-cmd-test"+exeSuffix, "go install did not write to current directory")
1688}
1689
1690// Without $GOBIN set, installing a program outside $GOPATH should fail
1691// (there is nowhere to install it).
1692func TestInstallWithoutDestinationFails(t *testing.T) {
1693	tg := testgo(t)
1694	defer tg.cleanup()
1695	tg.runFail("install", "testdata/src/go-cmd-test/helloworld.go")
1696	tg.grepStderr("no install location for .go files listed on command line", "wrong error")
1697}
1698
1699// With $GOBIN set, should install there.
1700func TestInstallToGOBINCommandLinePackage(t *testing.T) {
1701	tg := testgo(t)
1702	defer tg.cleanup()
1703	gobin := filepath.Join(tg.pwd(), "testdata", "bin1")
1704	tg.creatingTemp(gobin)
1705	tg.setenv("GOBIN", gobin)
1706	tg.run("install", "testdata/src/go-cmd-test/helloworld.go")
1707	tg.wantExecutable("testdata/bin1/helloworld"+exeSuffix, "go install testdata/src/go-cmd-test/helloworld.go did not write testdata/bin1/helloworld")
1708}
1709
1710func TestGoGetNonPkg(t *testing.T) {
1711	testenv.MustHaveExternalNetwork(t)
1712
1713	tg := testgo(t)
1714	defer tg.cleanup()
1715	tg.tempDir("gobin")
1716	tg.setenv("GOPATH", tg.path("."))
1717	tg.setenv("GOBIN", tg.path("gobin"))
1718	tg.runFail("get", "-d", "golang.org/x/tools")
1719	tg.grepStderr("golang.org/x/tools: no Go files", "missing error")
1720	tg.runFail("get", "-d", "-u", "golang.org/x/tools")
1721	tg.grepStderr("golang.org/x/tools: no Go files", "missing error")
1722	tg.runFail("get", "-d", "golang.org/x/tools")
1723	tg.grepStderr("golang.org/x/tools: no Go files", "missing error")
1724}
1725
1726func TestGoGetTestOnlyPkg(t *testing.T) {
1727	testenv.MustHaveExternalNetwork(t)
1728
1729	tg := testgo(t)
1730	defer tg.cleanup()
1731	tg.tempDir("gopath")
1732	tg.setenv("GOPATH", tg.path("gopath"))
1733	tg.run("get", "golang.org/x/tour/content")
1734	tg.run("get", "-t", "golang.org/x/tour/content")
1735}
1736
1737func TestInstalls(t *testing.T) {
1738	if testing.Short() {
1739		t.Skip("don't install into GOROOT in short mode")
1740	}
1741
1742	tg := testgo(t)
1743	defer tg.cleanup()
1744	tg.parallel()
1745	tg.tempDir("gobin")
1746	tg.setenv("GOPATH", tg.path("."))
1747	goroot := runtime.GOROOT()
1748	tg.setenv("GOROOT", goroot)
1749
1750	// cmd/fix installs into tool
1751	tg.run("env", "GOOS")
1752	goos := strings.TrimSpace(tg.getStdout())
1753	tg.setenv("GOOS", goos)
1754	tg.run("env", "GOARCH")
1755	goarch := strings.TrimSpace(tg.getStdout())
1756	tg.setenv("GOARCH", goarch)
1757	fixbin := filepath.Join(goroot, "pkg", "tool", goos+"_"+goarch, "fix") + exeSuffix
1758	tg.must(os.RemoveAll(fixbin))
1759	tg.run("install", "cmd/fix")
1760	tg.wantExecutable(fixbin, "did not install cmd/fix to $GOROOT/pkg/tool")
1761	tg.must(os.Remove(fixbin))
1762	tg.setenv("GOBIN", tg.path("gobin"))
1763	tg.run("install", "cmd/fix")
1764	tg.wantExecutable(fixbin, "did not install cmd/fix to $GOROOT/pkg/tool with $GOBIN set")
1765	tg.unsetenv("GOBIN")
1766
1767	// gopath program installs into GOBIN
1768	tg.tempFile("src/progname/p.go", `package main; func main() {}`)
1769	tg.setenv("GOBIN", tg.path("gobin"))
1770	tg.run("install", "progname")
1771	tg.unsetenv("GOBIN")
1772	tg.wantExecutable(tg.path("gobin/progname")+exeSuffix, "did not install progname to $GOBIN/progname")
1773
1774	// gopath program installs into GOPATH/bin
1775	tg.run("install", "progname")
1776	tg.wantExecutable(tg.path("bin/progname")+exeSuffix, "did not install progname to $GOPATH/bin/progname")
1777}
1778
1779func TestRejectRelativeDotPathInGOPATHCommandLinePackage(t *testing.T) {
1780	tg := testgo(t)
1781	defer tg.cleanup()
1782	tg.setenv("GOPATH", ".")
1783	tg.runFail("build", "testdata/src/go-cmd-test/helloworld.go")
1784	tg.grepStderr("GOPATH entry is relative", "expected an error message rejecting relative GOPATH entries")
1785}
1786
1787func TestRejectRelativePathsInGOPATH(t *testing.T) {
1788	tg := testgo(t)
1789	defer tg.cleanup()
1790	sep := string(filepath.ListSeparator)
1791	tg.setenv("GOPATH", sep+filepath.Join(tg.pwd(), "testdata")+sep+".")
1792	tg.runFail("build", "go-cmd-test")
1793	tg.grepStderr("GOPATH entry is relative", "expected an error message rejecting relative GOPATH entries")
1794}
1795
1796func TestRejectRelativePathsInGOPATHCommandLinePackage(t *testing.T) {
1797	tg := testgo(t)
1798	defer tg.cleanup()
1799	tg.setenv("GOPATH", "testdata")
1800	tg.runFail("build", "testdata/src/go-cmd-test/helloworld.go")
1801	tg.grepStderr("GOPATH entry is relative", "expected an error message rejecting relative GOPATH entries")
1802}
1803
1804// Issue 21928.
1805func TestRejectBlankPathsInGOPATH(t *testing.T) {
1806	tg := testgo(t)
1807	defer tg.cleanup()
1808	sep := string(filepath.ListSeparator)
1809	tg.setenv("GOPATH", " "+sep+filepath.Join(tg.pwd(), "testdata"))
1810	tg.runFail("build", "go-cmd-test")
1811	tg.grepStderr("GOPATH entry is relative", "expected an error message rejecting relative GOPATH entries")
1812}
1813
1814// Issue 21928.
1815func TestIgnoreEmptyPathsInGOPATH(t *testing.T) {
1816	tg := testgo(t)
1817	defer tg.cleanup()
1818	tg.creatingTemp("testdata/bin/go-cmd-test" + exeSuffix)
1819	sep := string(filepath.ListSeparator)
1820	tg.setenv("GOPATH", ""+sep+filepath.Join(tg.pwd(), "testdata"))
1821	tg.run("install", "go-cmd-test")
1822	tg.wantExecutable("testdata/bin/go-cmd-test"+exeSuffix, "go install go-cmd-test did not write to testdata/bin/go-cmd-test")
1823}
1824
1825// Issue 4104.
1826func TestGoTestWithPackageListedMultipleTimes(t *testing.T) {
1827	tooSlow(t)
1828	tg := testgo(t)
1829	defer tg.cleanup()
1830	tg.parallel()
1831	tg.run("test", "errors", "errors", "errors", "errors", "errors")
1832	if strings.Contains(strings.TrimSpace(tg.getStdout()), "\n") {
1833		t.Error("go test errors errors errors errors errors tested the same package multiple times")
1834	}
1835}
1836
1837func TestGoListHasAConsistentOrder(t *testing.T) {
1838	tooSlow(t)
1839	tg := testgo(t)
1840	defer tg.cleanup()
1841	tg.parallel()
1842	tg.run("list", "std")
1843	first := tg.getStdout()
1844	tg.run("list", "std")
1845	if first != tg.getStdout() {
1846		t.Error("go list std ordering is inconsistent")
1847	}
1848}
1849
1850func TestGoListStdDoesNotIncludeCommands(t *testing.T) {
1851	tooSlow(t)
1852	tg := testgo(t)
1853	defer tg.cleanup()
1854	tg.parallel()
1855	tg.run("list", "std")
1856	tg.grepStdoutNot("cmd/", "go list std shows commands")
1857}
1858
1859func TestGoListCmdOnlyShowsCommands(t *testing.T) {
1860	skipIfGccgo(t, "gccgo has no GOROOT")
1861	tooSlow(t)
1862	tg := testgo(t)
1863	defer tg.cleanup()
1864	tg.parallel()
1865	tg.run("list", "cmd")
1866	out := strings.TrimSpace(tg.getStdout())
1867	for _, line := range strings.Split(out, "\n") {
1868		if !strings.Contains(line, "cmd/") {
1869			t.Error("go list cmd shows non-commands")
1870			break
1871		}
1872	}
1873}
1874
1875func TestGoListDedupsPackages(t *testing.T) {
1876	tg := testgo(t)
1877	defer tg.cleanup()
1878	// TODO: tg.parallel()
1879	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
1880	tg.run("list", "xtestonly", "./testdata/src/xtestonly/...")
1881	got := strings.TrimSpace(tg.getStdout())
1882	const want = "xtestonly"
1883	if got != want {
1884		t.Errorf("got %q; want %q", got, want)
1885	}
1886}
1887
1888func TestGoListDeps(t *testing.T) {
1889	tg := testgo(t)
1890	defer tg.cleanup()
1891	tg.parallel()
1892	tg.tempDir("src/p1/p2/p3/p4")
1893	tg.setenv("GOPATH", tg.path("."))
1894	tg.tempFile("src/p1/p.go", "package p1\nimport _ \"p1/p2\"\n")
1895	tg.tempFile("src/p1/p2/p.go", "package p2\nimport _ \"p1/p2/p3\"\n")
1896	tg.tempFile("src/p1/p2/p3/p.go", "package p3\nimport _ \"p1/p2/p3/p4\"\n")
1897	tg.tempFile("src/p1/p2/p3/p4/p.go", "package p4\n")
1898	tg.run("list", "-f", "{{.Deps}}", "p1")
1899	tg.grepStdout("p1/p2/p3/p4", "Deps(p1) does not mention p4")
1900}
1901
1902// Issue 4096. Validate the output of unsuccessful go install foo/quxx.
1903func TestUnsuccessfulGoInstallShouldMentionMissingPackage(t *testing.T) {
1904	tg := testgo(t)
1905	defer tg.cleanup()
1906	tg.parallel()
1907	tg.runFail("install", "foo/quxx")
1908	if tg.grepCountBoth(`cannot find package "foo/quxx" in any of`) != 1 {
1909		t.Error(`go install foo/quxx expected error: .*cannot find package "foo/quxx" in any of`)
1910	}
1911}
1912
1913func TestGOROOTSearchFailureReporting(t *testing.T) {
1914	tg := testgo(t)
1915	defer tg.cleanup()
1916	tg.parallel()
1917	tg.runFail("install", "foo/quxx")
1918	if tg.grepCountBoth(regexp.QuoteMeta(filepath.Join("foo", "quxx"))+` \(from \$GOROOT\)$`) != 1 {
1919		t.Error(`go install foo/quxx expected error: .*foo/quxx (from $GOROOT)`)
1920	}
1921}
1922
1923func TestMultipleGOPATHEntriesReportedSeparately(t *testing.T) {
1924	tg := testgo(t)
1925	defer tg.cleanup()
1926	tg.parallel()
1927	sep := string(filepath.ListSeparator)
1928	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata", "a")+sep+filepath.Join(tg.pwd(), "testdata", "b"))
1929	tg.runFail("install", "foo/quxx")
1930	if tg.grepCountBoth(`testdata[/\\].[/\\]src[/\\]foo[/\\]quxx`) != 2 {
1931		t.Error(`go install foo/quxx expected error: .*testdata/a/src/foo/quxx (from $GOPATH)\n.*testdata/b/src/foo/quxx`)
1932	}
1933}
1934
1935// Test (from $GOPATH) annotation is reported for the first GOPATH entry,
1936func TestMentionGOPATHInFirstGOPATHEntry(t *testing.T) {
1937	tg := testgo(t)
1938	defer tg.cleanup()
1939	tg.parallel()
1940	sep := string(filepath.ListSeparator)
1941	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata", "a")+sep+filepath.Join(tg.pwd(), "testdata", "b"))
1942	tg.runFail("install", "foo/quxx")
1943	if tg.grepCountBoth(regexp.QuoteMeta(filepath.Join("testdata", "a", "src", "foo", "quxx"))+` \(from \$GOPATH\)$`) != 1 {
1944		t.Error(`go install foo/quxx expected error: .*testdata/a/src/foo/quxx (from $GOPATH)`)
1945	}
1946}
1947
1948// but not on the second.
1949func TestMentionGOPATHNotOnSecondEntry(t *testing.T) {
1950	tg := testgo(t)
1951	defer tg.cleanup()
1952	tg.parallel()
1953	sep := string(filepath.ListSeparator)
1954	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata", "a")+sep+filepath.Join(tg.pwd(), "testdata", "b"))
1955	tg.runFail("install", "foo/quxx")
1956	if tg.grepCountBoth(regexp.QuoteMeta(filepath.Join("testdata", "b", "src", "foo", "quxx"))+`$`) != 1 {
1957		t.Error(`go install foo/quxx expected error: .*testdata/b/src/foo/quxx`)
1958	}
1959}
1960
1961func homeEnvName() string {
1962	switch runtime.GOOS {
1963	case "windows":
1964		return "USERPROFILE"
1965	case "plan9":
1966		return "home"
1967	default:
1968		return "HOME"
1969	}
1970}
1971
1972func TestDefaultGOPATH(t *testing.T) {
1973	tg := testgo(t)
1974	defer tg.cleanup()
1975	tg.parallel()
1976	tg.tempDir("home/go")
1977	tg.setenv(homeEnvName(), tg.path("home"))
1978
1979	tg.run("env", "GOPATH")
1980	tg.grepStdout(regexp.QuoteMeta(tg.path("home/go")), "want GOPATH=$HOME/go")
1981
1982	tg.setenv("GOROOT", tg.path("home/go"))
1983	tg.run("env", "GOPATH")
1984	tg.grepStdoutNot(".", "want unset GOPATH because GOROOT=$HOME/go")
1985
1986	tg.setenv("GOROOT", tg.path("home/go")+"/")
1987	tg.run("env", "GOPATH")
1988	tg.grepStdoutNot(".", "want unset GOPATH because GOROOT=$HOME/go/")
1989}
1990
1991func TestDefaultGOPATHGet(t *testing.T) {
1992	testenv.MustHaveExternalNetwork(t)
1993
1994	tg := testgo(t)
1995	defer tg.cleanup()
1996	tg.setenv("GOPATH", "")
1997	tg.tempDir("home")
1998	tg.setenv(homeEnvName(), tg.path("home"))
1999
2000	// warn for creating directory
2001	tg.run("get", "-v", "github.com/golang/example/hello")
2002	tg.grepStderr("created GOPATH="+regexp.QuoteMeta(tg.path("home/go"))+"; see 'go help gopath'", "did not create GOPATH")
2003
2004	// no warning if directory already exists
2005	tg.must(os.RemoveAll(tg.path("home/go")))
2006	tg.tempDir("home/go")
2007	tg.run("get", "github.com/golang/example/hello")
2008	tg.grepStderrNot(".", "expected no output on standard error")
2009
2010	// error if $HOME/go is a file
2011	tg.must(os.RemoveAll(tg.path("home/go")))
2012	tg.tempFile("home/go", "")
2013	tg.runFail("get", "github.com/golang/example/hello")
2014	tg.grepStderr(`mkdir .*[/\\]go: .*(not a directory|cannot find the path)`, "expected error because $HOME/go is a file")
2015}
2016
2017func TestDefaultGOPATHPrintedSearchList(t *testing.T) {
2018	tg := testgo(t)
2019	defer tg.cleanup()
2020	tg.setenv("GOPATH", "")
2021	tg.tempDir("home")
2022	tg.setenv(homeEnvName(), tg.path("home"))
2023
2024	tg.runFail("install", "github.com/golang/example/hello")
2025	tg.grepStderr(regexp.QuoteMeta(tg.path("home/go/src/github.com/golang/example/hello"))+`.*from \$GOPATH`, "expected default GOPATH")
2026}
2027
2028// Issue 4186. go get cannot be used to download packages to $GOROOT.
2029// Test that without GOPATH set, go get should fail.
2030func TestGoGetIntoGOROOT(t *testing.T) {
2031	testenv.MustHaveExternalNetwork(t)
2032
2033	tg := testgo(t)
2034	defer tg.cleanup()
2035	tg.parallel()
2036	tg.tempDir("src")
2037
2038	// Fails because GOROOT=GOPATH
2039	tg.setenv("GOPATH", tg.path("."))
2040	tg.setenv("GOROOT", tg.path("."))
2041	tg.runFail("get", "-d", "github.com/golang/example/hello")
2042	tg.grepStderr("warning: GOPATH set to GOROOT", "go should detect GOPATH=GOROOT")
2043	tg.grepStderr(`\$GOPATH must not be set to \$GOROOT`, "go should detect GOPATH=GOROOT")
2044
2045	// Fails because GOROOT=GOPATH after cleaning.
2046	tg.setenv("GOPATH", tg.path(".")+"/")
2047	tg.setenv("GOROOT", tg.path("."))
2048	tg.runFail("get", "-d", "github.com/golang/example/hello")
2049	tg.grepStderr("warning: GOPATH set to GOROOT", "go should detect GOPATH=GOROOT")
2050	tg.grepStderr(`\$GOPATH must not be set to \$GOROOT`, "go should detect GOPATH=GOROOT")
2051
2052	tg.setenv("GOPATH", tg.path("."))
2053	tg.setenv("GOROOT", tg.path(".")+"/")
2054	tg.runFail("get", "-d", "github.com/golang/example/hello")
2055	tg.grepStderr("warning: GOPATH set to GOROOT", "go should detect GOPATH=GOROOT")
2056	tg.grepStderr(`\$GOPATH must not be set to \$GOROOT`, "go should detect GOPATH=GOROOT")
2057
2058	// Fails because GOROOT=$HOME/go so default GOPATH unset.
2059	tg.tempDir("home/go")
2060	tg.setenv(homeEnvName(), tg.path("home"))
2061	tg.setenv("GOPATH", "")
2062	tg.setenv("GOROOT", tg.path("home/go"))
2063	tg.runFail("get", "-d", "github.com/golang/example/hello")
2064	tg.grepStderr(`\$GOPATH not set`, "expected GOPATH not set")
2065
2066	tg.setenv(homeEnvName(), tg.path("home")+"/")
2067	tg.setenv("GOPATH", "")
2068	tg.setenv("GOROOT", tg.path("home/go"))
2069	tg.runFail("get", "-d", "github.com/golang/example/hello")
2070	tg.grepStderr(`\$GOPATH not set`, "expected GOPATH not set")
2071
2072	tg.setenv(homeEnvName(), tg.path("home"))
2073	tg.setenv("GOPATH", "")
2074	tg.setenv("GOROOT", tg.path("home/go")+"/")
2075	tg.runFail("get", "-d", "github.com/golang/example/hello")
2076	tg.grepStderr(`\$GOPATH not set`, "expected GOPATH not set")
2077}
2078
2079func TestLdflagsArgumentsWithSpacesIssue3941(t *testing.T) {
2080	skipIfGccgo(t, "gccgo does not support -ldflags -X")
2081	tooSlow(t)
2082	tg := testgo(t)
2083	defer tg.cleanup()
2084	tg.parallel()
2085	tg.tempFile("main.go", `package main
2086		var extern string
2087		func main() {
2088			println(extern)
2089		}`)
2090	tg.run("run", "-ldflags", `-X "main.extern=hello world"`, tg.path("main.go"))
2091	tg.grepStderr("^hello world", `ldflags -X "main.extern=hello world"' failed`)
2092}
2093
2094func TestGoTestCpuprofileLeavesBinaryBehind(t *testing.T) {
2095	skipIfGccgo(t, "gccgo has no standard packages")
2096	tooSlow(t)
2097	tg := testgo(t)
2098	defer tg.cleanup()
2099	// TODO: tg.parallel()
2100	tg.makeTempdir()
2101	tg.cd(tg.path("."))
2102	tg.run("test", "-cpuprofile", "errors.prof", "errors")
2103	tg.wantExecutable("errors.test"+exeSuffix, "go test -cpuprofile did not create errors.test")
2104}
2105
2106func TestGoTestCpuprofileDashOControlsBinaryLocation(t *testing.T) {
2107	skipIfGccgo(t, "gccgo has no standard packages")
2108	tooSlow(t)
2109	tg := testgo(t)
2110	defer tg.cleanup()
2111	// TODO: tg.parallel()
2112	tg.makeTempdir()
2113	tg.cd(tg.path("."))
2114	tg.run("test", "-cpuprofile", "errors.prof", "-o", "myerrors.test"+exeSuffix, "errors")
2115	tg.wantExecutable("myerrors.test"+exeSuffix, "go test -cpuprofile -o myerrors.test did not create myerrors.test")
2116}
2117
2118func TestGoTestMutexprofileLeavesBinaryBehind(t *testing.T) {
2119	skipIfGccgo(t, "gccgo has no standard packages")
2120	tooSlow(t)
2121	tg := testgo(t)
2122	defer tg.cleanup()
2123	// TODO: tg.parallel()
2124	tg.makeTempdir()
2125	tg.cd(tg.path("."))
2126	tg.run("test", "-mutexprofile", "errors.prof", "errors")
2127	tg.wantExecutable("errors.test"+exeSuffix, "go test -mutexprofile did not create errors.test")
2128}
2129
2130func TestGoTestMutexprofileDashOControlsBinaryLocation(t *testing.T) {
2131	skipIfGccgo(t, "gccgo has no standard packages")
2132	tooSlow(t)
2133	tg := testgo(t)
2134	defer tg.cleanup()
2135	// TODO: tg.parallel()
2136	tg.makeTempdir()
2137	tg.cd(tg.path("."))
2138	tg.run("test", "-mutexprofile", "errors.prof", "-o", "myerrors.test"+exeSuffix, "errors")
2139	tg.wantExecutable("myerrors.test"+exeSuffix, "go test -mutexprofile -o myerrors.test did not create myerrors.test")
2140}
2141
2142func TestGoBuildNonMain(t *testing.T) {
2143	tg := testgo(t)
2144	defer tg.cleanup()
2145	// TODO: tg.parallel()
2146	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
2147	tg.runFail("build", "-buildmode=exe", "-o", "not_main"+exeSuffix, "not_main")
2148	tg.grepStderr("-buildmode=exe requires exactly one main package", "go build with -o and -buildmode=exe should on a non-main package should throw an error")
2149	tg.mustNotExist("not_main" + exeSuffix)
2150}
2151
2152func TestGoTestDashCDashOControlsBinaryLocation(t *testing.T) {
2153	skipIfGccgo(t, "gccgo has no standard packages")
2154	tooSlow(t)
2155	tg := testgo(t)
2156	defer tg.cleanup()
2157	tg.parallel()
2158	tg.makeTempdir()
2159	tg.run("test", "-c", "-o", tg.path("myerrors.test"+exeSuffix), "errors")
2160	tg.wantExecutable(tg.path("myerrors.test"+exeSuffix), "go test -c -o myerrors.test did not create myerrors.test")
2161}
2162
2163func TestGoTestDashOWritesBinary(t *testing.T) {
2164	skipIfGccgo(t, "gccgo has no standard packages")
2165	tooSlow(t)
2166	tg := testgo(t)
2167	defer tg.cleanup()
2168	tg.parallel()
2169	tg.makeTempdir()
2170	tg.run("test", "-o", tg.path("myerrors.test"+exeSuffix), "errors")
2171	tg.wantExecutable(tg.path("myerrors.test"+exeSuffix), "go test -o myerrors.test did not create myerrors.test")
2172}
2173
2174func TestGoTestDashIDashOWritesBinary(t *testing.T) {
2175	skipIfGccgo(t, "gccgo has no standard packages")
2176	tooSlow(t)
2177	tg := testgo(t)
2178	defer tg.cleanup()
2179	tg.parallel()
2180	tg.makeTempdir()
2181
2182	// don't let test -i overwrite runtime
2183	tg.wantNotStale("runtime", "", "must be non-stale before test -i")
2184
2185	tg.run("test", "-v", "-i", "-o", tg.path("myerrors.test"+exeSuffix), "errors")
2186	tg.grepBothNot("PASS|FAIL", "test should not have run")
2187	tg.wantExecutable(tg.path("myerrors.test"+exeSuffix), "go test -o myerrors.test did not create myerrors.test")
2188}
2189
2190// Issue 4568.
2191func TestSymlinksList(t *testing.T) {
2192	testenv.MustHaveSymlink(t)
2193
2194	tg := testgo(t)
2195	defer tg.cleanup()
2196	// TODO: tg.parallel()
2197	tg.tempDir("src")
2198	tg.must(os.Symlink(tg.path("."), tg.path("src/dir1")))
2199	tg.tempFile("src/dir1/p.go", "package p")
2200	tg.setenv("GOPATH", tg.path("."))
2201	tg.cd(tg.path("src"))
2202	tg.run("list", "-f", "{{.Root}}", "dir1")
2203	if strings.TrimSpace(tg.getStdout()) != tg.path(".") {
2204		t.Error("confused by symlinks")
2205	}
2206}
2207
2208// Issue 14054.
2209func TestSymlinksVendor(t *testing.T) {
2210	testenv.MustHaveSymlink(t)
2211
2212	tg := testgo(t)
2213	defer tg.cleanup()
2214	// TODO: tg.parallel()
2215	tg.tempDir("gopath/src/dir1/vendor/v")
2216	tg.tempFile("gopath/src/dir1/p.go", "package main\nimport _ `v`\nfunc main(){}")
2217	tg.tempFile("gopath/src/dir1/vendor/v/v.go", "package v")
2218	tg.must(os.Symlink(tg.path("gopath/src/dir1"), tg.path("symdir1")))
2219	tg.setenv("GOPATH", tg.path("gopath"))
2220	tg.cd(tg.path("symdir1"))
2221	tg.run("list", "-f", "{{.Root}}", ".")
2222	if strings.TrimSpace(tg.getStdout()) != tg.path("gopath") {
2223		t.Error("list confused by symlinks")
2224	}
2225
2226	// All of these should succeed, not die in vendor-handling code.
2227	tg.run("run", "p.go")
2228	tg.run("build")
2229	tg.run("install")
2230}
2231
2232// Issue 15201.
2233func TestSymlinksVendor15201(t *testing.T) {
2234	testenv.MustHaveSymlink(t)
2235
2236	tg := testgo(t)
2237	defer tg.cleanup()
2238
2239	tg.tempDir("gopath/src/x/y/_vendor/src/x")
2240	tg.must(os.Symlink("../../..", tg.path("gopath/src/x/y/_vendor/src/x/y")))
2241	tg.tempFile("gopath/src/x/y/w/w.go", "package w\nimport \"x/y/z\"\n")
2242	tg.must(os.Symlink("../_vendor/src", tg.path("gopath/src/x/y/w/vendor")))
2243	tg.tempFile("gopath/src/x/y/z/z.go", "package z\n")
2244
2245	tg.setenv("GOPATH", tg.path("gopath/src/x/y/_vendor")+string(filepath.ListSeparator)+tg.path("gopath"))
2246	tg.cd(tg.path("gopath/src"))
2247	tg.run("list", "./...")
2248}
2249
2250func TestSymlinksInternal(t *testing.T) {
2251	testenv.MustHaveSymlink(t)
2252
2253	tg := testgo(t)
2254	defer tg.cleanup()
2255	tg.tempDir("gopath/src/dir1/internal/v")
2256	tg.tempFile("gopath/src/dir1/p.go", "package main\nimport _ `dir1/internal/v`\nfunc main(){}")
2257	tg.tempFile("gopath/src/dir1/internal/v/v.go", "package v")
2258	tg.must(os.Symlink(tg.path("gopath/src/dir1"), tg.path("symdir1")))
2259	tg.setenv("GOPATH", tg.path("gopath"))
2260	tg.cd(tg.path("symdir1"))
2261	tg.run("list", "-f", "{{.Root}}", ".")
2262	if strings.TrimSpace(tg.getStdout()) != tg.path("gopath") {
2263		t.Error("list confused by symlinks")
2264	}
2265
2266	// All of these should succeed, not die in internal-handling code.
2267	tg.run("run", "p.go")
2268	tg.run("build")
2269	tg.run("install")
2270}
2271
2272// Issue 4515.
2273func TestInstallWithTags(t *testing.T) {
2274	tooSlow(t)
2275	tg := testgo(t)
2276	defer tg.cleanup()
2277	tg.parallel()
2278	tg.tempDir("bin")
2279	tg.tempFile("src/example/a/main.go", `package main
2280		func main() {}`)
2281	tg.tempFile("src/example/b/main.go", `// +build mytag
2282
2283		package main
2284		func main() {}`)
2285	tg.setenv("GOPATH", tg.path("."))
2286	tg.run("install", "-tags", "mytag", "example/a", "example/b")
2287	tg.wantExecutable(tg.path("bin/a"+exeSuffix), "go install example/a example/b did not install binaries")
2288	tg.wantExecutable(tg.path("bin/b"+exeSuffix), "go install example/a example/b did not install binaries")
2289	tg.must(os.Remove(tg.path("bin/a" + exeSuffix)))
2290	tg.must(os.Remove(tg.path("bin/b" + exeSuffix)))
2291	tg.run("install", "-tags", "mytag", "example/...")
2292	tg.wantExecutable(tg.path("bin/a"+exeSuffix), "go install example/... did not install binaries")
2293	tg.wantExecutable(tg.path("bin/b"+exeSuffix), "go install example/... did not install binaries")
2294	tg.run("list", "-tags", "mytag", "example/b...")
2295	if strings.TrimSpace(tg.getStdout()) != "example/b" {
2296		t.Error("go list example/b did not find example/b")
2297	}
2298}
2299
2300// Issue 4773
2301func TestCaseCollisions(t *testing.T) {
2302	tg := testgo(t)
2303	defer tg.cleanup()
2304	tg.parallel()
2305	tg.tempDir("src/example/a/pkg")
2306	tg.tempDir("src/example/a/Pkg")
2307	tg.tempDir("src/example/b")
2308	tg.setenv("GOPATH", tg.path("."))
2309	tg.tempFile("src/example/a/a.go", `package p
2310		import (
2311			_ "example/a/pkg"
2312			_ "example/a/Pkg"
2313		)`)
2314	tg.tempFile("src/example/a/pkg/pkg.go", `package pkg`)
2315	tg.tempFile("src/example/a/Pkg/pkg.go", `package pkg`)
2316	tg.run("list", "-json", "example/a")
2317	tg.grepStdout("case-insensitive import collision", "go list -json example/a did not report import collision")
2318	tg.runFail("build", "example/a")
2319	tg.grepStderr("case-insensitive import collision", "go build example/a did not report import collision")
2320	tg.tempFile("src/example/b/file.go", `package b`)
2321	tg.tempFile("src/example/b/FILE.go", `package b`)
2322	f, err := os.Open(tg.path("src/example/b"))
2323	tg.must(err)
2324	names, err := f.Readdirnames(0)
2325	tg.must(err)
2326	tg.check(f.Close())
2327	args := []string{"list"}
2328	if len(names) == 2 {
2329		// case-sensitive file system, let directory read find both files
2330		args = append(args, "example/b")
2331	} else {
2332		// case-insensitive file system, list files explicitly on command line
2333		args = append(args, tg.path("src/example/b/file.go"), tg.path("src/example/b/FILE.go"))
2334	}
2335	tg.runFail(args...)
2336	tg.grepStderr("case-insensitive file name collision", "go list example/b did not report file name collision")
2337
2338	tg.runFail("list", "example/a/pkg", "example/a/Pkg")
2339	tg.grepStderr("case-insensitive import collision", "go list example/a/pkg example/a/Pkg did not report import collision")
2340	tg.run("list", "-json", "-e", "example/a/pkg", "example/a/Pkg")
2341	tg.grepStdout("case-insensitive import collision", "go list -json -e example/a/pkg example/a/Pkg did not report import collision")
2342	tg.runFail("build", "example/a/pkg", "example/a/Pkg")
2343	tg.grepStderr("case-insensitive import collision", "go build example/a/pkg example/a/Pkg did not report import collision")
2344}
2345
2346// Issue 17451, 17662.
2347func TestSymlinkWarning(t *testing.T) {
2348	tg := testgo(t)
2349	defer tg.cleanup()
2350	tg.parallel()
2351	tg.makeTempdir()
2352	tg.setenv("GOPATH", tg.path("."))
2353
2354	tg.tempDir("src/example/xx")
2355	tg.tempDir("yy/zz")
2356	tg.tempFile("yy/zz/zz.go", "package zz\n")
2357	if err := os.Symlink(tg.path("yy"), tg.path("src/example/xx/yy")); err != nil {
2358		t.Skipf("symlink failed: %v", err)
2359	}
2360	tg.run("list", "example/xx/z...")
2361	tg.grepStdoutNot(".", "list should not have matched anything")
2362	tg.grepStderr("matched no packages", "list should have reported that pattern matched no packages")
2363	tg.grepStderrNot("symlink", "list should not have reported symlink")
2364
2365	tg.run("list", "example/xx/...")
2366	tg.grepStdoutNot(".", "list should not have matched anything")
2367	tg.grepStderr("matched no packages", "list should have reported that pattern matched no packages")
2368	tg.grepStderr("ignoring symlink", "list should have reported symlink")
2369}
2370
2371// Issue 8181.
2372func TestGoGetDashTIssue8181(t *testing.T) {
2373	testenv.MustHaveExternalNetwork(t)
2374
2375	tg := testgo(t)
2376	defer tg.cleanup()
2377	tg.parallel()
2378	tg.makeTempdir()
2379	tg.setenv("GOPATH", tg.path("."))
2380	tg.run("get", "-v", "-t", "github.com/rsc/go-get-issue-8181/a", "github.com/rsc/go-get-issue-8181/b")
2381	tg.run("list", "...")
2382	tg.grepStdout("x/build/gerrit", "missing expected x/build/gerrit")
2383}
2384
2385func TestIssue11307(t *testing.T) {
2386	// go get -u was not working except in checkout directory
2387	testenv.MustHaveExternalNetwork(t)
2388
2389	tg := testgo(t)
2390	defer tg.cleanup()
2391	tg.parallel()
2392	tg.makeTempdir()
2393	tg.setenv("GOPATH", tg.path("."))
2394	tg.run("get", "github.com/rsc/go-get-issue-11307")
2395	tg.run("get", "-u", "github.com/rsc/go-get-issue-11307") // was failing
2396}
2397
2398func TestShadowingLogic(t *testing.T) {
2399	skipIfGccgo(t, "gccgo has no standard packages")
2400	tg := testgo(t)
2401	defer tg.cleanup()
2402	pwd := tg.pwd()
2403	sep := string(filepath.ListSeparator)
2404	tg.setenv("GOPATH", filepath.Join(pwd, "testdata", "shadow", "root1")+sep+filepath.Join(pwd, "testdata", "shadow", "root2"))
2405
2406	// The math in root1 is not "math" because the standard math is.
2407	tg.run("list", "-f", "({{.ImportPath}}) ({{.ConflictDir}})", "./testdata/shadow/root1/src/math")
2408	pwdForwardSlash := strings.Replace(pwd, string(os.PathSeparator), "/", -1)
2409	if !strings.HasPrefix(pwdForwardSlash, "/") {
2410		pwdForwardSlash = "/" + pwdForwardSlash
2411	}
2412	// The output will have makeImportValid applies, but we only
2413	// bother to deal with characters we might reasonably see.
2414	for _, r := range " :" {
2415		pwdForwardSlash = strings.Replace(pwdForwardSlash, string(r), "_", -1)
2416	}
2417	want := "(_" + pwdForwardSlash + "/testdata/shadow/root1/src/math) (" + filepath.Join(runtime.GOROOT(), "src", "math") + ")"
2418	if strings.TrimSpace(tg.getStdout()) != want {
2419		t.Error("shadowed math is not shadowed; looking for", want)
2420	}
2421
2422	// The foo in root1 is "foo".
2423	tg.run("list", "-f", "({{.ImportPath}}) ({{.ConflictDir}})", "./testdata/shadow/root1/src/foo")
2424	if strings.TrimSpace(tg.getStdout()) != "(foo) ()" {
2425		t.Error("unshadowed foo is shadowed")
2426	}
2427
2428	// The foo in root2 is not "foo" because the foo in root1 got there first.
2429	tg.run("list", "-f", "({{.ImportPath}}) ({{.ConflictDir}})", "./testdata/shadow/root2/src/foo")
2430	want = "(_" + pwdForwardSlash + "/testdata/shadow/root2/src/foo) (" + filepath.Join(pwd, "testdata", "shadow", "root1", "src", "foo") + ")"
2431	if strings.TrimSpace(tg.getStdout()) != want {
2432		t.Error("shadowed foo is not shadowed; looking for", want)
2433	}
2434
2435	// The error for go install should mention the conflicting directory.
2436	tg.runFail("install", "./testdata/shadow/root2/src/foo")
2437	want = "go install: no install location for " + filepath.Join(pwd, "testdata", "shadow", "root2", "src", "foo") + ": hidden by " + filepath.Join(pwd, "testdata", "shadow", "root1", "src", "foo")
2438	if strings.TrimSpace(tg.getStderr()) != want {
2439		t.Error("wrong shadowed install error; looking for", want)
2440	}
2441}
2442
2443// Only succeeds if source order is preserved.
2444func TestSourceFileNameOrderPreserved(t *testing.T) {
2445	tg := testgo(t)
2446	defer tg.cleanup()
2447	tg.run("test", "testdata/example1_test.go", "testdata/example2_test.go")
2448}
2449
2450// Check that coverage analysis works at all.
2451// Don't worry about the exact numbers but require not 0.0%.
2452func checkCoverage(tg *testgoData, data string) {
2453	tg.t.Helper()
2454	if regexp.MustCompile(`[^0-9]0\.0%`).MatchString(data) {
2455		tg.t.Error("some coverage results are 0.0%")
2456	}
2457}
2458
2459func TestCoverageRuns(t *testing.T) {
2460	skipIfGccgo(t, "gccgo has no cover tool")
2461	tooSlow(t)
2462	tg := testgo(t)
2463	defer tg.cleanup()
2464	tg.run("test", "-short", "-coverpkg=strings", "strings", "regexp")
2465	data := tg.getStdout() + tg.getStderr()
2466	tg.run("test", "-short", "-cover", "strings", "math", "regexp")
2467	data += tg.getStdout() + tg.getStderr()
2468	checkCoverage(tg, data)
2469}
2470
2471func TestCoverageDotImport(t *testing.T) {
2472	skipIfGccgo(t, "gccgo has no cover tool")
2473	tg := testgo(t)
2474	defer tg.cleanup()
2475	tg.parallel()
2476	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
2477	tg.run("test", "-coverpkg=coverdot1,coverdot2", "coverdot2")
2478	data := tg.getStdout() + tg.getStderr()
2479	checkCoverage(tg, data)
2480}
2481
2482// Check that coverage analysis uses set mode.
2483// Also check that coverage profiles merge correctly.
2484func TestCoverageUsesSetMode(t *testing.T) {
2485	skipIfGccgo(t, "gccgo has no cover tool")
2486	tooSlow(t)
2487	tg := testgo(t)
2488	defer tg.cleanup()
2489	tg.creatingTemp("testdata/cover.out")
2490	tg.run("test", "-short", "-cover", "encoding/binary", "errors", "-coverprofile=testdata/cover.out")
2491	data := tg.getStdout() + tg.getStderr()
2492	if out, err := ioutil.ReadFile("testdata/cover.out"); err != nil {
2493		t.Error(err)
2494	} else {
2495		if !bytes.Contains(out, []byte("mode: set")) {
2496			t.Error("missing mode: set")
2497		}
2498		if !bytes.Contains(out, []byte("errors.go")) {
2499			t.Error("missing errors.go")
2500		}
2501		if !bytes.Contains(out, []byte("binary.go")) {
2502			t.Error("missing binary.go")
2503		}
2504		if bytes.Count(out, []byte("mode: set")) != 1 {
2505			t.Error("too many mode: set")
2506		}
2507	}
2508	checkCoverage(tg, data)
2509}
2510
2511func TestCoverageUsesAtomicModeForRace(t *testing.T) {
2512	tooSlow(t)
2513	if !canRace {
2514		t.Skip("skipping because race detector not supported")
2515	}
2516	skipIfGccgo(t, "gccgo has no cover tool")
2517
2518	tg := testgo(t)
2519	defer tg.cleanup()
2520	tg.creatingTemp("testdata/cover.out")
2521	tg.run("test", "-short", "-race", "-cover", "encoding/binary", "-coverprofile=testdata/cover.out")
2522	data := tg.getStdout() + tg.getStderr()
2523	if out, err := ioutil.ReadFile("testdata/cover.out"); err != nil {
2524		t.Error(err)
2525	} else {
2526		if !bytes.Contains(out, []byte("mode: atomic")) {
2527			t.Error("missing mode: atomic")
2528		}
2529	}
2530	checkCoverage(tg, data)
2531}
2532
2533func TestCoverageSyncAtomicImport(t *testing.T) {
2534	skipIfGccgo(t, "gccgo has no cover tool")
2535	tooSlow(t)
2536	tg := testgo(t)
2537	defer tg.cleanup()
2538	tg.parallel()
2539	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
2540	tg.run("test", "-short", "-cover", "-covermode=atomic", "-coverpkg=coverdep/p1", "coverdep")
2541}
2542
2543func TestCoverageDepLoop(t *testing.T) {
2544	tooSlow(t)
2545	tg := testgo(t)
2546	defer tg.cleanup()
2547	tg.parallel()
2548	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
2549	// coverdep2/p1's xtest imports coverdep2/p2 which imports coverdep2/p1.
2550	// Make sure that coverage on coverdep2/p2 recompiles coverdep2/p2.
2551	tg.run("test", "-short", "-cover", "coverdep2/p1")
2552	tg.grepStdout("coverage: 100.0% of statements", "expected 100.0% coverage")
2553}
2554
2555func TestCoverageImportMainLoop(t *testing.T) {
2556	skipIfGccgo(t, "gccgo has no cover tool")
2557	tg := testgo(t)
2558	defer tg.cleanup()
2559	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
2560	tg.runFail("test", "importmain/test")
2561	tg.grepStderr("not an importable package", "did not detect import main")
2562	tg.runFail("test", "-cover", "importmain/test")
2563	tg.grepStderr("not an importable package", "did not detect import main")
2564}
2565
2566func TestCoveragePattern(t *testing.T) {
2567	skipIfGccgo(t, "gccgo has no cover tool")
2568	tooSlow(t)
2569	tg := testgo(t)
2570	defer tg.cleanup()
2571	tg.parallel()
2572	tg.makeTempdir()
2573	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
2574
2575	// If coverpkg=sleepy... expands by package loading
2576	// (as opposed to pattern matching on deps)
2577	// then it will try to load sleepybad, which does not compile,
2578	// and the test command will fail.
2579	tg.run("test", "-coverprofile="+tg.path("cover.out"), "-coverpkg=sleepy...", "-run=^$", "sleepy1")
2580}
2581
2582func TestCoverageErrorLine(t *testing.T) {
2583	skipIfGccgo(t, "gccgo has no cover tool")
2584	tooSlow(t)
2585	tg := testgo(t)
2586	defer tg.cleanup()
2587	tg.parallel()
2588	tg.makeTempdir()
2589	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
2590	tg.setenv("GOTMPDIR", tg.tempdir)
2591
2592	tg.runFail("test", "coverbad")
2593	tg.grepStderr(`coverbad[\\/]p\.go:4`, "did not find coverbad/p.go:4")
2594	if canCgo {
2595		tg.grepStderr(`coverbad[\\/]p1\.go:6`, "did not find coverbad/p1.go:6")
2596	}
2597	tg.grepStderrNot(regexp.QuoteMeta(tg.tempdir), "found temporary directory in error")
2598	stderr := tg.getStderr()
2599
2600	tg.runFail("test", "-cover", "coverbad")
2601	stderr2 := tg.getStderr()
2602
2603	// It's OK that stderr2 drops the character position in the error,
2604	// because of the //line directive (see golang.org/issue/22662).
2605	stderr = strings.Replace(stderr, "p.go:4:2:", "p.go:4:", -1)
2606	if stderr != stderr2 {
2607		t.Logf("test -cover changed error messages:\nbefore:\n%s\n\nafter:\n%s", stderr, stderr2)
2608		t.Skip("golang.org/issue/22660")
2609		t.FailNow()
2610	}
2611}
2612
2613func TestTestBuildFailureOutput(t *testing.T) {
2614	tooSlow(t)
2615
2616	tg := testgo(t)
2617	defer tg.cleanup()
2618	tg.parallel()
2619	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
2620
2621	// Doesn't build, -x output should not claim to run test.
2622	tg.runFail("test", "-x", "coverbad")
2623	tg.grepStderrNot(`[\\/]coverbad\.test( |$)`, "claimed to run test")
2624}
2625
2626func TestCoverageFunc(t *testing.T) {
2627	skipIfGccgo(t, "gccgo has no cover tool")
2628	tooSlow(t)
2629	tg := testgo(t)
2630	defer tg.cleanup()
2631	tg.parallel()
2632	tg.makeTempdir()
2633	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
2634
2635	tg.run("test", "-outputdir="+tg.tempdir, "-coverprofile=cover.out", "coverasm")
2636	tg.run("tool", "cover", "-func="+tg.path("cover.out"))
2637	tg.grepStdout(`\tg\t*100.0%`, "did not find g 100% covered")
2638	tg.grepStdoutNot(`\tf\t*[0-9]`, "reported coverage for assembly function f")
2639}
2640
2641func TestPluginNonMain(t *testing.T) {
2642	wd, err := os.Getwd()
2643	if err != nil {
2644		t.Fatal(err)
2645	}
2646
2647	pkg := filepath.Join(wd, "testdata", "testdep", "p2")
2648
2649	tg := testgo(t)
2650	defer tg.cleanup()
2651
2652	tg.runFail("build", "-buildmode=plugin", pkg)
2653}
2654
2655func TestTestEmpty(t *testing.T) {
2656	if !canRace {
2657		t.Skip("no race detector")
2658	}
2659
2660	wd, _ := os.Getwd()
2661	testdata := filepath.Join(wd, "testdata")
2662	for _, dir := range []string{"pkg", "test", "xtest", "pkgtest", "pkgxtest", "pkgtestxtest", "testxtest"} {
2663		t.Run(dir, func(t *testing.T) {
2664			tg := testgo(t)
2665			defer tg.cleanup()
2666			tg.setenv("GOPATH", testdata)
2667			tg.cd(filepath.Join(testdata, "src/empty/"+dir))
2668			tg.run("test", "-cover", "-coverpkg=.", "-race")
2669		})
2670		if testing.Short() {
2671			break
2672		}
2673	}
2674}
2675
2676func TestNoGoError(t *testing.T) {
2677	wd, _ := os.Getwd()
2678	testdata := filepath.Join(wd, "testdata")
2679	for _, dir := range []string{"empty/test", "empty/xtest", "empty/testxtest", "exclude", "exclude/ignore", "exclude/empty"} {
2680		t.Run(dir, func(t *testing.T) {
2681			tg := testgo(t)
2682			defer tg.cleanup()
2683			tg.setenv("GOPATH", testdata)
2684			tg.cd(filepath.Join(testdata, "src"))
2685			tg.runFail("build", "./"+dir)
2686			var want string
2687			if strings.Contains(dir, "test") {
2688				want = "no non-test Go files in "
2689			} else if dir == "exclude" {
2690				want = "build constraints exclude all Go files in "
2691			} else {
2692				want = "no Go files in "
2693			}
2694			tg.grepStderr(want, "wrong reason for failure")
2695		})
2696	}
2697}
2698
2699func TestTestRaceInstall(t *testing.T) {
2700	if !canRace {
2701		t.Skip("no race detector")
2702	}
2703	tooSlow(t)
2704
2705	tg := testgo(t)
2706	defer tg.cleanup()
2707	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
2708
2709	tg.tempDir("pkg")
2710	pkgdir := tg.path("pkg")
2711	tg.run("install", "-race", "-pkgdir="+pkgdir, "std")
2712	tg.run("test", "-race", "-pkgdir="+pkgdir, "-i", "-v", "empty/pkg")
2713	if tg.getStderr() != "" {
2714		t.Error("go test -i -race: rebuilds cached packages")
2715	}
2716}
2717
2718func TestBuildDryRunWithCgo(t *testing.T) {
2719	if !canCgo {
2720		t.Skip("skipping because cgo not enabled")
2721	}
2722
2723	tg := testgo(t)
2724	defer tg.cleanup()
2725	tg.tempFile("foo.go", `package main
2726
2727/*
2728#include <limits.h>
2729*/
2730import "C"
2731
2732func main() {
2733        println(C.INT_MAX)
2734}`)
2735	tg.run("build", "-n", tg.path("foo.go"))
2736	tg.grepStderrNot(`os.Stat .* no such file or directory`, "unexpected stat of archive file")
2737}
2738
2739func TestCoverageWithCgo(t *testing.T) {
2740	skipIfGccgo(t, "gccgo has no cover tool")
2741	tooSlow(t)
2742	if !canCgo {
2743		t.Skip("skipping because cgo not enabled")
2744	}
2745
2746	for _, dir := range []string{"cgocover", "cgocover2", "cgocover3", "cgocover4"} {
2747		t.Run(dir, func(t *testing.T) {
2748			tg := testgo(t)
2749			tg.parallel()
2750			defer tg.cleanup()
2751			tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
2752			tg.run("test", "-short", "-cover", dir)
2753			data := tg.getStdout() + tg.getStderr()
2754			checkCoverage(tg, data)
2755		})
2756	}
2757}
2758
2759func TestCgoAsmError(t *testing.T) {
2760	if !canCgo {
2761		t.Skip("skipping because cgo not enabled")
2762	}
2763
2764	tg := testgo(t)
2765	tg.parallel()
2766	defer tg.cleanup()
2767	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
2768	tg.runFail("build", "cgoasm")
2769	tg.grepBoth("package using cgo has Go assembly file", "did not detect Go assembly file")
2770}
2771
2772func TestCgoDependsOnSyscall(t *testing.T) {
2773	if testing.Short() {
2774		t.Skip("skipping test that removes $GOROOT/pkg/*_race in short mode")
2775	}
2776	if !canCgo {
2777		t.Skip("skipping because cgo not enabled")
2778	}
2779	if !canRace {
2780		t.Skip("skipping because race detector not supported")
2781	}
2782
2783	tg := testgo(t)
2784	defer tg.cleanup()
2785	files, err := filepath.Glob(filepath.Join(runtime.GOROOT(), "pkg", "*_race"))
2786	tg.must(err)
2787	for _, file := range files {
2788		tg.check(os.RemoveAll(file))
2789	}
2790	tg.tempFile("src/foo/foo.go", `
2791		package foo
2792		//#include <stdio.h>
2793		import "C"`)
2794	tg.setenv("GOPATH", tg.path("."))
2795	tg.run("build", "-race", "foo")
2796}
2797
2798func TestCgoShowsFullPathNames(t *testing.T) {
2799	if !canCgo {
2800		t.Skip("skipping because cgo not enabled")
2801	}
2802
2803	tg := testgo(t)
2804	defer tg.cleanup()
2805	tg.parallel()
2806	tg.tempFile("src/x/y/dirname/foo.go", `
2807		package foo
2808		import "C"
2809		func f() {`)
2810	tg.setenv("GOPATH", tg.path("."))
2811	tg.runFail("build", "x/y/dirname")
2812	tg.grepBoth("x/y/dirname", "error did not use full path")
2813}
2814
2815func TestCgoHandlesWlORIGIN(t *testing.T) {
2816	tooSlow(t)
2817	if !canCgo {
2818		t.Skip("skipping because cgo not enabled")
2819	}
2820
2821	tg := testgo(t)
2822	defer tg.cleanup()
2823	tg.parallel()
2824	tg.tempFile("src/origin/origin.go", `package origin
2825		// #cgo !darwin LDFLAGS: -Wl,-rpath,$ORIGIN
2826		// void f(void) {}
2827		import "C"
2828		func f() { C.f() }`)
2829	tg.setenv("GOPATH", tg.path("."))
2830	tg.run("build", "origin")
2831}
2832
2833func TestCgoPkgConfig(t *testing.T) {
2834	tooSlow(t)
2835	if !canCgo {
2836		t.Skip("skipping because cgo not enabled")
2837	}
2838	tg := testgo(t)
2839	defer tg.cleanup()
2840	tg.parallel()
2841
2842	tg.run("env", "PKG_CONFIG")
2843	pkgConfig := strings.TrimSpace(tg.getStdout())
2844	if out, err := exec.Command(pkgConfig, "--atleast-pkgconfig-version", "0.24").CombinedOutput(); err != nil {
2845		t.Skipf("%s --atleast-pkgconfig-version 0.24: %v\n%s", pkgConfig, err, out)
2846	}
2847
2848	// OpenBSD's pkg-config is strict about whitespace and only
2849	// supports backslash-escaped whitespace. It does not support
2850	// quotes, which the normal freedesktop.org pkg-config does
2851	// support. See http://man.openbsd.org/pkg-config.1
2852	tg.tempFile("foo.pc", `
2853Name: foo
2854Description: The foo library
2855Version: 1.0.0
2856Cflags: -Dhello=10 -Dworld=+32 -DDEFINED_FROM_PKG_CONFIG=hello\ world
2857`)
2858	tg.tempFile("foo.go", `package main
2859
2860/*
2861#cgo pkg-config: foo
2862int value() {
2863	return DEFINED_FROM_PKG_CONFIG;
2864}
2865*/
2866import "C"
2867import "os"
2868
2869func main() {
2870	if C.value() != 42 {
2871		println("value() =", C.value(), "wanted 42")
2872		os.Exit(1)
2873	}
2874}
2875`)
2876	tg.setenv("PKG_CONFIG_PATH", tg.path("."))
2877	tg.run("run", tg.path("foo.go"))
2878}
2879
2880// "go test -c -test.bench=XXX errors" should not hang.
2881// "go test -c" should also produce reproducible binaries.
2882// "go test -c" should also appear to write a new binary every time,
2883// even if it's really just updating the mtime on an existing up-to-date binary.
2884func TestIssue6480(t *testing.T) {
2885	skipIfGccgo(t, "gccgo has no standard packages")
2886	tooSlow(t)
2887	tg := testgo(t)
2888	defer tg.cleanup()
2889	// TODO: tg.parallel()
2890	tg.makeTempdir()
2891	tg.cd(tg.path("."))
2892	tg.run("test", "-c", "-test.bench=XXX", "errors")
2893	tg.run("test", "-c", "-o", "errors2.test", "errors")
2894
2895	data1, err := ioutil.ReadFile("errors.test" + exeSuffix)
2896	tg.must(err)
2897	data2, err := ioutil.ReadFile("errors2.test") // no exeSuffix because -o above doesn't have it
2898	tg.must(err)
2899	if !bytes.Equal(data1, data2) {
2900		t.Fatalf("go test -c errors produced different binaries when run twice")
2901	}
2902
2903	start := time.Now()
2904	tg.run("test", "-x", "-c", "-test.bench=XXX", "errors")
2905	tg.grepStderrNot(`[\\/]link|gccgo`, "incorrectly relinked up-to-date test binary")
2906	info, err := os.Stat("errors.test" + exeSuffix)
2907	if err != nil {
2908		t.Fatal(err)
2909	}
2910	start = truncateLike(start, info.ModTime())
2911	if info.ModTime().Before(start) {
2912		t.Fatalf("mtime of errors.test predates test -c command (%v < %v)", info.ModTime(), start)
2913	}
2914
2915	start = time.Now()
2916	tg.run("test", "-x", "-c", "-o", "errors2.test", "errors")
2917	tg.grepStderrNot(`[\\/]link|gccgo`, "incorrectly relinked up-to-date test binary")
2918	info, err = os.Stat("errors2.test")
2919	if err != nil {
2920		t.Fatal(err)
2921	}
2922	start = truncateLike(start, info.ModTime())
2923	if info.ModTime().Before(start) {
2924		t.Fatalf("mtime of errors2.test predates test -c command (%v < %v)", info.ModTime(), start)
2925	}
2926}
2927
2928// truncateLike returns the result of truncating t to the apparent precision of p.
2929func truncateLike(t, p time.Time) time.Time {
2930	nano := p.UnixNano()
2931	d := 1 * time.Nanosecond
2932	for nano%int64(d) == 0 && d < 1*time.Second {
2933		d *= 10
2934	}
2935	for nano%int64(d) == 0 && d < 2*time.Second {
2936		d *= 2
2937	}
2938	return t.Truncate(d)
2939}
2940
2941// cmd/cgo: undefined reference when linking a C-library using gccgo
2942func TestIssue7573(t *testing.T) {
2943	if !canCgo {
2944		t.Skip("skipping because cgo not enabled")
2945	}
2946	if _, err := exec.LookPath("gccgo"); err != nil {
2947		t.Skip("skipping because no gccgo compiler found")
2948	}
2949	t.Skip("golang.org/issue/22472")
2950
2951	tg := testgo(t)
2952	defer tg.cleanup()
2953	tg.parallel()
2954	tg.tempFile("src/cgoref/cgoref.go", `
2955package main
2956// #cgo LDFLAGS: -L alibpath -lalib
2957// void f(void) {}
2958import "C"
2959
2960func main() { C.f() }`)
2961	tg.setenv("GOPATH", tg.path("."))
2962	tg.run("build", "-n", "-compiler", "gccgo", "cgoref")
2963	tg.grepStderr(`gccgo.*\-L [^ ]*alibpath \-lalib`, `no Go-inline "#cgo LDFLAGS:" ("-L alibpath -lalib") passed to gccgo linking stage`)
2964}
2965
2966func TestListTemplateContextFunction(t *testing.T) {
2967	t.Parallel()
2968	for _, tt := range []struct {
2969		v    string
2970		want string
2971	}{
2972		{"GOARCH", runtime.GOARCH},
2973		{"GOOS", runtime.GOOS},
2974		{"GOROOT", filepath.Clean(runtime.GOROOT())},
2975		{"GOPATH", os.Getenv("GOPATH")},
2976		{"CgoEnabled", ""},
2977		{"UseAllFiles", ""},
2978		{"Compiler", ""},
2979		{"BuildTags", ""},
2980		{"ReleaseTags", ""},
2981		{"InstallSuffix", ""},
2982	} {
2983		tt := tt
2984		t.Run(tt.v, func(t *testing.T) {
2985			tg := testgo(t)
2986			tg.parallel()
2987			defer tg.cleanup()
2988			tmpl := "{{context." + tt.v + "}}"
2989			tg.run("list", "-f", tmpl)
2990			if tt.want == "" {
2991				return
2992			}
2993			if got := strings.TrimSpace(tg.getStdout()); got != tt.want {
2994				t.Errorf("go list -f %q: got %q; want %q", tmpl, got, tt.want)
2995			}
2996		})
2997	}
2998}
2999
3000// cmd/go: "go test" should fail if package does not build
3001func TestIssue7108(t *testing.T) {
3002	tg := testgo(t)
3003	defer tg.cleanup()
3004	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
3005	tg.runFail("test", "notest")
3006}
3007
3008// cmd/go: go test -a foo does not rebuild regexp.
3009func TestIssue6844(t *testing.T) {
3010	if testing.Short() {
3011		t.Skip("don't rebuild the standard library in short mode")
3012	}
3013
3014	tg := testgo(t)
3015	defer tg.cleanup()
3016	tg.creatingTemp("deps.test" + exeSuffix)
3017	tg.run("test", "-x", "-a", "-c", "testdata/dep_test.go")
3018	tg.grepStderr("regexp", "go test -x -a -c testdata/dep-test.go did not rebuild regexp")
3019}
3020
3021func TestBuildDashIInstallsDependencies(t *testing.T) {
3022	tooSlow(t)
3023
3024	tg := testgo(t)
3025	defer tg.cleanup()
3026	tg.parallel()
3027	tg.tempFile("src/x/y/foo/foo.go", `package foo
3028		func F() {}`)
3029	tg.tempFile("src/x/y/bar/bar.go", `package bar
3030		import "x/y/foo"
3031		func F() { foo.F() }`)
3032	tg.setenv("GOPATH", tg.path("."))
3033
3034	// don't let build -i overwrite runtime
3035	tg.wantNotStale("runtime", "", "must be non-stale before build -i")
3036
3037	checkbar := func(desc string) {
3038		tg.run("build", "-v", "-i", "x/y/bar")
3039		tg.grepBoth("x/y/foo", "first build -i "+desc+" did not build x/y/foo")
3040		tg.run("build", "-v", "-i", "x/y/bar")
3041		tg.grepBothNot("x/y/foo", "second build -i "+desc+" built x/y/foo")
3042	}
3043	checkbar("pkg")
3044
3045	tg.creatingTemp("bar" + exeSuffix)
3046	tg.sleep()
3047	tg.tempFile("src/x/y/foo/foo.go", `package foo
3048		func F() { F() }`)
3049	tg.tempFile("src/x/y/bar/bar.go", `package main
3050		import "x/y/foo"
3051		func main() { foo.F() }`)
3052	checkbar("cmd")
3053}
3054
3055func TestGoBuildInTestOnlyDirectoryFailsWithAGoodError(t *testing.T) {
3056	tg := testgo(t)
3057	defer tg.cleanup()
3058	tg.runFail("build", "./testdata/testonly")
3059	tg.grepStderr("no non-test Go files in", "go build ./testdata/testonly produced unexpected error")
3060}
3061
3062func TestGoTestDetectsTestOnlyImportCycles(t *testing.T) {
3063	tg := testgo(t)
3064	defer tg.cleanup()
3065	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
3066	tg.runFail("test", "-c", "testcycle/p3")
3067	tg.grepStderr("import cycle not allowed in test", "go test testcycle/p3 produced unexpected error")
3068
3069	tg.runFail("test", "-c", "testcycle/q1")
3070	tg.grepStderr("import cycle not allowed in test", "go test testcycle/q1 produced unexpected error")
3071}
3072
3073func TestGoTestFooTestWorks(t *testing.T) {
3074	tg := testgo(t)
3075	defer tg.cleanup()
3076	tg.run("test", "testdata/standalone_test.go")
3077}
3078
3079// Issue 22388
3080func TestGoTestMainWithWrongSignature(t *testing.T) {
3081	tg := testgo(t)
3082	defer tg.cleanup()
3083	tg.runFail("test", "testdata/standalone_main_wrong_test.go")
3084	tg.grepStderr(`wrong signature for TestMain, must be: func TestMain\(m \*testing.M\)`, "detected wrong error message")
3085}
3086
3087func TestGoTestMainAsNormalTest(t *testing.T) {
3088	tg := testgo(t)
3089	defer tg.cleanup()
3090	tg.run("test", "testdata/standalone_main_normal_test.go")
3091	tg.grepBoth(okPattern, "go test did not say ok")
3092}
3093
3094func TestGoTestMainTwice(t *testing.T) {
3095	tg := testgo(t)
3096	defer tg.cleanup()
3097	tg.makeTempdir()
3098	tg.setenv("GOCACHE", tg.tempdir)
3099	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
3100	tg.run("test", "-v", "multimain")
3101	if strings.Count(tg.getStdout(), "notwithstanding") != 2 {
3102		t.Fatal("tests did not run twice")
3103	}
3104}
3105
3106func TestGoTestFlagsAfterPackage(t *testing.T) {
3107	tooSlow(t)
3108	tg := testgo(t)
3109	defer tg.cleanup()
3110	tg.run("test", "testdata/flag_test.go", "-v", "-args", "-v=7") // Two distinct -v flags.
3111	tg.run("test", "-v", "testdata/flag_test.go", "-args", "-v=7") // Two distinct -v flags.
3112}
3113
3114func TestGoTestXtestonlyWorks(t *testing.T) {
3115	tg := testgo(t)
3116	defer tg.cleanup()
3117	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
3118	tg.run("clean", "-i", "xtestonly")
3119	tg.run("test", "xtestonly")
3120}
3121
3122func TestGoTestBuildsAnXtestContainingOnlyNonRunnableExamples(t *testing.T) {
3123	tg := testgo(t)
3124	defer tg.cleanup()
3125	tg.run("test", "-v", "./testdata/norunexample")
3126	tg.grepStdout("File with non-runnable example was built.", "file with non-runnable example was not built")
3127}
3128
3129func TestGoGenerateHandlesSimpleCommand(t *testing.T) {
3130	if runtime.GOOS == "windows" {
3131		t.Skip("skipping because windows has no echo command")
3132	}
3133
3134	tg := testgo(t)
3135	defer tg.cleanup()
3136	tg.run("generate", "./testdata/generate/test1.go")
3137	tg.grepStdout("Success", "go generate ./testdata/generate/test1.go generated wrong output")
3138}
3139
3140func TestGoGenerateHandlesCommandAlias(t *testing.T) {
3141	if runtime.GOOS == "windows" {
3142		t.Skip("skipping because windows has no echo command")
3143	}
3144
3145	tg := testgo(t)
3146	defer tg.cleanup()
3147	tg.run("generate", "./testdata/generate/test2.go")
3148	tg.grepStdout("Now is the time for all good men", "go generate ./testdata/generate/test2.go generated wrong output")
3149}
3150
3151func TestGoGenerateVariableSubstitution(t *testing.T) {
3152	if runtime.GOOS == "windows" {
3153		t.Skip("skipping because windows has no echo command")
3154	}
3155
3156	tg := testgo(t)
3157	defer tg.cleanup()
3158	tg.run("generate", "./testdata/generate/test3.go")
3159	tg.grepStdout(runtime.GOARCH+" test3.go:7 pabc xyzp/test3.go/123", "go generate ./testdata/generate/test3.go generated wrong output")
3160}
3161
3162func TestGoGenerateRunFlag(t *testing.T) {
3163	if runtime.GOOS == "windows" {
3164		t.Skip("skipping because windows has no echo command")
3165	}
3166
3167	tg := testgo(t)
3168	defer tg.cleanup()
3169	tg.run("generate", "-run", "y.s", "./testdata/generate/test4.go")
3170	tg.grepStdout("yes", "go generate -run yes ./testdata/generate/test4.go did not select yes")
3171	tg.grepStdoutNot("no", "go generate -run yes ./testdata/generate/test4.go selected no")
3172}
3173
3174func TestGoGenerateEnv(t *testing.T) {
3175	switch runtime.GOOS {
3176	case "plan9", "windows":
3177		t.Skipf("skipping because %s does not have the env command", runtime.GOOS)
3178	}
3179	tg := testgo(t)
3180	defer tg.cleanup()
3181	tg.parallel()
3182	tg.tempFile("env.go", "package main\n\n//go:generate env")
3183	tg.run("generate", tg.path("env.go"))
3184	for _, v := range []string{"GOARCH", "GOOS", "GOFILE", "GOLINE", "GOPACKAGE", "DOLLAR"} {
3185		tg.grepStdout("^"+v+"=", "go generate environment missing "+v)
3186	}
3187}
3188
3189func TestGoGenerateBadImports(t *testing.T) {
3190	if runtime.GOOS == "windows" {
3191		t.Skip("skipping because windows has no echo command")
3192	}
3193
3194	// This package has an invalid import causing an import cycle,
3195	// but go generate is supposed to still run.
3196	tg := testgo(t)
3197	defer tg.cleanup()
3198	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
3199	tg.run("generate", "gencycle")
3200	tg.grepStdout("hello world", "go generate gencycle did not run generator")
3201}
3202
3203func TestGoGetCustomDomainWildcard(t *testing.T) {
3204	testenv.MustHaveExternalNetwork(t)
3205
3206	tg := testgo(t)
3207	defer tg.cleanup()
3208	tg.makeTempdir()
3209	tg.setenv("GOPATH", tg.path("."))
3210	tg.run("get", "-u", "rsc.io/pdf/...")
3211	tg.wantExecutable(tg.path("bin/pdfpasswd"+exeSuffix), "did not build rsc/io/pdf/pdfpasswd")
3212}
3213
3214func TestGoGetInternalWildcard(t *testing.T) {
3215	testenv.MustHaveExternalNetwork(t)
3216
3217	tg := testgo(t)
3218	defer tg.cleanup()
3219	tg.makeTempdir()
3220	tg.setenv("GOPATH", tg.path("."))
3221	// used to fail with errors about internal packages
3222	tg.run("get", "github.com/rsc/go-get-issue-11960/...")
3223}
3224
3225func TestGoVetWithExternalTests(t *testing.T) {
3226	skipIfGccgo(t, "gccgo does not have vet")
3227	tg := testgo(t)
3228	defer tg.cleanup()
3229	tg.makeTempdir()
3230	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
3231	tg.runFail("vet", "vetpkg")
3232	tg.grepBoth("Printf", "go vet vetpkg did not find missing argument for Printf")
3233}
3234
3235func TestGoVetWithTags(t *testing.T) {
3236	skipIfGccgo(t, "gccgo does not have vet")
3237	tg := testgo(t)
3238	defer tg.cleanup()
3239	tg.makeTempdir()
3240	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
3241	tg.runFail("vet", "-tags", "tagtest", "vetpkg")
3242	tg.grepBoth(`c\.go.*Printf`, "go vet vetpkg did not run scan tagged file")
3243}
3244
3245func TestGoVetWithFlagsOn(t *testing.T) {
3246	skipIfGccgo(t, "gccgo does not have vet")
3247	tg := testgo(t)
3248	defer tg.cleanup()
3249	tg.makeTempdir()
3250	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
3251	tg.runFail("vet", "-printf", "vetpkg")
3252	tg.grepBoth("Printf", "go vet -printf vetpkg did not find missing argument for Printf")
3253}
3254
3255func TestGoVetWithFlagsOff(t *testing.T) {
3256	skipIfGccgo(t, "gccgo does not have vet")
3257	tg := testgo(t)
3258	defer tg.cleanup()
3259	tg.makeTempdir()
3260	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
3261	tg.run("vet", "-printf=false", "vetpkg")
3262}
3263
3264// Issue 23395.
3265func TestGoVetWithOnlyTestFiles(t *testing.T) {
3266	tg := testgo(t)
3267	defer tg.cleanup()
3268	tg.parallel()
3269	tg.tempFile("src/p/p_test.go", "package p; import \"testing\"; func TestMe(*testing.T) {}")
3270	tg.setenv("GOPATH", tg.path("."))
3271	tg.run("vet", "p")
3272}
3273
3274// Issue 24193.
3275func TestVetWithOnlyCgoFiles(t *testing.T) {
3276	if !canCgo {
3277		t.Skip("skipping because cgo not enabled")
3278	}
3279
3280	tg := testgo(t)
3281	defer tg.cleanup()
3282	tg.parallel()
3283	tg.tempFile("src/p/p.go", "package p; import \"C\"; func F() {}")
3284	tg.setenv("GOPATH", tg.path("."))
3285	tg.run("vet", "p")
3286}
3287
3288// Issue 9767, 19769.
3289func TestGoGetDotSlashDownload(t *testing.T) {
3290	testenv.MustHaveExternalNetwork(t)
3291
3292	tg := testgo(t)
3293	defer tg.cleanup()
3294	tg.tempDir("src/rsc.io")
3295	tg.setenv("GOPATH", tg.path("."))
3296	tg.cd(tg.path("src/rsc.io"))
3297	tg.run("get", "./pprof_mac_fix")
3298}
3299
3300// Issue 13037: Was not parsing <meta> tags in 404 served over HTTPS
3301func TestGoGetHTTPS404(t *testing.T) {
3302	testenv.MustHaveExternalNetwork(t)
3303	switch runtime.GOOS {
3304	case "darwin", "linux", "freebsd":
3305	default:
3306		t.Skipf("test case does not work on %s", runtime.GOOS)
3307	}
3308
3309	tg := testgo(t)
3310	defer tg.cleanup()
3311	tg.tempDir("src")
3312	tg.setenv("GOPATH", tg.path("."))
3313	tg.run("get", "bazil.org/fuse/fs/fstestutil")
3314}
3315
3316// Test that you cannot import a main package.
3317// See golang.org/issue/4210 and golang.org/issue/17475.
3318func TestImportMain(t *testing.T) {
3319	tooSlow(t)
3320
3321	tg := testgo(t)
3322	tg.parallel()
3323	defer tg.cleanup()
3324
3325	// Importing package main from that package main's test should work.
3326	tg.tempFile("src/x/main.go", `package main
3327		var X int
3328		func main() {}`)
3329	tg.tempFile("src/x/main_test.go", `package main_test
3330		import xmain "x"
3331		import "testing"
3332		var _ = xmain.X
3333		func TestFoo(t *testing.T) {}
3334	`)
3335	tg.setenv("GOPATH", tg.path("."))
3336	tg.creatingTemp("x" + exeSuffix)
3337	tg.run("build", "x")
3338	tg.run("test", "x")
3339
3340	// Importing package main from another package should fail.
3341	tg.tempFile("src/p1/p.go", `package p1
3342		import xmain "x"
3343		var _ = xmain.X
3344	`)
3345	tg.runFail("build", "p1")
3346	tg.grepStderr("import \"x\" is a program, not an importable package", "did not diagnose package main")
3347
3348	// ... even in that package's test.
3349	tg.tempFile("src/p2/p.go", `package p2
3350	`)
3351	tg.tempFile("src/p2/p_test.go", `package p2
3352		import xmain "x"
3353		import "testing"
3354		var _ = xmain.X
3355		func TestFoo(t *testing.T) {}
3356	`)
3357	tg.run("build", "p2")
3358	tg.runFail("test", "p2")
3359	tg.grepStderr("import \"x\" is a program, not an importable package", "did not diagnose package main")
3360
3361	// ... even if that package's test is an xtest.
3362	tg.tempFile("src/p3/p.go", `package p
3363	`)
3364	tg.tempFile("src/p3/p_test.go", `package p_test
3365		import xmain "x"
3366		import "testing"
3367		var _ = xmain.X
3368		func TestFoo(t *testing.T) {}
3369	`)
3370	tg.run("build", "p3")
3371	tg.runFail("test", "p3")
3372	tg.grepStderr("import \"x\" is a program, not an importable package", "did not diagnose package main")
3373
3374	// ... even if that package is a package main
3375	tg.tempFile("src/p4/p.go", `package main
3376	func main() {}
3377	`)
3378	tg.tempFile("src/p4/p_test.go", `package main
3379		import xmain "x"
3380		import "testing"
3381		var _ = xmain.X
3382		func TestFoo(t *testing.T) {}
3383	`)
3384	tg.creatingTemp("p4" + exeSuffix)
3385	tg.run("build", "p4")
3386	tg.runFail("test", "p4")
3387	tg.grepStderr("import \"x\" is a program, not an importable package", "did not diagnose package main")
3388
3389	// ... even if that package is a package main using an xtest.
3390	tg.tempFile("src/p5/p.go", `package main
3391	func main() {}
3392	`)
3393	tg.tempFile("src/p5/p_test.go", `package main_test
3394		import xmain "x"
3395		import "testing"
3396		var _ = xmain.X
3397		func TestFoo(t *testing.T) {}
3398	`)
3399	tg.creatingTemp("p5" + exeSuffix)
3400	tg.run("build", "p5")
3401	tg.runFail("test", "p5")
3402	tg.grepStderr("import \"x\" is a program, not an importable package", "did not diagnose package main")
3403}
3404
3405// Test that you cannot use a local import in a package
3406// accessed by a non-local import (found in a GOPATH/GOROOT).
3407// See golang.org/issue/17475.
3408func TestImportLocal(t *testing.T) {
3409	tooSlow(t)
3410
3411	tg := testgo(t)
3412	tg.parallel()
3413	defer tg.cleanup()
3414
3415	tg.tempFile("src/dir/x/x.go", `package x
3416		var X int
3417	`)
3418	tg.setenv("GOPATH", tg.path("."))
3419	tg.run("build", "dir/x")
3420
3421	// Ordinary import should work.
3422	tg.tempFile("src/dir/p0/p.go", `package p0
3423		import "dir/x"
3424		var _ = x.X
3425	`)
3426	tg.run("build", "dir/p0")
3427
3428	// Relative import should not.
3429	tg.tempFile("src/dir/p1/p.go", `package p1
3430		import "../x"
3431		var _ = x.X
3432	`)
3433	tg.runFail("build", "dir/p1")
3434	tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
3435
3436	// ... even in a test.
3437	tg.tempFile("src/dir/p2/p.go", `package p2
3438	`)
3439	tg.tempFile("src/dir/p2/p_test.go", `package p2
3440		import "../x"
3441		import "testing"
3442		var _ = x.X
3443		func TestFoo(t *testing.T) {}
3444	`)
3445	tg.run("build", "dir/p2")
3446	tg.runFail("test", "dir/p2")
3447	tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
3448
3449	// ... even in an xtest.
3450	tg.tempFile("src/dir/p2/p_test.go", `package p2_test
3451		import "../x"
3452		import "testing"
3453		var _ = x.X
3454		func TestFoo(t *testing.T) {}
3455	`)
3456	tg.run("build", "dir/p2")
3457	tg.runFail("test", "dir/p2")
3458	tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
3459
3460	// Relative import starting with ./ should not work either.
3461	tg.tempFile("src/dir/d.go", `package dir
3462		import "./x"
3463		var _ = x.X
3464	`)
3465	tg.runFail("build", "dir")
3466	tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
3467
3468	// ... even in a test.
3469	tg.tempFile("src/dir/d.go", `package dir
3470	`)
3471	tg.tempFile("src/dir/d_test.go", `package dir
3472		import "./x"
3473		import "testing"
3474		var _ = x.X
3475		func TestFoo(t *testing.T) {}
3476	`)
3477	tg.run("build", "dir")
3478	tg.runFail("test", "dir")
3479	tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
3480
3481	// ... even in an xtest.
3482	tg.tempFile("src/dir/d_test.go", `package dir_test
3483		import "./x"
3484		import "testing"
3485		var _ = x.X
3486		func TestFoo(t *testing.T) {}
3487	`)
3488	tg.run("build", "dir")
3489	tg.runFail("test", "dir")
3490	tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
3491
3492	// Relative import plain ".." should not work.
3493	tg.tempFile("src/dir/x/y/y.go", `package dir
3494		import ".."
3495		var _ = x.X
3496	`)
3497	tg.runFail("build", "dir/x/y")
3498	tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
3499
3500	// ... even in a test.
3501	tg.tempFile("src/dir/x/y/y.go", `package y
3502	`)
3503	tg.tempFile("src/dir/x/y/y_test.go", `package y
3504		import ".."
3505		import "testing"
3506		var _ = x.X
3507		func TestFoo(t *testing.T) {}
3508	`)
3509	tg.run("build", "dir/x/y")
3510	tg.runFail("test", "dir/x/y")
3511	tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
3512
3513	// ... even in an x test.
3514	tg.tempFile("src/dir/x/y/y_test.go", `package y_test
3515		import ".."
3516		import "testing"
3517		var _ = x.X
3518		func TestFoo(t *testing.T) {}
3519	`)
3520	tg.run("build", "dir/x/y")
3521	tg.runFail("test", "dir/x/y")
3522	tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
3523
3524	// Relative import "." should not work.
3525	tg.tempFile("src/dir/x/xx.go", `package x
3526		import "."
3527		var _ = x.X
3528	`)
3529	tg.runFail("build", "dir/x")
3530	tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
3531
3532	// ... even in a test.
3533	tg.tempFile("src/dir/x/xx.go", `package x
3534	`)
3535	tg.tempFile("src/dir/x/xx_test.go", `package x
3536		import "."
3537		import "testing"
3538		var _ = x.X
3539		func TestFoo(t *testing.T) {}
3540	`)
3541	tg.run("build", "dir/x")
3542	tg.runFail("test", "dir/x")
3543	tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
3544
3545	// ... even in an xtest.
3546	tg.tempFile("src/dir/x/xx.go", `package x
3547	`)
3548	tg.tempFile("src/dir/x/xx_test.go", `package x_test
3549		import "."
3550		import "testing"
3551		var _ = x.X
3552		func TestFoo(t *testing.T) {}
3553	`)
3554	tg.run("build", "dir/x")
3555	tg.runFail("test", "dir/x")
3556	tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
3557}
3558
3559func TestGoGetInsecure(t *testing.T) {
3560	testenv.MustHaveExternalNetwork(t)
3561
3562	tg := testgo(t)
3563	defer tg.cleanup()
3564	tg.makeTempdir()
3565	tg.setenv("GOPATH", tg.path("."))
3566	tg.failSSH()
3567
3568	const repo = "insecure.go-get-issue-15410.appspot.com/pkg/p"
3569
3570	// Try go get -d of HTTP-only repo (should fail).
3571	tg.runFail("get", "-d", repo)
3572
3573	// Try again with -insecure (should succeed).
3574	tg.run("get", "-d", "-insecure", repo)
3575
3576	// Try updating without -insecure (should fail).
3577	tg.runFail("get", "-d", "-u", "-f", repo)
3578}
3579
3580func TestGoGetUpdateInsecure(t *testing.T) {
3581	testenv.MustHaveExternalNetwork(t)
3582
3583	tg := testgo(t)
3584	defer tg.cleanup()
3585	tg.makeTempdir()
3586	tg.setenv("GOPATH", tg.path("."))
3587
3588	const repo = "github.com/golang/example"
3589
3590	// Clone the repo via HTTP manually.
3591	cmd := exec.Command("git", "clone", "-q", "http://"+repo, tg.path("src/"+repo))
3592	if out, err := cmd.CombinedOutput(); err != nil {
3593		t.Fatalf("cloning %v repo: %v\n%s", repo, err, out)
3594	}
3595
3596	// Update without -insecure should fail.
3597	// Update with -insecure should succeed.
3598	// We need -f to ignore import comments.
3599	const pkg = repo + "/hello"
3600	tg.runFail("get", "-d", "-u", "-f", pkg)
3601	tg.run("get", "-d", "-u", "-f", "-insecure", pkg)
3602}
3603
3604func TestGoGetInsecureCustomDomain(t *testing.T) {
3605	testenv.MustHaveExternalNetwork(t)
3606
3607	tg := testgo(t)
3608	defer tg.cleanup()
3609	tg.makeTempdir()
3610	tg.setenv("GOPATH", tg.path("."))
3611
3612	const repo = "insecure.go-get-issue-15410.appspot.com/pkg/p"
3613	tg.runFail("get", "-d", repo)
3614	tg.run("get", "-d", "-insecure", repo)
3615}
3616
3617func TestGoRunDirs(t *testing.T) {
3618	tg := testgo(t)
3619	defer tg.cleanup()
3620	tg.cd("testdata/rundir")
3621	tg.runFail("run", "x.go", "sub/sub.go")
3622	tg.grepStderr("named files must all be in one directory; have ./ and sub/", "wrong output")
3623	tg.runFail("run", "sub/sub.go", "x.go")
3624	tg.grepStderr("named files must all be in one directory; have sub/ and ./", "wrong output")
3625}
3626
3627func TestGoInstallPkgdir(t *testing.T) {
3628	skipIfGccgo(t, "gccgo has no standard packages")
3629	tooSlow(t)
3630
3631	tg := testgo(t)
3632	tg.parallel()
3633	defer tg.cleanup()
3634	tg.makeTempdir()
3635	pkg := tg.path(".")
3636	tg.run("install", "-pkgdir", pkg, "sync")
3637	tg.mustExist(filepath.Join(pkg, "sync.a"))
3638	tg.mustNotExist(filepath.Join(pkg, "sync/atomic.a"))
3639	tg.run("install", "-i", "-pkgdir", pkg, "sync")
3640	tg.mustExist(filepath.Join(pkg, "sync.a"))
3641	tg.mustExist(filepath.Join(pkg, "sync/atomic.a"))
3642}
3643
3644func TestGoTestRaceInstallCgo(t *testing.T) {
3645	if !canRace {
3646		t.Skip("skipping because race detector not supported")
3647	}
3648
3649	// golang.org/issue/10500.
3650	// This used to install a race-enabled cgo.
3651	tg := testgo(t)
3652	defer tg.cleanup()
3653	tg.run("tool", "-n", "cgo")
3654	cgo := strings.TrimSpace(tg.stdout.String())
3655	old, err := os.Stat(cgo)
3656	tg.must(err)
3657	tg.run("test", "-race", "-i", "runtime/race")
3658	new, err := os.Stat(cgo)
3659	tg.must(err)
3660	if !new.ModTime().Equal(old.ModTime()) {
3661		t.Fatalf("go test -i runtime/race reinstalled cmd/cgo")
3662	}
3663}
3664
3665func TestGoTestRaceFailures(t *testing.T) {
3666	tooSlow(t)
3667
3668	if !canRace {
3669		t.Skip("skipping because race detector not supported")
3670	}
3671
3672	tg := testgo(t)
3673	tg.parallel()
3674	defer tg.cleanup()
3675	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
3676
3677	tg.run("test", "testrace")
3678
3679	tg.runFail("test", "-race", "testrace")
3680	tg.grepStdout("FAIL: TestRace", "TestRace did not fail")
3681	tg.grepBothNot("PASS", "something passed")
3682
3683	tg.runFail("test", "-race", "testrace", "-run", "XXX", "-bench", ".")
3684	tg.grepStdout("FAIL: BenchmarkRace", "BenchmarkRace did not fail")
3685	tg.grepBothNot("PASS", "something passed")
3686}
3687
3688func TestGoTestImportErrorStack(t *testing.T) {
3689	const out = `package testdep/p1 (test)
3690	imports testdep/p2
3691	imports testdep/p3: build constraints exclude all Go files `
3692
3693	tg := testgo(t)
3694	defer tg.cleanup()
3695	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
3696	tg.runFail("test", "testdep/p1")
3697	if !strings.Contains(tg.stderr.String(), out) {
3698		t.Fatalf("did not give full import stack:\n\n%s", tg.stderr.String())
3699	}
3700}
3701
3702func TestGoGetUpdate(t *testing.T) {
3703	// golang.org/issue/9224.
3704	// The recursive updating was trying to walk to
3705	// former dependencies, not current ones.
3706
3707	testenv.MustHaveExternalNetwork(t)
3708
3709	tg := testgo(t)
3710	defer tg.cleanup()
3711	tg.makeTempdir()
3712	tg.setenv("GOPATH", tg.path("."))
3713
3714	rewind := func() {
3715		tg.run("get", "github.com/rsc/go-get-issue-9224-cmd")
3716		cmd := exec.Command("git", "reset", "--hard", "HEAD~")
3717		cmd.Dir = tg.path("src/github.com/rsc/go-get-issue-9224-lib")
3718		out, err := cmd.CombinedOutput()
3719		if err != nil {
3720			t.Fatalf("git: %v\n%s", err, out)
3721		}
3722	}
3723
3724	rewind()
3725	tg.run("get", "-u", "github.com/rsc/go-get-issue-9224-cmd")
3726
3727	// Again with -d -u.
3728	rewind()
3729	tg.run("get", "-d", "-u", "github.com/rsc/go-get-issue-9224-cmd")
3730}
3731
3732// Issue #20512.
3733func TestGoGetRace(t *testing.T) {
3734	testenv.MustHaveExternalNetwork(t)
3735	if !canRace {
3736		t.Skip("skipping because race detector not supported")
3737	}
3738
3739	tg := testgo(t)
3740	defer tg.cleanup()
3741	tg.makeTempdir()
3742	tg.setenv("GOPATH", tg.path("."))
3743	tg.run("get", "-race", "github.com/rsc/go-get-issue-9224-cmd")
3744}
3745
3746func TestGoGetDomainRoot(t *testing.T) {
3747	// golang.org/issue/9357.
3748	// go get foo.io (not foo.io/subdir) was not working consistently.
3749
3750	testenv.MustHaveExternalNetwork(t)
3751
3752	tg := testgo(t)
3753	defer tg.cleanup()
3754	tg.makeTempdir()
3755	tg.setenv("GOPATH", tg.path("."))
3756
3757	// go-get-issue-9357.appspot.com is running
3758	// the code at github.com/rsc/go-get-issue-9357,
3759	// a trivial Go on App Engine app that serves a
3760	// <meta> tag for the domain root.
3761	tg.run("get", "-d", "go-get-issue-9357.appspot.com")
3762	tg.run("get", "go-get-issue-9357.appspot.com")
3763	tg.run("get", "-u", "go-get-issue-9357.appspot.com")
3764
3765	tg.must(os.RemoveAll(tg.path("src/go-get-issue-9357.appspot.com")))
3766	tg.run("get", "go-get-issue-9357.appspot.com")
3767
3768	tg.must(os.RemoveAll(tg.path("src/go-get-issue-9357.appspot.com")))
3769	tg.run("get", "-u", "go-get-issue-9357.appspot.com")
3770}
3771
3772func TestGoInstallShadowedGOPATH(t *testing.T) {
3773	// golang.org/issue/3652.
3774	// go get foo.io (not foo.io/subdir) was not working consistently.
3775
3776	testenv.MustHaveExternalNetwork(t)
3777
3778	tg := testgo(t)
3779	defer tg.cleanup()
3780	tg.makeTempdir()
3781	tg.setenv("GOPATH", tg.path("gopath1")+string(filepath.ListSeparator)+tg.path("gopath2"))
3782
3783	tg.tempDir("gopath1/src/test")
3784	tg.tempDir("gopath2/src/test")
3785	tg.tempFile("gopath2/src/test/main.go", "package main\nfunc main(){}\n")
3786
3787	tg.cd(tg.path("gopath2/src/test"))
3788	tg.runFail("install")
3789	tg.grepStderr("no install location for.*gopath2.src.test: hidden by .*gopath1.src.test", "missing error")
3790}
3791
3792func TestGoBuildGOPATHOrder(t *testing.T) {
3793	// golang.org/issue/14176#issuecomment-179895769
3794	// golang.org/issue/14192
3795	// -I arguments to compiler could end up not in GOPATH order,
3796	// leading to unexpected import resolution in the compiler.
3797	// This is still not a complete fix (see golang.org/issue/14271 and next test)
3798	// but it is clearly OK and enough to fix both of the two reported
3799	// instances of the underlying problem. It will have to do for now.
3800
3801	tg := testgo(t)
3802	defer tg.cleanup()
3803	tg.makeTempdir()
3804	tg.setenv("GOPATH", tg.path("p1")+string(filepath.ListSeparator)+tg.path("p2"))
3805
3806	tg.tempFile("p1/src/foo/foo.go", "package foo\n")
3807	tg.tempFile("p2/src/baz/baz.go", "package baz\n")
3808	tg.tempFile("p2/pkg/"+runtime.GOOS+"_"+runtime.GOARCH+"/foo.a", "bad\n")
3809	tg.tempFile("p1/src/bar/bar.go", `
3810		package bar
3811		import _ "baz"
3812		import _ "foo"
3813	`)
3814
3815	tg.run("install", "-x", "bar")
3816}
3817
3818func TestGoBuildGOPATHOrderBroken(t *testing.T) {
3819	// This test is known not to work.
3820	// See golang.org/issue/14271.
3821	t.Skip("golang.org/issue/14271")
3822
3823	tg := testgo(t)
3824	defer tg.cleanup()
3825	tg.makeTempdir()
3826
3827	tg.tempFile("p1/src/foo/foo.go", "package foo\n")
3828	tg.tempFile("p2/src/baz/baz.go", "package baz\n")
3829	tg.tempFile("p1/pkg/"+runtime.GOOS+"_"+runtime.GOARCH+"/baz.a", "bad\n")
3830	tg.tempFile("p2/pkg/"+runtime.GOOS+"_"+runtime.GOARCH+"/foo.a", "bad\n")
3831	tg.tempFile("p1/src/bar/bar.go", `
3832		package bar
3833		import _ "baz"
3834		import _ "foo"
3835	`)
3836
3837	colon := string(filepath.ListSeparator)
3838	tg.setenv("GOPATH", tg.path("p1")+colon+tg.path("p2"))
3839	tg.run("install", "-x", "bar")
3840
3841	tg.setenv("GOPATH", tg.path("p2")+colon+tg.path("p1"))
3842	tg.run("install", "-x", "bar")
3843}
3844
3845func TestIssue11709(t *testing.T) {
3846	tg := testgo(t)
3847	defer tg.cleanup()
3848	tg.tempFile("run.go", `
3849		package main
3850		import "os"
3851		func main() {
3852			if os.Getenv("TERM") != "" {
3853				os.Exit(1)
3854			}
3855		}`)
3856	tg.unsetenv("TERM")
3857	tg.run("run", tg.path("run.go"))
3858}
3859
3860func TestIssue12096(t *testing.T) {
3861	tg := testgo(t)
3862	defer tg.cleanup()
3863	tg.tempFile("test_test.go", `
3864		package main
3865		import ("os"; "testing")
3866		func TestEnv(t *testing.T) {
3867			if os.Getenv("TERM") != "" {
3868				t.Fatal("TERM is set")
3869			}
3870		}`)
3871	tg.unsetenv("TERM")
3872	tg.run("test", tg.path("test_test.go"))
3873}
3874
3875func TestGoBuildOutput(t *testing.T) {
3876	skipIfGccgo(t, "gccgo has no standard packages")
3877	tooSlow(t)
3878	tg := testgo(t)
3879	defer tg.cleanup()
3880
3881	tg.makeTempdir()
3882	tg.cd(tg.path("."))
3883
3884	nonExeSuffix := ".exe"
3885	if exeSuffix == ".exe" {
3886		nonExeSuffix = ""
3887	}
3888
3889	tg.tempFile("x.go", "package main\nfunc main(){}\n")
3890	tg.run("build", "x.go")
3891	tg.wantExecutable("x"+exeSuffix, "go build x.go did not write x"+exeSuffix)
3892	tg.must(os.Remove(tg.path("x" + exeSuffix)))
3893	tg.mustNotExist("x" + nonExeSuffix)
3894
3895	tg.run("build", "-o", "myprog", "x.go")
3896	tg.mustNotExist("x")
3897	tg.mustNotExist("x.exe")
3898	tg.wantExecutable("myprog", "go build -o myprog x.go did not write myprog")
3899	tg.mustNotExist("myprog.exe")
3900
3901	tg.tempFile("p.go", "package p\n")
3902	tg.run("build", "p.go")
3903	tg.mustNotExist("p")
3904	tg.mustNotExist("p.a")
3905	tg.mustNotExist("p.o")
3906	tg.mustNotExist("p.exe")
3907
3908	tg.run("build", "-o", "p.a", "p.go")
3909	tg.wantArchive("p.a")
3910
3911	tg.run("build", "cmd/gofmt")
3912	tg.wantExecutable("gofmt"+exeSuffix, "go build cmd/gofmt did not write gofmt"+exeSuffix)
3913	tg.must(os.Remove(tg.path("gofmt" + exeSuffix)))
3914	tg.mustNotExist("gofmt" + nonExeSuffix)
3915
3916	tg.run("build", "-o", "mygofmt", "cmd/gofmt")
3917	tg.wantExecutable("mygofmt", "go build -o mygofmt cmd/gofmt did not write mygofmt")
3918	tg.mustNotExist("mygofmt.exe")
3919	tg.mustNotExist("gofmt")
3920	tg.mustNotExist("gofmt.exe")
3921
3922	tg.run("build", "sync/atomic")
3923	tg.mustNotExist("atomic")
3924	tg.mustNotExist("atomic.exe")
3925
3926	tg.run("build", "-o", "myatomic.a", "sync/atomic")
3927	tg.wantArchive("myatomic.a")
3928	tg.mustNotExist("atomic")
3929	tg.mustNotExist("atomic.a")
3930	tg.mustNotExist("atomic.exe")
3931
3932	tg.runFail("build", "-o", "whatever", "cmd/gofmt", "sync/atomic")
3933	tg.grepStderr("multiple packages", "did not reject -o with multiple packages")
3934}
3935
3936func TestGoBuildARM(t *testing.T) {
3937	if testing.Short() {
3938		t.Skip("skipping cross-compile in short mode")
3939	}
3940
3941	tg := testgo(t)
3942	defer tg.cleanup()
3943
3944	tg.makeTempdir()
3945	tg.cd(tg.path("."))
3946
3947	tg.setenv("GOARCH", "arm")
3948	tg.setenv("GOOS", "linux")
3949	tg.setenv("GOARM", "5")
3950	tg.tempFile("hello.go", `package main
3951		func main() {}`)
3952	tg.run("build", "hello.go")
3953	tg.grepStderrNot("unable to find math.a", "did not build math.a correctly")
3954}
3955
3956// For issue 14337.
3957func TestParallelTest(t *testing.T) {
3958	tooSlow(t)
3959	tg := testgo(t)
3960	tg.parallel()
3961	defer tg.cleanup()
3962	tg.makeTempdir()
3963	const testSrc = `package package_test
3964		import (
3965			"testing"
3966		)
3967		func TestTest(t *testing.T) {
3968		}`
3969	tg.tempFile("src/p1/p1_test.go", strings.Replace(testSrc, "package_test", "p1_test", 1))
3970	tg.tempFile("src/p2/p2_test.go", strings.Replace(testSrc, "package_test", "p2_test", 1))
3971	tg.tempFile("src/p3/p3_test.go", strings.Replace(testSrc, "package_test", "p3_test", 1))
3972	tg.tempFile("src/p4/p4_test.go", strings.Replace(testSrc, "package_test", "p4_test", 1))
3973	tg.setenv("GOPATH", tg.path("."))
3974	tg.run("test", "-p=4", "p1", "p2", "p3", "p4")
3975}
3976
3977func TestCgoConsistentResults(t *testing.T) {
3978	tooSlow(t)
3979	if !canCgo {
3980		t.Skip("skipping because cgo not enabled")
3981	}
3982	switch runtime.GOOS {
3983	case "freebsd":
3984		testenv.SkipFlaky(t, 15405)
3985	case "solaris":
3986		testenv.SkipFlaky(t, 13247)
3987	}
3988
3989	tg := testgo(t)
3990	defer tg.cleanup()
3991	tg.parallel()
3992	tg.makeTempdir()
3993	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
3994	exe1 := tg.path("cgotest1" + exeSuffix)
3995	exe2 := tg.path("cgotest2" + exeSuffix)
3996	tg.run("build", "-o", exe1, "cgotest")
3997	tg.run("build", "-x", "-o", exe2, "cgotest")
3998	b1, err := ioutil.ReadFile(exe1)
3999	tg.must(err)
4000	b2, err := ioutil.ReadFile(exe2)
4001	tg.must(err)
4002
4003	if !tg.doGrepMatch(`-fdebug-prefix-map=\$WORK`, &tg.stderr) {
4004		t.Skip("skipping because C compiler does not support -fdebug-prefix-map")
4005	}
4006	if !bytes.Equal(b1, b2) {
4007		t.Error("building cgotest twice did not produce the same output")
4008	}
4009}
4010
4011// Issue 14444: go get -u .../ duplicate loads errors
4012func TestGoGetUpdateAllDoesNotTryToLoadDuplicates(t *testing.T) {
4013	testenv.MustHaveExternalNetwork(t)
4014
4015	tg := testgo(t)
4016	defer tg.cleanup()
4017	tg.makeTempdir()
4018	tg.setenv("GOPATH", tg.path("."))
4019	tg.run("get", "-u", ".../")
4020	tg.grepStderrNot("duplicate loads of", "did not remove old packages from cache")
4021}
4022
4023// Issue 17119 more duplicate load errors
4024func TestIssue17119(t *testing.T) {
4025	testenv.MustHaveExternalNetwork(t)
4026
4027	tg := testgo(t)
4028	defer tg.cleanup()
4029	tg.parallel()
4030	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
4031	tg.runFail("build", "dupload")
4032	tg.grepBothNot("duplicate load|internal error", "internal error")
4033}
4034
4035func TestFatalInBenchmarkCauseNonZeroExitStatus(t *testing.T) {
4036	tg := testgo(t)
4037	defer tg.cleanup()
4038	// TODO: tg.parallel()
4039	tg.runFail("test", "-run", "^$", "-bench", ".", "./testdata/src/benchfatal")
4040	tg.grepBothNot("^ok", "test passed unexpectedly")
4041	tg.grepBoth("FAIL.*benchfatal", "test did not run everything")
4042}
4043
4044func TestBinaryOnlyPackages(t *testing.T) {
4045	tooSlow(t)
4046
4047	tg := testgo(t)
4048	defer tg.cleanup()
4049	tg.parallel()
4050	tg.makeTempdir()
4051	tg.setenv("GOPATH", tg.path("."))
4052
4053	tg.tempFile("src/p1/p1.go", `//go:binary-only-package
4054
4055		package p1
4056	`)
4057	tg.wantStale("p1", "missing or invalid binary-only package", "p1 is binary-only but has no binary, should be stale")
4058	tg.runFail("install", "p1")
4059	tg.grepStderr("missing or invalid binary-only package", "did not report attempt to compile binary-only package")
4060
4061	tg.tempFile("src/p1/p1.go", `
4062		package p1
4063		import "fmt"
4064		func F(b bool) { fmt.Printf("hello from p1\n"); if b { F(false) } }
4065	`)
4066	tg.run("install", "p1")
4067	os.Remove(tg.path("src/p1/p1.go"))
4068	tg.mustNotExist(tg.path("src/p1/p1.go"))
4069
4070	tg.tempFile("src/p2/p2.go", `//go:binary-only-packages-are-not-great
4071
4072		package p2
4073		import "p1"
4074		func F() { p1.F(true) }
4075	`)
4076	tg.runFail("install", "p2")
4077	tg.grepStderr("no Go files", "did not complain about missing sources")
4078
4079	tg.tempFile("src/p1/missing.go", `//go:binary-only-package
4080
4081		package p1
4082		import _ "fmt"
4083		func G()
4084	`)
4085	tg.wantNotStale("p1", "binary-only package", "should NOT want to rebuild p1 (first)")
4086	tg.run("install", "-x", "p1") // no-op, up to date
4087	tg.grepBothNot(`[\\/]compile`, "should not have run compiler")
4088	tg.run("install", "p2") // does not rebuild p1 (or else p2 will fail)
4089	tg.wantNotStale("p2", "", "should NOT want to rebuild p2")
4090
4091	// changes to the non-source-code do not matter,
4092	// and only one file needs the special comment.
4093	tg.tempFile("src/p1/missing2.go", `
4094		package p1
4095		func H()
4096	`)
4097	tg.wantNotStale("p1", "binary-only package", "should NOT want to rebuild p1 (second)")
4098	tg.wantNotStale("p2", "", "should NOT want to rebuild p2")
4099
4100	tg.tempFile("src/p3/p3.go", `
4101		package main
4102		import (
4103			"p1"
4104			"p2"
4105		)
4106		func main() {
4107			p1.F(false)
4108			p2.F()
4109		}
4110	`)
4111	tg.run("install", "p3")
4112
4113	tg.run("run", tg.path("src/p3/p3.go"))
4114	tg.grepStdout("hello from p1", "did not see message from p1")
4115
4116	tg.tempFile("src/p4/p4.go", `package main`)
4117	// The odd string split below avoids vet complaining about
4118	// a // +build line appearing too late in this source file.
4119	tg.tempFile("src/p4/p4not.go", `//go:binary-only-package
4120
4121		/`+`/ +build asdf
4122
4123		package main
4124	`)
4125	tg.run("list", "-f", "{{.BinaryOnly}}", "p4")
4126	tg.grepStdout("false", "did not see BinaryOnly=false for p4")
4127}
4128
4129// Issue 16050.
4130func TestAlwaysLinkSysoFiles(t *testing.T) {
4131	tg := testgo(t)
4132	defer tg.cleanup()
4133	tg.parallel()
4134	tg.tempDir("src/syso")
4135	tg.tempFile("src/syso/a.syso", ``)
4136	tg.tempFile("src/syso/b.go", `package syso`)
4137	tg.setenv("GOPATH", tg.path("."))
4138
4139	// We should see the .syso file regardless of the setting of
4140	// CGO_ENABLED.
4141
4142	tg.setenv("CGO_ENABLED", "1")
4143	tg.run("list", "-f", "{{.SysoFiles}}", "syso")
4144	tg.grepStdout("a.syso", "missing syso file with CGO_ENABLED=1")
4145
4146	tg.setenv("CGO_ENABLED", "0")
4147	tg.run("list", "-f", "{{.SysoFiles}}", "syso")
4148	tg.grepStdout("a.syso", "missing syso file with CGO_ENABLED=0")
4149}
4150
4151// Issue 16120.
4152func TestGenerateUsesBuildContext(t *testing.T) {
4153	if runtime.GOOS == "windows" {
4154		t.Skip("this test won't run under Windows")
4155	}
4156
4157	tg := testgo(t)
4158	defer tg.cleanup()
4159	tg.parallel()
4160	tg.tempDir("src/gen")
4161	tg.tempFile("src/gen/gen.go", "package gen\n//go:generate echo $GOOS $GOARCH\n")
4162	tg.setenv("GOPATH", tg.path("."))
4163
4164	tg.setenv("GOOS", "linux")
4165	tg.setenv("GOARCH", "amd64")
4166	tg.run("generate", "gen")
4167	tg.grepStdout("linux amd64", "unexpected GOOS/GOARCH combination")
4168
4169	tg.setenv("GOOS", "darwin")
4170	tg.setenv("GOARCH", "386")
4171	tg.run("generate", "gen")
4172	tg.grepStdout("darwin 386", "unexpected GOOS/GOARCH combination")
4173}
4174
4175// Issue 14450: go get -u .../ tried to import not downloaded package
4176func TestGoGetUpdateWithWildcard(t *testing.T) {
4177	testenv.MustHaveExternalNetwork(t)
4178
4179	tg := testgo(t)
4180	defer tg.cleanup()
4181	tg.parallel()
4182	tg.makeTempdir()
4183	tg.setenv("GOPATH", tg.path("."))
4184	const aPkgImportPath = "github.com/tmwh/go-get-issue-14450/a"
4185	tg.run("get", aPkgImportPath)
4186	tg.run("get", "-u", ".../")
4187	tg.grepStderrNot("cannot find package", "did not update packages given wildcard path")
4188
4189	var expectedPkgPaths = []string{
4190		"src/github.com/tmwh/go-get-issue-14450/b",
4191		"src/github.com/tmwh/go-get-issue-14450-b-dependency/c",
4192		"src/github.com/tmwh/go-get-issue-14450-b-dependency/d",
4193	}
4194
4195	for _, importPath := range expectedPkgPaths {
4196		_, err := os.Stat(tg.path(importPath))
4197		tg.must(err)
4198	}
4199	const notExpectedPkgPath = "src/github.com/tmwh/go-get-issue-14450-c-dependency/e"
4200	tg.mustNotExist(tg.path(notExpectedPkgPath))
4201}
4202
4203func TestGoEnv(t *testing.T) {
4204	tg := testgo(t)
4205	tg.parallel()
4206	defer tg.cleanup()
4207	tg.setenv("GOOS", "freebsd") // to avoid invalid pair errors
4208	tg.setenv("GOARCH", "arm")
4209	tg.run("env", "GOARCH")
4210	tg.grepStdout("^arm$", "GOARCH not honored")
4211
4212	tg.run("env", "GCCGO")
4213	tg.grepStdout(".", "GCCGO unexpectedly empty")
4214
4215	tg.run("env", "CGO_CFLAGS")
4216	tg.grepStdout(".", "default CGO_CFLAGS unexpectedly empty")
4217
4218	tg.setenv("CGO_CFLAGS", "-foobar")
4219	tg.run("env", "CGO_CFLAGS")
4220	tg.grepStdout("^-foobar$", "CGO_CFLAGS not honored")
4221
4222	tg.setenv("CC", "gcc -fmust -fgo -ffaster")
4223	tg.run("env", "CC")
4224	tg.grepStdout("gcc", "CC not found")
4225	tg.run("env", "GOGCCFLAGS")
4226	tg.grepStdout("-ffaster", "CC arguments not found")
4227}
4228
4229const (
4230	noMatchesPattern = `(?m)^ok.*\[no tests to run\]`
4231	okPattern        = `(?m)^ok`
4232)
4233
4234func TestMatchesNoTests(t *testing.T) {
4235	tg := testgo(t)
4236	defer tg.cleanup()
4237	// TODO: tg.parallel()
4238	tg.run("test", "-run", "ThisWillNotMatch", "testdata/standalone_test.go")
4239	tg.grepBoth(noMatchesPattern, "go test did not say [no tests to run]")
4240}
4241
4242func TestMatchesNoTestsDoesNotOverrideBuildFailure(t *testing.T) {
4243	tg := testgo(t)
4244	defer tg.cleanup()
4245	tg.parallel()
4246	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
4247	tg.runFail("test", "-run", "ThisWillNotMatch", "syntaxerror")
4248	tg.grepBothNot(noMatchesPattern, "go test did say [no tests to run]")
4249	tg.grepBoth("FAIL", "go test did not say FAIL")
4250}
4251
4252func TestMatchesNoBenchmarksIsOK(t *testing.T) {
4253	tg := testgo(t)
4254	defer tg.cleanup()
4255	// TODO: tg.parallel()
4256	tg.run("test", "-run", "^$", "-bench", "ThisWillNotMatch", "testdata/standalone_benchmark_test.go")
4257	tg.grepBothNot(noMatchesPattern, "go test did say [no tests to run]")
4258	tg.grepBoth(okPattern, "go test did not say ok")
4259}
4260
4261func TestMatchesOnlyExampleIsOK(t *testing.T) {
4262	tg := testgo(t)
4263	defer tg.cleanup()
4264	// TODO: tg.parallel()
4265	tg.run("test", "-run", "Example", "testdata/example1_test.go")
4266	tg.grepBothNot(noMatchesPattern, "go test did say [no tests to run]")
4267	tg.grepBoth(okPattern, "go test did not say ok")
4268}
4269
4270func TestMatchesOnlyBenchmarkIsOK(t *testing.T) {
4271	tg := testgo(t)
4272	defer tg.cleanup()
4273	// TODO: tg.parallel()
4274	tg.run("test", "-run", "^$", "-bench", ".", "testdata/standalone_benchmark_test.go")
4275	tg.grepBothNot(noMatchesPattern, "go test did say [no tests to run]")
4276	tg.grepBoth(okPattern, "go test did not say ok")
4277}
4278
4279func TestBenchmarkLabels(t *testing.T) {
4280	tg := testgo(t)
4281	defer tg.cleanup()
4282	// TODO: tg.parallel()
4283	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
4284	tg.run("test", "-run", "^$", "-bench", ".", "bench")
4285	tg.grepStdout(`(?m)^goos: `+runtime.GOOS, "go test did not print goos")
4286	tg.grepStdout(`(?m)^goarch: `+runtime.GOARCH, "go test did not print goarch")
4287	tg.grepStdout(`(?m)^pkg: bench`, "go test did not say pkg: bench")
4288	tg.grepBothNot(`(?s)pkg:.*pkg:`, "go test said pkg multiple times")
4289}
4290
4291func TestBenchmarkLabelsOutsideGOPATH(t *testing.T) {
4292	tg := testgo(t)
4293	defer tg.cleanup()
4294	// TODO: tg.parallel()
4295	tg.run("test", "-run", "^$", "-bench", ".", "testdata/standalone_benchmark_test.go")
4296	tg.grepStdout(`(?m)^goos: `+runtime.GOOS, "go test did not print goos")
4297	tg.grepStdout(`(?m)^goarch: `+runtime.GOARCH, "go test did not print goarch")
4298	tg.grepBothNot(`(?m)^pkg:`, "go test did say pkg:")
4299}
4300
4301func TestMatchesOnlyTestIsOK(t *testing.T) {
4302	tg := testgo(t)
4303	defer tg.cleanup()
4304	// TODO: tg.parallel()
4305	tg.run("test", "-run", "Test", "testdata/standalone_test.go")
4306	tg.grepBothNot(noMatchesPattern, "go test did say [no tests to run]")
4307	tg.grepBoth(okPattern, "go test did not say ok")
4308}
4309
4310func TestMatchesNoTestsWithSubtests(t *testing.T) {
4311	tg := testgo(t)
4312	defer tg.cleanup()
4313	tg.run("test", "-run", "ThisWillNotMatch", "testdata/standalone_sub_test.go")
4314	tg.grepBoth(noMatchesPattern, "go test did not say [no tests to run]")
4315}
4316
4317func TestMatchesNoSubtestsMatch(t *testing.T) {
4318	tg := testgo(t)
4319	defer tg.cleanup()
4320	tg.run("test", "-run", "Test/ThisWillNotMatch", "testdata/standalone_sub_test.go")
4321	tg.grepBoth(noMatchesPattern, "go test did not say [no tests to run]")
4322}
4323
4324func TestMatchesNoSubtestsDoesNotOverrideFailure(t *testing.T) {
4325	tg := testgo(t)
4326	defer tg.cleanup()
4327	tg.runFail("test", "-run", "TestThatFails/ThisWillNotMatch", "testdata/standalone_fail_sub_test.go")
4328	tg.grepBothNot(noMatchesPattern, "go test did say [no tests to run]")
4329	tg.grepBoth("FAIL", "go test did not say FAIL")
4330}
4331
4332func TestMatchesOnlySubtestIsOK(t *testing.T) {
4333	tg := testgo(t)
4334	defer tg.cleanup()
4335	tg.run("test", "-run", "Test/Sub", "testdata/standalone_sub_test.go")
4336	tg.grepBothNot(noMatchesPattern, "go test did say [no tests to run]")
4337	tg.grepBoth(okPattern, "go test did not say ok")
4338}
4339
4340func TestMatchesNoSubtestsParallel(t *testing.T) {
4341	tg := testgo(t)
4342	defer tg.cleanup()
4343	tg.run("test", "-run", "Test/Sub/ThisWillNotMatch", "testdata/standalone_parallel_sub_test.go")
4344	tg.grepBoth(noMatchesPattern, "go test did not say [no tests to run]")
4345}
4346
4347func TestMatchesOnlySubtestParallelIsOK(t *testing.T) {
4348	tg := testgo(t)
4349	defer tg.cleanup()
4350	tg.run("test", "-run", "Test/Sub/Nested", "testdata/standalone_parallel_sub_test.go")
4351	tg.grepBothNot(noMatchesPattern, "go test did say [no tests to run]")
4352	tg.grepBoth(okPattern, "go test did not say ok")
4353}
4354
4355// Issue 18845
4356func TestBenchTimeout(t *testing.T) {
4357	tooSlow(t)
4358	tg := testgo(t)
4359	defer tg.cleanup()
4360	tg.run("test", "-bench", ".", "-timeout", "750ms", "testdata/timeoutbench_test.go")
4361}
4362
4363// Issue 19394
4364func TestWriteProfilesOnTimeout(t *testing.T) {
4365	tooSlow(t)
4366	tg := testgo(t)
4367	defer tg.cleanup()
4368	tg.tempDir("profiling")
4369	tg.tempFile("profiling/timeouttest_test.go", `package timeouttest_test
4370import "testing"
4371import "time"
4372func TestSleep(t *testing.T) { time.Sleep(time.Second) }`)
4373	tg.cd(tg.path("profiling"))
4374	tg.runFail(
4375		"test",
4376		"-cpuprofile", tg.path("profiling/cpu.pprof"), "-memprofile", tg.path("profiling/mem.pprof"),
4377		"-timeout", "1ms")
4378	tg.mustHaveContent(tg.path("profiling/cpu.pprof"))
4379	tg.mustHaveContent(tg.path("profiling/mem.pprof"))
4380}
4381
4382func TestLinkXImportPathEscape(t *testing.T) {
4383	// golang.org/issue/16710
4384	skipIfGccgo(t, "gccgo does not support -ldflags -X")
4385	tg := testgo(t)
4386	defer tg.cleanup()
4387	tg.parallel()
4388	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
4389	exe := "./linkx" + exeSuffix
4390	tg.creatingTemp(exe)
4391	tg.run("build", "-o", exe, "-ldflags", "-X=my.pkg.Text=linkXworked", "my.pkg/main")
4392	out, err := exec.Command(exe).CombinedOutput()
4393	if err != nil {
4394		tg.t.Fatal(err)
4395	}
4396	if string(out) != "linkXworked\n" {
4397		tg.t.Log(string(out))
4398		tg.t.Fatal(`incorrect output: expected "linkXworked\n"`)
4399	}
4400}
4401
4402// Issue 18044.
4403func TestLdBindNow(t *testing.T) {
4404	tg := testgo(t)
4405	defer tg.cleanup()
4406	tg.parallel()
4407	tg.setenv("LD_BIND_NOW", "1")
4408	tg.run("help")
4409}
4410
4411// Issue 18225.
4412// This is really a cmd/asm issue but this is a convenient place to test it.
4413func TestConcurrentAsm(t *testing.T) {
4414	skipIfGccgo(t, "gccgo does not use cmd/asm")
4415	tg := testgo(t)
4416	defer tg.cleanup()
4417	tg.parallel()
4418	asm := `DATA ·constants<>+0x0(SB)/8,$0
4419GLOBL ·constants<>(SB),8,$8
4420`
4421	tg.tempFile("go/src/p/a.s", asm)
4422	tg.tempFile("go/src/p/b.s", asm)
4423	tg.tempFile("go/src/p/p.go", `package p`)
4424	tg.setenv("GOPATH", tg.path("go"))
4425	tg.run("build", "p")
4426}
4427
4428// Issue 18778.
4429func TestDotDotDotOutsideGOPATH(t *testing.T) {
4430	tg := testgo(t)
4431	defer tg.cleanup()
4432
4433	tg.tempFile("pkgs/a.go", `package x`)
4434	tg.tempFile("pkgs/a_test.go", `package x_test
4435import "testing"
4436func TestX(t *testing.T) {}`)
4437
4438	tg.tempFile("pkgs/a/a.go", `package a`)
4439	tg.tempFile("pkgs/a/a_test.go", `package a_test
4440import "testing"
4441func TestA(t *testing.T) {}`)
4442
4443	tg.cd(tg.path("pkgs"))
4444	tg.run("build", "./...")
4445	tg.run("test", "./...")
4446	tg.run("list", "./...")
4447	tg.grepStdout("pkgs$", "expected package not listed")
4448	tg.grepStdout("pkgs/a", "expected package not listed")
4449}
4450
4451// Issue 18975.
4452func TestFFLAGS(t *testing.T) {
4453	if !canCgo {
4454		t.Skip("skipping because cgo not enabled")
4455	}
4456
4457	tg := testgo(t)
4458	defer tg.cleanup()
4459	tg.parallel()
4460
4461	tg.tempFile("p/src/p/main.go", `package main
4462		// #cgo FFLAGS: -no-such-fortran-flag
4463		import "C"
4464		func main() {}
4465	`)
4466	tg.tempFile("p/src/p/a.f", `! comment`)
4467	tg.setenv("GOPATH", tg.path("p"))
4468
4469	// This should normally fail because we are passing an unknown flag,
4470	// but issue #19080 points to Fortran compilers that succeed anyhow.
4471	// To work either way we call doRun directly rather than run or runFail.
4472	tg.doRun([]string{"build", "-x", "p"})
4473
4474	tg.grepStderr("no-such-fortran-flag", `missing expected "-no-such-fortran-flag"`)
4475}
4476
4477// Issue 19198.
4478// This is really a cmd/link issue but this is a convenient place to test it.
4479func TestDuplicateGlobalAsmSymbols(t *testing.T) {
4480	skipIfGccgo(t, "gccgo does not use cmd/asm")
4481	tooSlow(t)
4482	if runtime.GOARCH != "386" && runtime.GOARCH != "amd64" {
4483		t.Skipf("skipping test on %s", runtime.GOARCH)
4484	}
4485	if !canCgo {
4486		t.Skip("skipping because cgo not enabled")
4487	}
4488
4489	tg := testgo(t)
4490	defer tg.cleanup()
4491	tg.parallel()
4492
4493	asm := `
4494#include "textflag.h"
4495
4496DATA sym<>+0x0(SB)/8,$0
4497GLOBL sym<>(SB),(NOPTR+RODATA),$8
4498
4499TEXT ·Data(SB),NOSPLIT,$0
4500	MOVB sym<>(SB), AX
4501	MOVB AX, ret+0(FP)
4502	RET
4503`
4504	tg.tempFile("go/src/a/a.s", asm)
4505	tg.tempFile("go/src/a/a.go", `package a; func Data() uint8`)
4506	tg.tempFile("go/src/b/b.s", asm)
4507	tg.tempFile("go/src/b/b.go", `package b; func Data() uint8`)
4508	tg.tempFile("go/src/p/p.go", `
4509package main
4510import "a"
4511import "b"
4512import "C"
4513func main() {
4514	_ = a.Data() + b.Data()
4515}
4516`)
4517	tg.setenv("GOPATH", tg.path("go"))
4518	exe := tg.path("p.exe")
4519	tg.creatingTemp(exe)
4520	tg.run("build", "-o", exe, "p")
4521}
4522
4523func TestBuildTagsNoComma(t *testing.T) {
4524	skipIfGccgo(t, "gccgo has no standard packages")
4525	tg := testgo(t)
4526	defer tg.cleanup()
4527	tg.makeTempdir()
4528	tg.setenv("GOPATH", tg.path("go"))
4529	tg.run("build", "-tags", "tag1 tag2", "math")
4530	tg.runFail("build", "-tags", "tag1,tag2", "math")
4531	tg.grepBoth("space-separated list contains comma", "-tags with a comma-separated list didn't error")
4532}
4533
4534func copyFile(src, dst string, perm os.FileMode) error {
4535	sf, err := os.Open(src)
4536	if err != nil {
4537		return err
4538	}
4539	defer sf.Close()
4540
4541	df, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
4542	if err != nil {
4543		return err
4544	}
4545
4546	_, err = io.Copy(df, sf)
4547	err2 := df.Close()
4548	if err != nil {
4549		return err
4550	}
4551	return err2
4552}
4553
4554func TestExecutableGOROOT(t *testing.T) {
4555	skipIfGccgo(t, "gccgo has no GOROOT")
4556	if runtime.GOOS == "openbsd" {
4557		t.Skipf("test case does not work on %s, missing os.Executable", runtime.GOOS)
4558	}
4559
4560	// Env with no GOROOT.
4561	var env []string
4562	for _, e := range os.Environ() {
4563		if !strings.HasPrefix(e, "GOROOT=") {
4564			env = append(env, e)
4565		}
4566	}
4567
4568	check := func(t *testing.T, exe, want string) {
4569		cmd := exec.Command(exe, "env", "GOROOT")
4570		cmd.Env = env
4571		out, err := cmd.CombinedOutput()
4572		if err != nil {
4573			t.Fatalf("%s env GOROOT: %v, %s", exe, err, out)
4574		}
4575		goroot, err := filepath.EvalSymlinks(strings.TrimSpace(string(out)))
4576		if err != nil {
4577			t.Fatal(err)
4578		}
4579		want, err = filepath.EvalSymlinks(want)
4580		if err != nil {
4581			t.Fatal(err)
4582		}
4583		if !strings.EqualFold(goroot, want) {
4584			t.Errorf("go env GOROOT:\nhave %s\nwant %s", goroot, want)
4585		} else {
4586			t.Logf("go env GOROOT: %s", goroot)
4587		}
4588	}
4589
4590	// Note: Must not call tg methods inside subtests: tg is attached to outer t.
4591	tg := testgo(t)
4592	defer tg.cleanup()
4593
4594	tg.makeTempdir()
4595	tg.tempDir("new/bin")
4596	newGoTool := tg.path("new/bin/go" + exeSuffix)
4597	tg.must(copyFile(tg.goTool(), newGoTool, 0775))
4598	newRoot := tg.path("new")
4599
4600	t.Run("RelocatedExe", func(t *testing.T) {
4601		// Should fall back to default location in binary,
4602		// which is the GOROOT we used when building testgo.exe.
4603		check(t, newGoTool, testGOROOT)
4604	})
4605
4606	// If the binary is sitting in a bin dir next to ../pkg/tool, that counts as a GOROOT,
4607	// so it should find the new tree.
4608	tg.tempDir("new/pkg/tool")
4609	t.Run("RelocatedTree", func(t *testing.T) {
4610		check(t, newGoTool, newRoot)
4611	})
4612
4613	tg.tempDir("other/bin")
4614	symGoTool := tg.path("other/bin/go" + exeSuffix)
4615
4616	// Symlink into go tree should still find go tree.
4617	t.Run("SymlinkedExe", func(t *testing.T) {
4618		testenv.MustHaveSymlink(t)
4619		if err := os.Symlink(newGoTool, symGoTool); err != nil {
4620			t.Fatal(err)
4621		}
4622		check(t, symGoTool, newRoot)
4623	})
4624
4625	tg.must(os.RemoveAll(tg.path("new/pkg")))
4626
4627	// Binaries built in the new tree should report the
4628	// new tree when they call runtime.GOROOT.
4629	t.Run("RuntimeGoroot", func(t *testing.T) {
4630		// Build a working GOROOT the easy way, with symlinks.
4631		testenv.MustHaveSymlink(t)
4632		if err := os.Symlink(filepath.Join(testGOROOT, "src"), tg.path("new/src")); err != nil {
4633			t.Fatal(err)
4634		}
4635		if err := os.Symlink(filepath.Join(testGOROOT, "pkg"), tg.path("new/pkg")); err != nil {
4636			t.Fatal(err)
4637		}
4638
4639		cmd := exec.Command(newGoTool, "run", "testdata/print_goroot.go")
4640		cmd.Env = env
4641		out, err := cmd.CombinedOutput()
4642		if err != nil {
4643			t.Fatalf("%s run testdata/print_goroot.go: %v, %s", newGoTool, err, out)
4644		}
4645		goroot, err := filepath.EvalSymlinks(strings.TrimSpace(string(out)))
4646		if err != nil {
4647			t.Fatal(err)
4648		}
4649		want, err := filepath.EvalSymlinks(tg.path("new"))
4650		if err != nil {
4651			t.Fatal(err)
4652		}
4653		if !strings.EqualFold(goroot, want) {
4654			t.Errorf("go run testdata/print_goroot.go:\nhave %s\nwant %s", goroot, want)
4655		} else {
4656			t.Logf("go run testdata/print_goroot.go: %s", goroot)
4657		}
4658	})
4659}
4660
4661func TestNeedVersion(t *testing.T) {
4662	skipIfGccgo(t, "gccgo does not use cmd/compile")
4663	tg := testgo(t)
4664	defer tg.cleanup()
4665	tg.parallel()
4666	tg.tempFile("goversion.go", `package main; func main() {}`)
4667	path := tg.path("goversion.go")
4668	tg.setenv("TESTGO_VERSION", "go1.testgo")
4669	tg.runFail("run", path)
4670	tg.grepStderr("compile", "does not match go tool version")
4671}
4672
4673// Test that user can override default code generation flags.
4674func TestUserOverrideFlags(t *testing.T) {
4675	skipIfGccgo(t, "gccgo does not use -gcflags")
4676	if !canCgo {
4677		t.Skip("skipping because cgo not enabled")
4678	}
4679	if runtime.GOOS != "linux" {
4680		// We are testing platform-independent code, so it's
4681		// OK to skip cases that work differently.
4682		t.Skipf("skipping on %s because test only works if c-archive implies -shared", runtime.GOOS)
4683	}
4684
4685	tg := testgo(t)
4686	defer tg.cleanup()
4687	// Don't call tg.parallel, as creating override.h and override.a may
4688	// confuse other tests.
4689	tg.tempFile("override.go", `package main
4690
4691import "C"
4692
4693//export GoFunc
4694func GoFunc() {}
4695
4696func main() {}`)
4697	tg.creatingTemp("override.a")
4698	tg.creatingTemp("override.h")
4699	tg.run("build", "-x", "-buildmode=c-archive", "-gcflags=all=-shared=false", tg.path("override.go"))
4700	tg.grepStderr("compile .*-shared .*-shared=false", "user can not override code generation flag")
4701}
4702
4703func TestCgoFlagContainsSpace(t *testing.T) {
4704	tooSlow(t)
4705	if !canCgo {
4706		t.Skip("skipping because cgo not enabled")
4707	}
4708	tg := testgo(t)
4709	defer tg.cleanup()
4710
4711	tg.makeTempdir()
4712	tg.cd(tg.path("."))
4713	tg.tempFile("main.go", `package main
4714		// #cgo CFLAGS: -I"c flags"
4715		// #cgo LDFLAGS: -L"ld flags"
4716		import "C"
4717		func main() {}
4718	`)
4719	tg.run("run", "-x", "main.go")
4720	tg.grepStderr(`"-I[^"]+c flags"`, "did not find quoted c flags")
4721	tg.grepStderrNot(`"-I[^"]+c flags".*"-I[^"]+c flags"`, "found too many quoted c flags")
4722	tg.grepStderr(`"-L[^"]+ld flags"`, "did not find quoted ld flags")
4723	tg.grepStderrNot(`"-L[^"]+c flags".*"-L[^"]+c flags"`, "found too many quoted ld flags")
4724}
4725
4726// Issue #20435.
4727func TestGoTestRaceCoverModeFailures(t *testing.T) {
4728	tooSlow(t)
4729	if !canRace {
4730		t.Skip("skipping because race detector not supported")
4731	}
4732
4733	tg := testgo(t)
4734	tg.parallel()
4735	defer tg.cleanup()
4736	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
4737
4738	tg.run("test", "testrace")
4739
4740	tg.runFail("test", "-race", "-covermode=set", "testrace")
4741	tg.grepStderr(`-covermode must be "atomic", not "set", when -race is enabled`, "-race -covermode=set was allowed")
4742	tg.grepBothNot("PASS", "something passed")
4743}
4744
4745// Issue 9737: verify that GOARM and GO386 affect the computed build ID.
4746func TestBuildIDContainsArchModeEnv(t *testing.T) {
4747	if testing.Short() {
4748		t.Skip("skipping in short mode")
4749	}
4750
4751	var tg *testgoData
4752	testWith := func(before, after func()) func(*testing.T) {
4753		return func(t *testing.T) {
4754			tg = testgo(t)
4755			defer tg.cleanup()
4756			tg.tempFile("src/mycmd/x.go", `package main
4757func main() {}`)
4758			tg.setenv("GOPATH", tg.path("."))
4759
4760			tg.cd(tg.path("src/mycmd"))
4761			tg.setenv("GOOS", "linux")
4762			before()
4763			tg.run("install", "mycmd")
4764			after()
4765			tg.wantStale("mycmd", "stale dependency: runtime/internal/sys", "should be stale after environment variable change")
4766		}
4767	}
4768
4769	t.Run("386", testWith(func() {
4770		tg.setenv("GOARCH", "386")
4771		tg.setenv("GO386", "387")
4772	}, func() {
4773		tg.setenv("GO386", "sse2")
4774	}))
4775
4776	t.Run("arm", testWith(func() {
4777		tg.setenv("GOARCH", "arm")
4778		tg.setenv("GOARM", "5")
4779	}, func() {
4780		tg.setenv("GOARM", "7")
4781	}))
4782}
4783
4784func TestTestRegexps(t *testing.T) {
4785	tg := testgo(t)
4786	defer tg.cleanup()
4787	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
4788	tg.run("test", "-cpu=1", "-run=X/Y", "-bench=X/Y", "-count=2", "-v", "testregexp")
4789	var lines []string
4790	for _, line := range strings.SplitAfter(tg.getStdout(), "\n") {
4791		if strings.Contains(line, "=== RUN") || strings.Contains(line, "--- BENCH") || strings.Contains(line, "LOG") {
4792			lines = append(lines, line)
4793		}
4794	}
4795
4796	// Important parts:
4797	//	TestX is run, twice
4798	//	TestX/Y is run, twice
4799	//	TestXX is run, twice
4800	//	TestZ is not run
4801	//	BenchmarkX is run but only with N=1, once
4802	//	BenchmarkXX is run but only with N=1, once
4803	//	BenchmarkX/Y is run in full, twice
4804	want := `=== RUN   TestX
4805=== RUN   TestX/Y
4806	x_test.go:6: LOG: X running
4807    	x_test.go:8: LOG: Y running
4808=== RUN   TestXX
4809	z_test.go:10: LOG: XX running
4810=== RUN   TestX
4811=== RUN   TestX/Y
4812	x_test.go:6: LOG: X running
4813    	x_test.go:8: LOG: Y running
4814=== RUN   TestXX
4815	z_test.go:10: LOG: XX running
4816--- BENCH: BenchmarkX/Y
4817	x_test.go:15: LOG: Y running N=1
4818	x_test.go:15: LOG: Y running N=100
4819	x_test.go:15: LOG: Y running N=10000
4820	x_test.go:15: LOG: Y running N=1000000
4821	x_test.go:15: LOG: Y running N=100000000
4822	x_test.go:15: LOG: Y running N=2000000000
4823--- BENCH: BenchmarkX/Y
4824	x_test.go:15: LOG: Y running N=1
4825	x_test.go:15: LOG: Y running N=100
4826	x_test.go:15: LOG: Y running N=10000
4827	x_test.go:15: LOG: Y running N=1000000
4828	x_test.go:15: LOG: Y running N=100000000
4829	x_test.go:15: LOG: Y running N=2000000000
4830--- BENCH: BenchmarkX
4831	x_test.go:13: LOG: X running N=1
4832--- BENCH: BenchmarkXX
4833	z_test.go:18: LOG: XX running N=1
4834`
4835
4836	have := strings.Join(lines, "")
4837	if have != want {
4838		t.Errorf("reduced output:<<<\n%s>>> want:<<<\n%s>>>", have, want)
4839	}
4840}
4841
4842func TestListTests(t *testing.T) {
4843	tooSlow(t)
4844	var tg *testgoData
4845	testWith := func(listName, expected string) func(*testing.T) {
4846		return func(t *testing.T) {
4847			tg = testgo(t)
4848			defer tg.cleanup()
4849			tg.run("test", "./testdata/src/testlist/...", fmt.Sprintf("-list=%s", listName))
4850			tg.grepStdout(expected, fmt.Sprintf("-test.list=%s returned %q, expected %s", listName, tg.getStdout(), expected))
4851		}
4852	}
4853
4854	t.Run("Test", testWith("Test", "TestSimple"))
4855	t.Run("Bench", testWith("Benchmark", "BenchmarkSimple"))
4856	t.Run("Example1", testWith("Example", "ExampleSimple"))
4857	t.Run("Example2", testWith("Example", "ExampleWithEmptyOutput"))
4858}
4859
4860func TestBuildmodePIE(t *testing.T) {
4861	if testing.Short() && testenv.Builder() == "" {
4862		t.Skipf("skipping in -short mode on non-builder")
4863	}
4864
4865	platform := fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH)
4866	switch platform {
4867	case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x",
4868		"android/amd64", "android/arm", "android/arm64", "android/386":
4869	case "darwin/amd64":
4870	default:
4871		t.Skipf("skipping test because buildmode=pie is not supported on %s", platform)
4872	}
4873
4874	tg := testgo(t)
4875	defer tg.cleanup()
4876
4877	tg.tempFile("main.go", `package main; func main() { print("hello") }`)
4878	src := tg.path("main.go")
4879	obj := tg.path("main")
4880	tg.run("build", "-buildmode=pie", "-o", obj, src)
4881
4882	switch runtime.GOOS {
4883	case "linux", "android":
4884		f, err := elf.Open(obj)
4885		if err != nil {
4886			t.Fatal(err)
4887		}
4888		defer f.Close()
4889		if f.Type != elf.ET_DYN {
4890			t.Errorf("PIE type must be ET_DYN, but %s", f.Type)
4891		}
4892	case "darwin":
4893		f, err := macho.Open(obj)
4894		if err != nil {
4895			t.Fatal(err)
4896		}
4897		defer f.Close()
4898		if f.Flags&macho.FlagDyldLink == 0 {
4899			t.Error("PIE must have DyldLink flag, but not")
4900		}
4901		if f.Flags&macho.FlagPIE == 0 {
4902			t.Error("PIE must have PIE flag, but not")
4903		}
4904	default:
4905		panic("unreachable")
4906	}
4907
4908	out, err := exec.Command(obj).CombinedOutput()
4909	if err != nil {
4910		t.Fatal(err)
4911	}
4912
4913	if string(out) != "hello" {
4914		t.Errorf("got %q; want %q", out, "hello")
4915	}
4916}
4917
4918func TestExecBuildX(t *testing.T) {
4919	tooSlow(t)
4920	if !canCgo {
4921		t.Skip("skipping because cgo not enabled")
4922	}
4923
4924	if runtime.GOOS == "plan9" || runtime.GOOS == "windows" {
4925		t.Skipf("skipping because unix shell is not supported on %s", runtime.GOOS)
4926	}
4927
4928	tg := testgo(t)
4929	defer tg.cleanup()
4930
4931	tg.setenv("GOCACHE", "off")
4932
4933	tg.tempFile("main.go", `package main; import "C"; func main() { print("hello") }`)
4934	src := tg.path("main.go")
4935	obj := tg.path("main")
4936	tg.run("build", "-x", "-o", obj, src)
4937	sh := tg.path("test.sh")
4938	err := ioutil.WriteFile(sh, []byte("set -e\n"+tg.getStderr()), 0666)
4939	if err != nil {
4940		t.Fatal(err)
4941	}
4942
4943	out, err := exec.Command(obj).CombinedOutput()
4944	if err != nil {
4945		t.Fatal(err)
4946	}
4947	if string(out) != "hello" {
4948		t.Fatalf("got %q; want %q", out, "hello")
4949	}
4950
4951	err = os.Remove(obj)
4952	if err != nil {
4953		t.Fatal(err)
4954	}
4955
4956	out, err = exec.Command("/usr/bin/env", "bash", "-x", sh).CombinedOutput()
4957	if err != nil {
4958		t.Fatalf("/bin/sh %s: %v\n%s", sh, err, out)
4959	}
4960	t.Logf("shell output:\n%s", out)
4961
4962	out, err = exec.Command(obj).CombinedOutput()
4963	if err != nil {
4964		t.Fatal(err)
4965	}
4966	if string(out) != "hello" {
4967		t.Fatalf("got %q; want %q", out, "hello")
4968	}
4969}
4970
4971func TestParallelNumber(t *testing.T) {
4972	tooSlow(t)
4973	for _, n := range [...]string{"-1", "0"} {
4974		t.Run(n, func(t *testing.T) {
4975			tg := testgo(t)
4976			defer tg.cleanup()
4977			tg.runFail("test", "-parallel", n, "testdata/standalone_parallel_sub_test.go")
4978			tg.grepBoth("-parallel can only be given", "go test -parallel with N<1 did not error")
4979		})
4980	}
4981}
4982
4983func TestWrongGOOSErrorBeforeLoadError(t *testing.T) {
4984	skipIfGccgo(t, "gccgo assumes cross-compilation is always possible")
4985	tg := testgo(t)
4986	defer tg.cleanup()
4987	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
4988	tg.setenv("GOOS", "windwos")
4989	tg.runFail("build", "exclude")
4990	tg.grepStderr("unsupported GOOS/GOARCH pair", "GOOS=windwos go build exclude did not report 'unsupported GOOS/GOARCH pair'")
4991}
4992
4993func TestUpxCompression(t *testing.T) {
4994	if runtime.GOOS != "linux" || runtime.GOARCH != "amd64" {
4995		t.Skipf("skipping upx test on %s/%s", runtime.GOOS, runtime.GOARCH)
4996	}
4997
4998	out, err := exec.Command("upx", "--version").CombinedOutput()
4999	if err != nil {
5000		t.Skip("skipping because upx is not available")
5001	}
5002
5003	// upx --version prints `upx <version>` in the first line of output:
5004	//   upx 3.94
5005	//   [...]
5006	re := regexp.MustCompile(`([[:digit:]]+)\.([[:digit:]]+)`)
5007	upxVersion := re.FindStringSubmatch(string(out))
5008	if len(upxVersion) != 3 {
5009		t.Errorf("bad upx version string: %s", upxVersion)
5010	}
5011
5012	major, err1 := strconv.Atoi(upxVersion[1])
5013	minor, err2 := strconv.Atoi(upxVersion[2])
5014	if err1 != nil || err2 != nil {
5015		t.Errorf("bad upx version string: %s", upxVersion[0])
5016	}
5017
5018	// Anything below 3.94 is known not to work with go binaries
5019	if (major < 3) || (major == 3 && minor < 94) {
5020		t.Skipf("skipping because upx version %v.%v is too old", major, minor)
5021	}
5022
5023	tg := testgo(t)
5024	defer tg.cleanup()
5025
5026	tg.tempFile("main.go", `package main; import "fmt"; func main() { fmt.Print("hello upx") }`)
5027	src := tg.path("main.go")
5028	obj := tg.path("main")
5029	tg.run("build", "-o", obj, src)
5030
5031	out, err = exec.Command("upx", obj).CombinedOutput()
5032	if err != nil {
5033		t.Logf("executing upx\n%s\n", out)
5034		t.Fatalf("upx failed with %v", err)
5035	}
5036
5037	out, err = exec.Command(obj).CombinedOutput()
5038	if err != nil {
5039		t.Logf("%s", out)
5040		t.Fatalf("running compressed go binary failed with error %s", err)
5041	}
5042	if string(out) != "hello upx" {
5043		t.Fatalf("bad output from compressed go binary:\ngot %q; want %q", out, "hello upx")
5044	}
5045}
5046
5047func TestGOTMPDIR(t *testing.T) {
5048	tg := testgo(t)
5049	defer tg.cleanup()
5050	tg.parallel()
5051	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
5052	tg.makeTempdir()
5053	tg.setenv("GOTMPDIR", tg.tempdir)
5054	tg.setenv("GOCACHE", "off")
5055
5056	// complex/x is a trivial non-main package.
5057	tg.run("build", "-work", "-x", "complex/w")
5058	tg.grepStderr("WORK="+regexp.QuoteMeta(tg.tempdir), "did not work in $GOTMPDIR")
5059}
5060
5061func TestBuildCache(t *testing.T) {
5062	tooSlow(t)
5063	if strings.Contains(os.Getenv("GODEBUG"), "gocacheverify") {
5064		t.Skip("GODEBUG gocacheverify")
5065	}
5066	tg := testgo(t)
5067	defer tg.cleanup()
5068	tg.parallel()
5069	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
5070	tg.makeTempdir()
5071	tg.setenv("GOCACHE", tg.tempdir)
5072
5073	// complex/w is a trivial non-main package.
5074	// It imports nothing, so there should be no Deps.
5075	tg.run("list", "-f={{join .Deps \" \"}}", "complex/w")
5076	tg.grepStdoutNot(".+", "complex/w depends on unexpected packages")
5077
5078	tg.run("build", "-x", "complex/w")
5079	tg.grepStderr(`[\\/]compile|gccgo`, "did not run compiler")
5080
5081	tg.run("build", "-x", "complex/w")
5082	tg.grepStderrNot(`[\\/]compile|gccgo`, "ran compiler incorrectly")
5083
5084	tg.run("build", "-a", "-x", "complex/w")
5085	tg.grepStderr(`[\\/]compile|gccgo`, "did not run compiler with -a")
5086
5087	// complex is a non-trivial main package.
5088	// the link step should not be cached.
5089	tg.run("build", "-o", os.DevNull, "-x", "complex")
5090	tg.grepStderr(`[\\/]link|gccgo`, "did not run linker")
5091
5092	tg.run("build", "-o", os.DevNull, "-x", "complex")
5093	tg.grepStderr(`[\\/]link|gccgo`, "did not run linker")
5094}
5095
5096func TestCacheOutput(t *testing.T) {
5097	// Test that command output is cached and replayed too.
5098	if strings.Contains(os.Getenv("GODEBUG"), "gocacheverify") {
5099		t.Skip("GODEBUG gocacheverify")
5100	}
5101	tg := testgo(t)
5102	defer tg.cleanup()
5103	tg.parallel()
5104	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
5105	tg.makeTempdir()
5106	tg.setenv("GOCACHE", tg.tempdir)
5107
5108	tg.run("build", "-gcflags=-m", "errors")
5109	stdout1 := tg.getStdout()
5110	stderr1 := tg.getStderr()
5111
5112	tg.run("build", "-gcflags=-m", "errors")
5113	stdout2 := tg.getStdout()
5114	stderr2 := tg.getStderr()
5115
5116	if stdout2 != stdout1 || stderr2 != stderr1 {
5117		t.Errorf("cache did not reproduce output:\n\nstdout1:\n%s\n\nstdout2:\n%s\n\nstderr1:\n%s\n\nstderr2:\n%s",
5118			stdout1, stdout2, stderr1, stderr2)
5119	}
5120}
5121
5122func TestCacheListStale(t *testing.T) {
5123	tooSlow(t)
5124	if strings.Contains(os.Getenv("GODEBUG"), "gocacheverify") {
5125		t.Skip("GODEBUG gocacheverify")
5126	}
5127	tg := testgo(t)
5128	defer tg.cleanup()
5129	tg.parallel()
5130	tg.makeTempdir()
5131	tg.setenv("GOCACHE", tg.path("cache"))
5132	tg.tempFile("gopath/src/p/p.go", "package p; import _ \"q\"; func F(){}\n")
5133	tg.tempFile("gopath/src/q/q.go", "package q; func F(){}\n")
5134	tg.tempFile("gopath/src/m/m.go", "package main; import _ \"q\"; func main(){}\n")
5135
5136	tg.setenv("GOPATH", tg.path("gopath"))
5137	tg.run("install", "p", "m")
5138	tg.run("list", "-f={{.ImportPath}} {{.Stale}}", "m", "q", "p")
5139	tg.grepStdout("^m false", "m should not be stale")
5140	tg.grepStdout("^q true", "q should be stale")
5141	tg.grepStdout("^p false", "p should not be stale")
5142}
5143
5144func TestCacheCoverage(t *testing.T) {
5145	tooSlow(t)
5146
5147	if strings.Contains(os.Getenv("GODEBUG"), "gocacheverify") {
5148		t.Skip("GODEBUG gocacheverify")
5149	}
5150
5151	tg := testgo(t)
5152	defer tg.cleanup()
5153	tg.parallel()
5154	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
5155	tg.makeTempdir()
5156
5157	tg.setenv("GOCACHE", tg.path("c1"))
5158	tg.run("test", "-cover", "-short", "strings")
5159	tg.run("test", "-cover", "-short", "math", "strings")
5160}
5161
5162func TestIssue22588(t *testing.T) {
5163	// Don't get confused by stderr coming from tools.
5164	tg := testgo(t)
5165	defer tg.cleanup()
5166	tg.parallel()
5167
5168	if _, err := os.Stat("/usr/bin/time"); err != nil {
5169		t.Skip(err)
5170	}
5171
5172	tg.run("list", "-f={{.Stale}}", "runtime")
5173	tg.run("list", "-toolexec=/usr/bin/time", "-f={{.Stale}}", "runtime")
5174	tg.grepStdout("false", "incorrectly reported runtime as stale")
5175}
5176
5177func TestIssue22531(t *testing.T) {
5178	tooSlow(t)
5179	if strings.Contains(os.Getenv("GODEBUG"), "gocacheverify") {
5180		t.Skip("GODEBUG gocacheverify")
5181	}
5182	tg := testgo(t)
5183	defer tg.cleanup()
5184	tg.parallel()
5185	tg.makeTempdir()
5186	tg.setenv("GOPATH", tg.tempdir)
5187	tg.setenv("GOCACHE", tg.path("cache"))
5188	tg.tempFile("src/m/main.go", "package main /* c1 */; func main() {}\n")
5189	tg.run("install", "-x", "m")
5190	tg.run("list", "-f", "{{.Stale}}", "m")
5191	tg.grepStdout("false", "reported m as stale after install")
5192	tg.run("tool", "buildid", tg.path("bin/m"+exeSuffix))
5193
5194	// The link action ID did not include the full main build ID,
5195	// even though the full main build ID is written into the
5196	// eventual binary. That caused the following install to
5197	// be a no-op, thinking the gofmt binary was up-to-date,
5198	// even though .Stale could see it was not.
5199	tg.tempFile("src/m/main.go", "package main /* c2 */; func main() {}\n")
5200	tg.run("install", "-x", "m")
5201	tg.run("list", "-f", "{{.Stale}}", "m")
5202	tg.grepStdout("false", "reported m as stale after reinstall")
5203	tg.run("tool", "buildid", tg.path("bin/m"+exeSuffix))
5204}
5205
5206func TestIssue22596(t *testing.T) {
5207	tooSlow(t)
5208	if strings.Contains(os.Getenv("GODEBUG"), "gocacheverify") {
5209		t.Skip("GODEBUG gocacheverify")
5210	}
5211	tg := testgo(t)
5212	defer tg.cleanup()
5213	tg.parallel()
5214	tg.makeTempdir()
5215	tg.setenv("GOCACHE", tg.path("cache"))
5216	tg.tempFile("gopath1/src/p/p.go", "package p; func F(){}\n")
5217	tg.tempFile("gopath2/src/p/p.go", "package p; func F(){}\n")
5218
5219	tg.setenv("GOPATH", tg.path("gopath1"))
5220	tg.run("list", "-f={{.Target}}", "p")
5221	target1 := strings.TrimSpace(tg.getStdout())
5222	tg.run("install", "p")
5223	tg.wantNotStale("p", "", "p stale after install")
5224
5225	tg.setenv("GOPATH", tg.path("gopath2"))
5226	tg.run("list", "-f={{.Target}}", "p")
5227	target2 := strings.TrimSpace(tg.getStdout())
5228	tg.must(os.MkdirAll(filepath.Dir(target2), 0777))
5229	tg.must(copyFile(target1, target2, 0666))
5230	tg.wantStale("p", "build ID mismatch", "p not stale after copy from gopath1")
5231	tg.run("install", "p")
5232	tg.wantNotStale("p", "", "p stale after install2")
5233}
5234
5235func TestTestCache(t *testing.T) {
5236	tooSlow(t)
5237
5238	if strings.Contains(os.Getenv("GODEBUG"), "gocacheverify") {
5239		t.Skip("GODEBUG gocacheverify")
5240	}
5241	tg := testgo(t)
5242	defer tg.cleanup()
5243	tg.parallel()
5244	tg.makeTempdir()
5245	tg.setenv("GOPATH", tg.tempdir)
5246	tg.setenv("GOCACHE", tg.path("cache"))
5247
5248	if runtime.Compiler != "gccgo" {
5249		// timeout here should not affect result being cached
5250		// or being retrieved later.
5251		tg.run("test", "-x", "-timeout=10s", "errors")
5252		tg.grepStderr(`[\\/](compile|gccgo) `, "did not run compiler")
5253		tg.grepStderr(`[\\/](link|gccgo) `, "did not run linker")
5254		tg.grepStderr(`errors\.test`, "did not run test")
5255
5256		tg.run("test", "-x", "errors")
5257		tg.grepStdout(`ok  \terrors\t\(cached\)`, "did not report cached result")
5258		tg.grepStderrNot(`[\\/](compile|gccgo) `, "incorrectly ran compiler")
5259		tg.grepStderrNot(`[\\/](link|gccgo) `, "incorrectly ran linker")
5260		tg.grepStderrNot(`errors\.test`, "incorrectly ran test")
5261		tg.grepStderrNot("DO NOT USE", "poisoned action status leaked")
5262
5263		// Even very low timeouts do not disqualify cached entries.
5264		tg.run("test", "-timeout=1ns", "-x", "errors")
5265		tg.grepStderrNot(`errors\.test`, "incorrectly ran test")
5266
5267		tg.run("clean", "-testcache")
5268		tg.run("test", "-x", "errors")
5269		tg.grepStderr(`errors\.test`, "did not run test")
5270	}
5271
5272	// The -p=1 in the commands below just makes the -x output easier to read.
5273
5274	t.Log("\n\nINITIAL\n\n")
5275
5276	tg.tempFile("src/p1/p1.go", "package p1\nvar X =  1\n")
5277	tg.tempFile("src/p2/p2.go", "package p2\nimport _ \"p1\"\nvar X = 1\n")
5278	tg.tempFile("src/t/t1/t1_test.go", "package t\nimport \"testing\"\nfunc Test1(*testing.T) {}\n")
5279	tg.tempFile("src/t/t2/t2_test.go", "package t\nimport _ \"p1\"\nimport \"testing\"\nfunc Test2(*testing.T) {}\n")
5280	tg.tempFile("src/t/t3/t3_test.go", "package t\nimport \"p1\"\nimport \"testing\"\nfunc Test3(t *testing.T) {t.Log(p1.X)}\n")
5281	tg.tempFile("src/t/t4/t4_test.go", "package t\nimport \"p2\"\nimport \"testing\"\nfunc Test4(t *testing.T) {t.Log(p2.X)}")
5282	tg.run("test", "-x", "-v", "-short", "t/...")
5283
5284	t.Log("\n\nREPEAT\n\n")
5285
5286	tg.run("test", "-x", "-v", "-short", "t/...")
5287	tg.grepStdout(`ok  \tt/t1\t\(cached\)`, "did not cache t1")
5288	tg.grepStdout(`ok  \tt/t2\t\(cached\)`, "did not cache t2")
5289	tg.grepStdout(`ok  \tt/t3\t\(cached\)`, "did not cache t3")
5290	tg.grepStdout(`ok  \tt/t4\t\(cached\)`, "did not cache t4")
5291	tg.grepStderrNot(`[\\/](compile|gccgo) `, "incorrectly ran compiler")
5292	tg.grepStderrNot(`[\\/](link|gccgo) `, "incorrectly ran linker")
5293	tg.grepStderrNot(`p[0-9]\.test`, "incorrectly ran test")
5294
5295	t.Log("\n\nCOMMENT\n\n")
5296
5297	// Changing the program text without affecting the compiled package
5298	// should result in the package being rebuilt but nothing more.
5299	tg.tempFile("src/p1/p1.go", "package p1\nvar X = 01\n")
5300	tg.run("test", "-p=1", "-x", "-v", "-short", "t/...")
5301	tg.grepStdout(`ok  \tt/t1\t\(cached\)`, "did not cache t1")
5302	tg.grepStdout(`ok  \tt/t2\t\(cached\)`, "did not cache t2")
5303	tg.grepStdout(`ok  \tt/t3\t\(cached\)`, "did not cache t3")
5304	tg.grepStdout(`ok  \tt/t4\t\(cached\)`, "did not cache t4")
5305	tg.grepStderrNot(`([\\/](compile|gccgo) ).*t[0-9]_test\.go`, "incorrectly ran compiler")
5306	tg.grepStderrNot(`[\\/](link|gccgo) `, "incorrectly ran linker")
5307	tg.grepStderrNot(`t[0-9]\.test.*test\.short`, "incorrectly ran test")
5308
5309	t.Log("\n\nCHANGE\n\n")
5310
5311	// Changing the actual package should have limited effects.
5312	tg.tempFile("src/p1/p1.go", "package p1\nvar X = 02\n")
5313	tg.run("test", "-p=1", "-x", "-v", "-short", "t/...")
5314
5315	// p2 should have been rebuilt.
5316	tg.grepStderr(`([\\/]compile|gccgo).*p2.go`, "did not recompile p2")
5317
5318	// t1 does not import anything, should not have been rebuilt.
5319	tg.grepStderrNot(`([\\/]compile|gccgo).*t1_test.go`, "incorrectly recompiled t1")
5320	tg.grepStderrNot(`([\\/]link|gccgo).*t1_test`, "incorrectly relinked t1_test")
5321	tg.grepStdout(`ok  \tt/t1\t\(cached\)`, "did not cache t/t1")
5322
5323	// t2 imports p1 and must be rebuilt and relinked,
5324	// but the change should not have any effect on the test binary,
5325	// so the test should not have been rerun.
5326	tg.grepStderr(`([\\/]compile|gccgo).*t2_test.go`, "did not recompile t2")
5327	tg.grepStderr(`([\\/]link|gccgo).*t2\.test`, "did not relink t2_test")
5328	// This check does not currently work with gccgo, as garbage
5329	// collection of unused variables is not turned on by default.
5330	if runtime.Compiler != "gccgo" {
5331		tg.grepStdout(`ok  \tt/t2\t\(cached\)`, "did not cache t/t2")
5332	}
5333
5334	// t3 imports p1, and changing X changes t3's test binary.
5335	tg.grepStderr(`([\\/]compile|gccgo).*t3_test.go`, "did not recompile t3")
5336	tg.grepStderr(`([\\/]link|gccgo).*t3\.test`, "did not relink t3_test")
5337	tg.grepStderr(`t3\.test.*-test.short`, "did not rerun t3_test")
5338	tg.grepStdoutNot(`ok  \tt/t3\t\(cached\)`, "reported cached t3_test result")
5339
5340	// t4 imports p2, but p2 did not change, so t4 should be relinked, not recompiled,
5341	// and not rerun.
5342	tg.grepStderrNot(`([\\/]compile|gccgo).*t4_test.go`, "incorrectly recompiled t4")
5343	tg.grepStderr(`([\\/]link|gccgo).*t4\.test`, "did not relink t4_test")
5344	// This check does not currently work with gccgo, as garbage
5345	// collection of unused variables is not turned on by default.
5346	if runtime.Compiler != "gccgo" {
5347		tg.grepStdout(`ok  \tt/t4\t\(cached\)`, "did not cache t/t4")
5348	}
5349}
5350
5351func TestTestCacheInputs(t *testing.T) {
5352	tooSlow(t)
5353
5354	if strings.Contains(os.Getenv("GODEBUG"), "gocacheverify") {
5355		t.Skip("GODEBUG gocacheverify")
5356	}
5357	tg := testgo(t)
5358	defer tg.cleanup()
5359	tg.parallel()
5360	tg.makeTempdir()
5361	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
5362	tg.setenv("GOCACHE", tg.path("cache"))
5363
5364	defer os.Remove(filepath.Join(tg.pwd(), "testdata/src/testcache/file.txt"))
5365	defer os.Remove(filepath.Join(tg.pwd(), "testdata/src/testcache/script.sh"))
5366	tg.must(ioutil.WriteFile(filepath.Join(tg.pwd(), "testdata/src/testcache/file.txt"), []byte("x"), 0644))
5367	old := time.Now().Add(-1 * time.Minute)
5368	tg.must(os.Chtimes(filepath.Join(tg.pwd(), "testdata/src/testcache/file.txt"), old, old))
5369	info, err := os.Stat(filepath.Join(tg.pwd(), "testdata/src/testcache/file.txt"))
5370	if err != nil {
5371		t.Fatal(err)
5372	}
5373	t.Logf("file.txt: old=%v, info.ModTime=%v", old, info.ModTime()) // help debug when Chtimes lies about succeeding
5374	tg.setenv("TESTKEY", "x")
5375
5376	tg.must(ioutil.WriteFile(filepath.Join(tg.pwd(), "testdata/src/testcache/script.sh"), []byte("#!/bin/sh\nexit 0\n"), 0755))
5377	tg.must(os.Chtimes(filepath.Join(tg.pwd(), "testdata/src/testcache/script.sh"), old, old))
5378
5379	tg.run("test", "testcache")
5380	tg.run("test", "testcache")
5381	tg.grepStdout(`\(cached\)`, "did not cache")
5382
5383	tg.setenv("TESTKEY", "y")
5384	tg.run("test", "testcache")
5385	tg.grepStdoutNot(`\(cached\)`, "did not notice env var change")
5386	tg.run("test", "testcache")
5387	tg.grepStdout(`\(cached\)`, "did not cache")
5388
5389	tg.run("test", "testcache", "-run=FileSize")
5390	tg.run("test", "testcache", "-run=FileSize")
5391	tg.grepStdout(`\(cached\)`, "did not cache")
5392	tg.must(ioutil.WriteFile(filepath.Join(tg.pwd(), "testdata/src/testcache/file.txt"), []byte("xxx"), 0644))
5393	tg.run("test", "testcache", "-run=FileSize")
5394	tg.grepStdoutNot(`\(cached\)`, "did not notice file size change")
5395	tg.run("test", "testcache", "-run=FileSize")
5396	tg.grepStdout(`\(cached\)`, "did not cache")
5397
5398	tg.run("test", "testcache", "-run=Chdir")
5399	tg.run("test", "testcache", "-run=Chdir")
5400	tg.grepStdout(`\(cached\)`, "did not cache")
5401	tg.must(ioutil.WriteFile(filepath.Join(tg.pwd(), "testdata/src/testcache/file.txt"), []byte("xxxxx"), 0644))
5402	tg.run("test", "testcache", "-run=Chdir")
5403	tg.grepStdoutNot(`\(cached\)`, "did not notice file size change")
5404	tg.run("test", "testcache", "-run=Chdir")
5405	tg.grepStdout(`\(cached\)`, "did not cache")
5406
5407	tg.must(os.Chtimes(filepath.Join(tg.pwd(), "testdata/src/testcache/file.txt"), old, old))
5408	tg.run("test", "testcache", "-run=FileContent")
5409	tg.run("test", "testcache", "-run=FileContent")
5410	tg.grepStdout(`\(cached\)`, "did not cache")
5411	tg.must(ioutil.WriteFile(filepath.Join(tg.pwd(), "testdata/src/testcache/file.txt"), []byte("yyy"), 0644))
5412	old2 := old.Add(10 * time.Second)
5413	tg.must(os.Chtimes(filepath.Join(tg.pwd(), "testdata/src/testcache/file.txt"), old2, old2))
5414	tg.run("test", "testcache", "-run=FileContent")
5415	tg.grepStdoutNot(`\(cached\)`, "did not notice file content change")
5416	tg.run("test", "testcache", "-run=FileContent")
5417	tg.grepStdout(`\(cached\)`, "did not cache")
5418
5419	tg.run("test", "testcache", "-run=DirList")
5420	tg.run("test", "testcache", "-run=DirList")
5421	tg.grepStdout(`\(cached\)`, "did not cache")
5422	tg.must(os.Remove(filepath.Join(tg.pwd(), "testdata/src/testcache/file.txt")))
5423	tg.run("test", "testcache", "-run=DirList")
5424	tg.grepStdoutNot(`\(cached\)`, "did not notice directory change")
5425	tg.run("test", "testcache", "-run=DirList")
5426	tg.grepStdout(`\(cached\)`, "did not cache")
5427
5428	tg.tempFile("file.txt", "")
5429	tg.must(ioutil.WriteFile(filepath.Join(tg.pwd(), "testdata/src/testcache/testcachetmp_test.go"), []byte(`package testcache
5430
5431		import (
5432			"os"
5433			"testing"
5434		)
5435
5436		func TestExternalFile(t *testing.T) {
5437			os.Open(`+fmt.Sprintf("%q", tg.path("file.txt"))+`)
5438			_, err := os.Stat(`+fmt.Sprintf("%q", tg.path("file.txt"))+`)
5439			if err != nil {
5440				t.Fatal(err)
5441			}
5442		}
5443	`), 0666))
5444	defer os.Remove(filepath.Join(tg.pwd(), "testdata/src/testcache/testcachetmp_test.go"))
5445	tg.run("test", "testcache", "-run=ExternalFile")
5446	tg.run("test", "testcache", "-run=ExternalFile")
5447	tg.grepStdout(`\(cached\)`, "did not cache")
5448	tg.must(os.Remove(filepath.Join(tg.tempdir, "file.txt")))
5449	tg.run("test", "testcache", "-run=ExternalFile")
5450	tg.grepStdout(`\(cached\)`, "did not cache")
5451
5452	switch runtime.GOOS {
5453	case "nacl", "plan9", "windows":
5454		// no shell scripts
5455	default:
5456		tg.run("test", "testcache", "-run=Exec")
5457		tg.run("test", "testcache", "-run=Exec")
5458		tg.grepStdout(`\(cached\)`, "did not cache")
5459		tg.must(os.Chtimes(filepath.Join(tg.pwd(), "testdata/src/testcache/script.sh"), old2, old2))
5460		tg.run("test", "testcache", "-run=Exec")
5461		tg.grepStdoutNot(`\(cached\)`, "did not notice script change")
5462		tg.run("test", "testcache", "-run=Exec")
5463		tg.grepStdout(`\(cached\)`, "did not cache")
5464	}
5465}
5466
5467func TestNoCache(t *testing.T) {
5468	switch runtime.GOOS {
5469	case "windows":
5470		t.Skipf("no unwritable directories on %s", runtime.GOOS)
5471	}
5472	if os.Getuid() == 0 {
5473		t.Skip("skipping test because running as root")
5474	}
5475
5476	tg := testgo(t)
5477	defer tg.cleanup()
5478	tg.parallel()
5479	tg.tempFile("triv.go", `package main; func main() {}`)
5480	tg.must(os.MkdirAll(tg.path("unwritable"), 0555))
5481	home := "HOME"
5482	if runtime.GOOS == "plan9" {
5483		home = "home"
5484	}
5485	tg.setenv(home, tg.path(filepath.Join("unwritable", "home")))
5486	tg.unsetenv("GOCACHE")
5487	tg.run("build", "-o", tg.path("triv"), tg.path("triv.go"))
5488	tg.grepStderr("disabling cache", "did not disable cache")
5489}
5490
5491func TestTestVet(t *testing.T) {
5492	tooSlow(t)
5493	tg := testgo(t)
5494	defer tg.cleanup()
5495	tg.parallel()
5496
5497	tg.tempFile("p1_test.go", `
5498		package p
5499		import "testing"
5500		func Test(t *testing.T) {
5501			t.Logf("%d") // oops
5502		}
5503	`)
5504
5505	tg.runFail("test", tg.path("p1_test.go"))
5506	tg.grepStderr(`Logf format %d`, "did not diagnose bad Logf")
5507	tg.run("test", "-vet=off", tg.path("p1_test.go"))
5508	tg.grepStdout(`^ok`, "did not print test summary")
5509
5510	tg.tempFile("p1.go", `
5511		package p
5512		import "fmt"
5513		func F() {
5514			fmt.Printf("%d") // oops
5515		}
5516	`)
5517	tg.runFail("test", tg.path("p1.go"))
5518	tg.grepStderr(`Printf format %d`, "did not diagnose bad Printf")
5519	tg.run("test", "-x", "-vet=shift", tg.path("p1.go"))
5520	tg.grepStderr(`[\\/]vet.*-shift`, "did not run vet with -shift")
5521	tg.grepStdout(`\[no test files\]`, "did not print test summary")
5522	tg.run("test", "-vet=off", tg.path("p1.go"))
5523	tg.grepStdout(`\[no test files\]`, "did not print test summary")
5524
5525	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
5526	tg.run("test", "vetcycle") // must not fail; #22890
5527
5528	tg.runFail("test", "vetfail/...")
5529	tg.grepStderr(`Printf format %d`, "did not diagnose bad Printf")
5530	tg.grepStdout(`ok\s+vetfail/p2`, "did not run vetfail/p2")
5531}
5532
5533func TestTestRebuild(t *testing.T) {
5534	tg := testgo(t)
5535	defer tg.cleanup()
5536	tg.parallel()
5537
5538	// golang.org/issue/23701.
5539	// b_test imports b with augmented method from export_test.go.
5540	// b_test also imports a, which imports b.
5541	// Must not accidentally see un-augmented b propagate through a to b_test.
5542	tg.tempFile("src/a/a.go", `package a
5543		import "b"
5544		type Type struct{}
5545		func (*Type) M() b.T {return 0}
5546	`)
5547	tg.tempFile("src/b/b.go", `package b
5548		type T int
5549		type I interface {M() T}
5550	`)
5551	tg.tempFile("src/b/export_test.go", `package b
5552		func (*T) Method() *T { return nil }
5553	`)
5554	tg.tempFile("src/b/b_test.go", `package b_test
5555		import (
5556			"testing"
5557			"a"
5558			. "b"
5559		)
5560		func TestBroken(t *testing.T) {
5561			x := new(T)
5562			x.Method()
5563			_ = new(a.Type)
5564		}
5565	`)
5566
5567	tg.setenv("GOPATH", tg.path("."))
5568	tg.run("test", "b")
5569}
5570
5571func TestInstallDeps(t *testing.T) {
5572	tooSlow(t)
5573	tg := testgo(t)
5574	defer tg.cleanup()
5575	tg.parallel()
5576	tg.makeTempdir()
5577	tg.setenv("GOPATH", tg.tempdir)
5578
5579	tg.tempFile("src/p1/p1.go", "package p1\nvar X =  1\n")
5580	tg.tempFile("src/p2/p2.go", "package p2\nimport _ \"p1\"\n")
5581	tg.tempFile("src/main1/main.go", "package main\nimport _ \"p2\"\nfunc main() {}\n")
5582
5583	tg.run("list", "-f={{.Target}}", "p1")
5584	p1 := strings.TrimSpace(tg.getStdout())
5585	tg.run("list", "-f={{.Target}}", "p2")
5586	p2 := strings.TrimSpace(tg.getStdout())
5587	tg.run("list", "-f={{.Target}}", "main1")
5588	main1 := strings.TrimSpace(tg.getStdout())
5589
5590	tg.run("install", "main1")
5591
5592	tg.mustExist(main1)
5593	tg.mustNotExist(p2)
5594	tg.mustNotExist(p1)
5595
5596	tg.run("install", "p2")
5597	tg.mustExist(p2)
5598	tg.mustNotExist(p1)
5599
5600	// don't let install -i overwrite runtime
5601	tg.wantNotStale("runtime", "", "must be non-stale before install -i")
5602
5603	tg.run("install", "-i", "main1")
5604	tg.mustExist(p1)
5605	tg.must(os.Remove(p1))
5606
5607	tg.run("install", "-i", "p2")
5608	tg.mustExist(p1)
5609}
5610
5611func TestFmtLoadErrors(t *testing.T) {
5612	tg := testgo(t)
5613	defer tg.cleanup()
5614	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
5615	tg.runFail("fmt", "does-not-exist")
5616	tg.run("fmt", "-n", "exclude")
5617}
5618
5619func TestRelativePkgdir(t *testing.T) {
5620	tooSlow(t)
5621	tg := testgo(t)
5622	defer tg.cleanup()
5623	tg.makeTempdir()
5624	tg.setenv("GOCACHE", "off")
5625	tg.cd(tg.tempdir)
5626
5627	tg.run("build", "-i", "-pkgdir=.", "runtime")
5628}
5629
5630func TestGcflagsPatterns(t *testing.T) {
5631	skipIfGccgo(t, "gccgo has no standard packages")
5632	tg := testgo(t)
5633	defer tg.cleanup()
5634	tg.setenv("GOPATH", "")
5635	tg.setenv("GOCACHE", "off")
5636
5637	tg.run("build", "-n", "-v", "-gcflags= \t\r\n -e", "fmt")
5638	tg.grepStderr("^# fmt", "did not rebuild fmt")
5639	tg.grepStderrNot("^# reflect", "incorrectly rebuilt reflect")
5640
5641	tg.run("build", "-n", "-v", "-gcflags=-e", "fmt", "reflect")
5642	tg.grepStderr("^# fmt", "did not rebuild fmt")
5643	tg.grepStderr("^# reflect", "did not rebuild reflect")
5644	tg.grepStderrNot("^# runtime", "incorrectly rebuilt runtime")
5645
5646	tg.run("build", "-n", "-x", "-v", "-gcflags= \t\r\n reflect \t\r\n = \t\r\n -N", "fmt")
5647	tg.grepStderr("^# fmt", "did not rebuild fmt")
5648	tg.grepStderr("^# reflect", "did not rebuild reflect")
5649	tg.grepStderr("compile.* -N .*-p reflect", "did not build reflect with -N flag")
5650	tg.grepStderrNot("compile.* -N .*-p fmt", "incorrectly built fmt with -N flag")
5651
5652	tg.run("test", "-c", "-n", "-gcflags=-N", "-ldflags=-X=x.y=z", "strings")
5653	tg.grepStderr("compile.* -N .*compare_test.go", "did not compile strings_test package with -N flag")
5654	tg.grepStderr("link.* -X=x.y=z", "did not link strings.test binary with -X flag")
5655
5656	tg.run("test", "-c", "-n", "-gcflags=strings=-N", "-ldflags=strings=-X=x.y=z", "strings")
5657	tg.grepStderr("compile.* -N .*compare_test.go", "did not compile strings_test package with -N flag")
5658	tg.grepStderr("link.* -X=x.y=z", "did not link strings.test binary with -X flag")
5659}
5660
5661func TestGoTestMinusN(t *testing.T) {
5662	// Intent here is to verify that 'go test -n' works without crashing.
5663	// This reuses flag_test.go, but really any test would do.
5664	tg := testgo(t)
5665	defer tg.cleanup()
5666	tg.run("test", "testdata/flag_test.go", "-n", "-args", "-v=7")
5667}
5668
5669func TestGoTestJSON(t *testing.T) {
5670	skipIfGccgo(t, "gccgo does not have standard packages")
5671	tooSlow(t)
5672
5673	tg := testgo(t)
5674	defer tg.cleanup()
5675	tg.parallel()
5676	tg.makeTempdir()
5677	tg.setenv("GOCACHE", tg.tempdir)
5678	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
5679
5680	// It would be nice to test that the output is interlaced
5681	// but it seems to be impossible to do that in a short test
5682	// that isn't also flaky. Just check that we get JSON output.
5683	tg.run("test", "-json", "-short", "-v", "errors", "empty/pkg", "skipper")
5684	tg.grepStdout(`"Package":"errors"`, "did not see JSON output")
5685	tg.grepStdout(`"Action":"run"`, "did not see JSON output")
5686
5687	tg.grepStdout(`"Action":"output","Package":"empty/pkg","Output":".*no test files`, "did not see no test files print")
5688	tg.grepStdout(`"Action":"skip","Package":"empty/pkg"`, "did not see skip")
5689
5690	tg.grepStdout(`"Action":"output","Package":"skipper","Test":"Test","Output":"--- SKIP:`, "did not see SKIP output")
5691	tg.grepStdout(`"Action":"skip","Package":"skipper","Test":"Test"`, "did not see skip result for Test")
5692
5693	tg.run("test", "-json", "-short", "-v", "errors")
5694	tg.grepStdout(`"Action":"output","Package":"errors","Output":".*\(cached\)`, "did not see no cached output")
5695
5696	tg.run("test", "-json", "-bench=NONE", "-short", "-v", "errors")
5697	tg.grepStdout(`"Package":"errors"`, "did not see JSON output")
5698	tg.grepStdout(`"Action":"run"`, "did not see JSON output")
5699
5700	tg.run("test", "-o", tg.path("errors.test.exe"), "-c", "errors")
5701	tg.run("tool", "test2json", "-p", "errors", tg.path("errors.test.exe"), "-test.v", "-test.short")
5702	tg.grepStdout(`"Package":"errors"`, "did not see JSON output")
5703	tg.grepStdout(`"Action":"run"`, "did not see JSON output")
5704	tg.grepStdout(`\{"Action":"pass","Package":"errors"\}`, "did not see final pass")
5705}
5706
5707func TestFailFast(t *testing.T) {
5708	tooSlow(t)
5709	tg := testgo(t)
5710	defer tg.cleanup()
5711
5712	tests := []struct {
5713		run      string
5714		failfast bool
5715		nfail    int
5716	}{
5717		{"TestFailingA", true, 1},
5718		{"TestFailing[AB]", true, 1},
5719		{"TestFailing[AB]", false, 2},
5720		// mix with non-failing tests:
5721		{"TestA|TestFailing[AB]", true, 1},
5722		{"TestA|TestFailing[AB]", false, 2},
5723		// mix with parallel tests:
5724		{"TestFailingB|TestParallelFailingA", true, 2},
5725		{"TestFailingB|TestParallelFailingA", false, 2},
5726		{"TestFailingB|TestParallelFailing[AB]", true, 3},
5727		{"TestFailingB|TestParallelFailing[AB]", false, 3},
5728		// mix with parallel sub-tests
5729		{"TestFailingB|TestParallelFailing[AB]|TestParallelFailingSubtestsA", true, 3},
5730		{"TestFailingB|TestParallelFailing[AB]|TestParallelFailingSubtestsA", false, 5},
5731		{"TestParallelFailingSubtestsA", true, 1},
5732		// only parallels:
5733		{"TestParallelFailing[AB]", false, 2},
5734		// non-parallel subtests:
5735		{"TestFailingSubtestsA", true, 1},
5736		{"TestFailingSubtestsA", false, 2},
5737	}
5738
5739	for _, tt := range tests {
5740		t.Run(tt.run, func(t *testing.T) {
5741			tg.runFail("test", "./testdata/src/failfast_test.go", "-run="+tt.run, "-failfast="+strconv.FormatBool(tt.failfast))
5742
5743			nfail := strings.Count(tg.getStdout(), "FAIL - ")
5744
5745			if nfail != tt.nfail {
5746				t.Errorf("go test -run=%s -failfast=%t printed %d FAILs, want %d", tt.run, tt.failfast, nfail, tt.nfail)
5747			}
5748		})
5749	}
5750}
5751
5752// Issue 22986.
5753func TestImportPath(t *testing.T) {
5754	tooSlow(t)
5755	tg := testgo(t)
5756	defer tg.cleanup()
5757	tg.parallel()
5758
5759	tg.tempFile("src/a/a.go", `
5760package main
5761
5762import (
5763	"log"
5764	p "a/p-1.0"
5765)
5766
5767func main() {
5768	if !p.V {
5769		log.Fatal("false")
5770	}
5771}`)
5772
5773	tg.tempFile("src/a/a_test.go", `
5774package main_test
5775
5776import (
5777	p "a/p-1.0"
5778	"testing"
5779)
5780
5781func TestV(t *testing.T) {
5782	if !p.V {
5783		t.Fatal("false")
5784	}
5785}`)
5786
5787	tg.tempFile("src/a/p-1.0/p.go", `
5788package p
5789
5790var V = true
5791
5792func init() {}
5793`)
5794
5795	tg.setenv("GOPATH", tg.path("."))
5796	tg.run("build", "-o", tg.path("a.exe"), "a")
5797	tg.run("test", "a")
5798}
5799
5800// Issue 23150.
5801func TestCpuprofileTwice(t *testing.T) {
5802	tg := testgo(t)
5803	defer tg.cleanup()
5804	tg.parallel()
5805	tg.tempFile("prof/src/x/x_test.go", `
5806		package x_test
5807		import (
5808			"testing"
5809			"time"
5810		)
5811		func TestSleep(t *testing.T) { time.Sleep(10 * time.Millisecond) }`)
5812	tg.setenv("GOPATH", tg.path("prof"))
5813	bin := tg.path("x.test")
5814	out := tg.path("cpu.out")
5815	tg.run("test", "-o="+bin, "-cpuprofile="+out, "x")
5816	tg.must(os.Remove(out))
5817	tg.run("test", "-o="+bin, "-cpuprofile="+out, "x")
5818	tg.mustExist(out)
5819}
5820
5821// Issue 23694.
5822func TestAtomicCoverpkgAll(t *testing.T) {
5823	skipIfGccgo(t, "gccgo has no cover tool")
5824	tg := testgo(t)
5825	defer tg.cleanup()
5826	tg.parallel()
5827
5828	tg.tempFile("src/x/x.go", `package x; import _ "sync/atomic"; func F() {}`)
5829	tg.tempFile("src/x/x_test.go", `package x; import "testing"; func TestF(t *testing.T) { F() }`)
5830	tg.setenv("GOPATH", tg.path("."))
5831	tg.run("test", "-coverpkg=all", "-covermode=atomic", "x")
5832	if canRace {
5833		tg.run("test", "-coverpkg=all", "-race", "x")
5834	}
5835}
5836
5837// Issue 23882.
5838func TestCoverpkgAllRuntime(t *testing.T) {
5839	skipIfGccgo(t, "gccgo has no cover tool")
5840	tg := testgo(t)
5841	defer tg.cleanup()
5842	tg.parallel()
5843
5844	tg.tempFile("src/x/x.go", `package x; import _ "runtime"; func F() {}`)
5845	tg.tempFile("src/x/x_test.go", `package x; import "testing"; func TestF(t *testing.T) { F() }`)
5846	tg.setenv("GOPATH", tg.path("."))
5847	tg.run("test", "-coverpkg=all", "x")
5848	if canRace {
5849		tg.run("test", "-coverpkg=all", "-race", "x")
5850	}
5851}
5852
5853func TestBadCommandLines(t *testing.T) {
5854	tg := testgo(t)
5855	defer tg.cleanup()
5856
5857	tg.tempFile("src/x/x.go", "package x\n")
5858	tg.setenv("GOPATH", tg.path("."))
5859
5860	tg.run("build", "x")
5861
5862	tg.tempFile("src/x/@y.go", "package x\n")
5863	tg.runFail("build", "x")
5864	tg.grepStderr("invalid input file name \"@y.go\"", "did not reject @y.go")
5865	tg.must(os.Remove(tg.path("src/x/@y.go")))
5866
5867	tg.tempFile("src/x/-y.go", "package x\n")
5868	tg.runFail("build", "x")
5869	tg.grepStderr("invalid input file name \"-y.go\"", "did not reject -y.go")
5870	tg.must(os.Remove(tg.path("src/x/-y.go")))
5871
5872	if runtime.Compiler == "gccgo" {
5873		tg.runFail("build", "-gccgoflags=all=@x", "x")
5874	} else {
5875		tg.runFail("build", "-gcflags=all=@x", "x")
5876	}
5877	tg.grepStderr("invalid command-line argument @x in command", "did not reject @x during exec")
5878
5879	tg.tempFile("src/@x/x.go", "package x\n")
5880	tg.setenv("GOPATH", tg.path("."))
5881	tg.runFail("build", "@x")
5882	tg.grepStderr("invalid input directory name \"@x\"", "did not reject @x directory")
5883
5884	tg.tempFile("src/@x/y/y.go", "package y\n")
5885	tg.setenv("GOPATH", tg.path("."))
5886	tg.runFail("build", "@x/y")
5887	tg.grepStderr("invalid import path \"@x/y\"", "did not reject @x/y import path")
5888
5889	tg.tempFile("src/-x/x.go", "package x\n")
5890	tg.setenv("GOPATH", tg.path("."))
5891	tg.runFail("build", "--", "-x")
5892	tg.grepStderr("invalid input directory name \"-x\"", "did not reject -x directory")
5893
5894	tg.tempFile("src/-x/y/y.go", "package y\n")
5895	tg.setenv("GOPATH", tg.path("."))
5896	tg.runFail("build", "--", "-x/y")
5897	tg.grepStderr("invalid import path \"-x/y\"", "did not reject -x/y import path")
5898}
5899
5900func TestBadCgoDirectives(t *testing.T) {
5901	if !canCgo {
5902		t.Skip("no cgo")
5903	}
5904	tg := testgo(t)
5905	defer tg.cleanup()
5906
5907	tg.tempFile("src/x/x.go", "package x\n")
5908	tg.setenv("GOPATH", tg.path("."))
5909
5910	if runtime.Compiler == "gc" {
5911		tg.tempFile("src/x/x.go", `package x
5912
5913			//go:cgo_ldflag "-fplugin=foo.so"
5914
5915			import "C"
5916		`)
5917		tg.runFail("build", "x")
5918		tg.grepStderr("//go:cgo_ldflag .* only allowed in cgo-generated code", "did not reject //go:cgo_ldflag directive")
5919	}
5920
5921	tg.must(os.Remove(tg.path("src/x/x.go")))
5922	tg.runFail("build", "x")
5923	tg.grepStderr("no Go files", "did not report missing source code")
5924	tg.tempFile("src/x/_cgo_yy.go", `package x
5925
5926		//go:cgo_ldflag "-fplugin=foo.so"
5927
5928		import "C"
5929	`)
5930	tg.runFail("build", "x")
5931	tg.grepStderr("no Go files", "did not report missing source code") // _* files are ignored...
5932
5933	if runtime.Compiler == "gc" {
5934		tg.runFail("build", tg.path("src/x/_cgo_yy.go")) // ... but if forced, the comment is rejected
5935		// Actually, today there is a separate issue that _ files named
5936		// on the command-line are ignored. Once that is fixed,
5937		// we want to see the cgo_ldflag error.
5938		tg.grepStderr("//go:cgo_ldflag only allowed in cgo-generated code|no Go files", "did not reject //go:cgo_ldflag directive")
5939	}
5940
5941	tg.must(os.Remove(tg.path("src/x/_cgo_yy.go")))
5942
5943	tg.tempFile("src/x/x.go", "package x\n")
5944	tg.tempFile("src/x/y.go", `package x
5945		// #cgo CFLAGS: -fplugin=foo.so
5946		import "C"
5947	`)
5948	tg.runFail("build", "x")
5949	tg.grepStderr("invalid flag in #cgo CFLAGS: -fplugin=foo.so", "did not reject -fplugin")
5950
5951	tg.tempFile("src/x/y.go", `package x
5952		// #cgo CFLAGS: -Ibar -fplugin=foo.so
5953		import "C"
5954	`)
5955	tg.runFail("build", "x")
5956	tg.grepStderr("invalid flag in #cgo CFLAGS: -fplugin=foo.so", "did not reject -fplugin")
5957
5958	tg.tempFile("src/x/y.go", `package x
5959		// #cgo pkg-config: -foo
5960		import "C"
5961	`)
5962	tg.runFail("build", "x")
5963	tg.grepStderr("invalid pkg-config package name: -foo", "did not reject pkg-config: -foo")
5964
5965	tg.tempFile("src/x/y.go", `package x
5966		// #cgo pkg-config: @foo
5967		import "C"
5968	`)
5969	tg.runFail("build", "x")
5970	tg.grepStderr("invalid pkg-config package name: @foo", "did not reject pkg-config: -foo")
5971
5972	tg.tempFile("src/x/y.go", `package x
5973		// #cgo CFLAGS: @foo
5974		import "C"
5975	`)
5976	tg.runFail("build", "x")
5977	tg.grepStderr("invalid flag in #cgo CFLAGS: @foo", "did not reject @foo flag")
5978
5979	tg.tempFile("src/x/y.go", `package x
5980		// #cgo CFLAGS: -D
5981		import "C"
5982	`)
5983	tg.runFail("build", "x")
5984	tg.grepStderr("invalid flag in #cgo CFLAGS: -D without argument", "did not reject trailing -I flag")
5985
5986	// Note that -I @foo is allowed because we rewrite it into -I /path/to/src/@foo
5987	// before the check is applied. There's no such rewrite for -D.
5988
5989	tg.tempFile("src/x/y.go", `package x
5990		// #cgo CFLAGS: -D @foo
5991		import "C"
5992	`)
5993	tg.runFail("build", "x")
5994	tg.grepStderr("invalid flag in #cgo CFLAGS: -D @foo", "did not reject -D @foo flag")
5995
5996	tg.tempFile("src/x/y.go", `package x
5997		// #cgo CFLAGS: -D@foo
5998		import "C"
5999	`)
6000	tg.runFail("build", "x")
6001	tg.grepStderr("invalid flag in #cgo CFLAGS: -D@foo", "did not reject -D@foo flag")
6002
6003	tg.setenv("CGO_CFLAGS", "-D@foo")
6004	tg.tempFile("src/x/y.go", `package x
6005		import "C"
6006	`)
6007	tg.run("build", "-n", "x")
6008	tg.grepStderr("-D@foo", "did not find -D@foo in commands")
6009}
6010
6011func TestTwoPkgConfigs(t *testing.T) {
6012	if !canCgo {
6013		t.Skip("no cgo")
6014	}
6015	if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
6016		t.Skipf("no shell scripts on %s", runtime.GOOS)
6017	}
6018	tg := testgo(t)
6019	defer tg.cleanup()
6020	tg.parallel()
6021	tg.tempFile("src/x/a.go", `package x
6022		// #cgo pkg-config: --static a
6023		import "C"
6024	`)
6025	tg.tempFile("src/x/b.go", `package x
6026		// #cgo pkg-config: --static a
6027		import "C"
6028	`)
6029	tg.tempFile("pkg-config.sh", `#!/bin/sh
6030echo $* >>`+tg.path("pkg-config.out"))
6031	tg.must(os.Chmod(tg.path("pkg-config.sh"), 0755))
6032	tg.setenv("GOPATH", tg.path("."))
6033	tg.setenv("PKG_CONFIG", tg.path("pkg-config.sh"))
6034	tg.run("build", "x")
6035	out, err := ioutil.ReadFile(tg.path("pkg-config.out"))
6036	tg.must(err)
6037	out = bytes.TrimSpace(out)
6038	want := "--cflags --static --static -- a a\n--libs --static --static -- a a"
6039	if !bytes.Equal(out, []byte(want)) {
6040		t.Errorf("got %q want %q", out, want)
6041	}
6042}
6043