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