Source file
src/cmd/go/go_test.go
Documentation: cmd/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
94
95 var testGOROOT_FINAL = os.Getenv("GOROOT_FINAL")
96
97 var testGOCACHE string
98
99 var testGo string
100 var testTmpDir string
101 var testBin string
102
103
104
105 func TestMain(m *testing.M) {
106
107
108
109
110 if os.Getenv("CMDGO_TEST_RUN_MAIN") != "" {
111 cfg.SetGOROOT(cfg.GOROOT, true)
112 gover.TestVersion = os.Getenv("TESTGO_VERSION")
113 toolchain.TestVersionSwitch = os.Getenv("TESTGO_VERSION_SWITCH")
114 if v := os.Getenv("TESTGO_TOOLCHAIN_VERSION"); v != "" {
115 work.ToolchainVersion = v
116 }
117
118 if testGOROOT := os.Getenv("TESTGO_GOROOT"); testGOROOT != "" {
119
120
121 work.AllowInstall = func(a *work.Action) error {
122 if cfg.BuildN {
123 return nil
124 }
125
126 rel := search.InDir(a.Target, testGOROOT)
127 if rel == "" {
128 return nil
129 }
130
131 callerPos := ""
132 if _, file, line, ok := runtime.Caller(1); ok {
133 if shortFile := search.InDir(file, filepath.Join(testGOROOT, "src")); shortFile != "" {
134 file = shortFile
135 }
136 callerPos = fmt.Sprintf("%s:%d: ", file, line)
137 }
138 notice := "This error error can occur if GOROOT is stale, in which case rerunning make.bash will fix it."
139 return fmt.Errorf("%stestgo must not write to GOROOT (installing to %s) (%v)", callerPos, filepath.Join("GOROOT", rel), notice)
140 }
141 }
142
143 if vcsTestHost := os.Getenv("TESTGO_VCSTEST_HOST"); vcsTestHost != "" {
144 vcs.VCSTestRepoURL = "http://" + vcsTestHost
145 vcs.VCSTestHosts = vcstest.Hosts
146 vcsTestTLSHost := os.Getenv("TESTGO_VCSTEST_TLS_HOST")
147 vcsTestClient, err := vcstest.TLSClient(os.Getenv("TESTGO_VCSTEST_CERT"))
148 if err != nil {
149 fmt.Fprintf(os.Stderr, "loading certificates from $TESTGO_VCSTEST_CERT: %v", err)
150 }
151 var interceptors []web.Interceptor
152 for _, host := range vcstest.Hosts {
153 interceptors = append(interceptors,
154 web.Interceptor{Scheme: "http", FromHost: host, ToHost: vcsTestHost},
155 web.Interceptor{Scheme: "https", FromHost: host, ToHost: vcsTestTLSHost, Client: vcsTestClient})
156 }
157 web.EnableTestHooks(interceptors)
158 }
159
160 cmdgo.Main()
161 os.Exit(0)
162 }
163 os.Setenv("CMDGO_TEST_RUN_MAIN", "true")
164
165
166
167 if os.Getenv("GO_GCFLAGS") != "" {
168 fmt.Fprintf(os.Stderr, "testing: warning: no tests to run\n")
169 fmt.Printf("cmd/go test is not compatible with $GO_GCFLAGS being set\n")
170 fmt.Printf("SKIP\n")
171 return
172 }
173
174 flag.Parse()
175
176 if *proxyAddr != "" {
177 StartProxy()
178 select {}
179 }
180
181
182
183 topTmpdir, err := os.MkdirTemp("", "cmd-go-test-")
184 if err != nil {
185 log.Fatal(err)
186 }
187 if !*testWork {
188 defer removeAll(topTmpdir)
189 } else {
190 fmt.Fprintf(os.Stderr, "TESTWORK: preserving top level tempdir %s\n", topTmpdir)
191 }
192 os.Setenv(tempEnvName(), topTmpdir)
193
194 dir, err := os.MkdirTemp(topTmpdir, "tmpdir")
195 if err != nil {
196 log.Fatal(err)
197 }
198 testTmpDir = dir
199 if !*testWork {
200 defer removeAll(testTmpDir)
201 }
202
203 testGOCACHE = cache.DefaultDir()
204 if testenv.HasGoBuild() {
205 testBin = filepath.Join(testTmpDir, "testbin")
206 if err := os.Mkdir(testBin, 0777); err != nil {
207 log.Fatal(err)
208 }
209 testGo = filepath.Join(testBin, "go"+exeSuffix)
210 gotool, err := testenv.GoTool()
211 if err != nil {
212 fmt.Fprintln(os.Stderr, "locating go tool: ", err)
213 os.Exit(2)
214 }
215
216 goEnv := func(name string) string {
217 out, err := exec.Command(gotool, "env", name).CombinedOutput()
218 if err != nil {
219 fmt.Fprintf(os.Stderr, "go env %s: %v\n%s", name, err, out)
220 os.Exit(2)
221 }
222 return strings.TrimSpace(string(out))
223 }
224 testGOROOT = goEnv("GOROOT")
225 os.Setenv("TESTGO_GOROOT", testGOROOT)
226
227
228
229
230 os.Setenv("GOROOT", testGOROOT)
231
232
233
234
235
236
237
238
239
240
241
242
243 goHostOS = goEnv("GOHOSTOS")
244 os.Setenv("TESTGO_GOHOSTOS", goHostOS)
245 goHostArch = goEnv("GOHOSTARCH")
246 os.Setenv("TESTGO_GOHOSTARCH", goHostArch)
247
248 cgoEnabled = goEnv("CGO_ENABLED")
249
250
251
252 testExe, err := os.Executable()
253 if err != nil {
254 log.Fatal(err)
255 }
256 if err := os.Symlink(testExe, testGo); err != nil {
257
258 src, err := os.Open(testExe)
259 if err != nil {
260 log.Fatal(err)
261 }
262 defer src.Close()
263
264 dst, err := os.OpenFile(testGo, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0o777)
265 if err != nil {
266 log.Fatal(err)
267 }
268
269 _, err = io.Copy(dst, src)
270 if closeErr := dst.Close(); err == nil {
271 err = closeErr
272 }
273 if err != nil {
274 log.Fatal(err)
275 }
276 }
277
278 out, err := exec.Command(gotool, "env", "GOCACHE").CombinedOutput()
279 if err != nil {
280 fmt.Fprintf(os.Stderr, "could not find testing GOCACHE: %v\n%s", err, out)
281 os.Exit(2)
282 }
283 testGOCACHE = strings.TrimSpace(string(out))
284
285 canMSan = testenv.HasCGO() && platform.MSanSupported(runtime.GOOS, runtime.GOARCH)
286 canASan = testenv.HasCGO() && platform.ASanSupported(runtime.GOOS, runtime.GOARCH)
287 canRace = testenv.HasCGO() && platform.RaceDetectorSupported(runtime.GOOS, runtime.GOARCH)
288
289
290
291 if isAlpineLinux() || runtime.Compiler == "gccgo" {
292 canRace = false
293 }
294 }
295
296 if n, limited := base.NetLimit(); limited && n > 0 {
297
298
299
300
301 netTestLimit := int(math.Sqrt(float64(n)))
302 netTestSem = make(chan struct{}, netTestLimit)
303 reducedLimit := fmt.Sprintf(",%s=%d", base.NetLimitGodebug.Name(), n/netTestLimit)
304 os.Setenv("GODEBUG", os.Getenv("GODEBUG")+reducedLimit)
305 }
306
307
308 os.Setenv("GOENV", "off")
309 os.Unsetenv("GOFLAGS")
310 os.Unsetenv("GOBIN")
311 os.Unsetenv("GOPATH")
312 os.Unsetenv("GIT_ALLOW_PROTOCOL")
313 os.Setenv("HOME", "/test-go-home-does-not-exist")
314
315
316
317 os.Setenv("CCACHE_DISABLE", "1")
318 if cfg.Getenv("GOCACHE") == "" {
319 os.Setenv("GOCACHE", testGOCACHE)
320 }
321
322 if testenv.Builder() != "" || os.Getenv("GIT_TRACE_CURL") == "1" {
323
324
325 os.Setenv("GIT_TRACE_CURL", "1")
326 os.Setenv("GIT_TRACE_CURL_NO_DATA", "1")
327 os.Setenv("GIT_REDACT_COOKIES", "o,SSO,GSSO_Uberproxy")
328 }
329
330 r := m.Run()
331 if !*testWork {
332 removeAll(testTmpDir)
333 }
334
335 if !*testWork {
336
337 var extraFiles, extraDirs []string
338 err := filepath.WalkDir(topTmpdir, func(path string, d fs.DirEntry, err error) error {
339 if err != nil {
340 return err
341 }
342 if path == topTmpdir {
343 return nil
344 }
345
346 if rel, err := filepath.Rel(topTmpdir, path); err == nil {
347 path = rel
348 }
349 if d.IsDir() {
350 extraDirs = append(extraDirs, path)
351 } else {
352 extraFiles = append(extraFiles, path)
353 }
354 return nil
355 })
356 if err != nil {
357 log.Fatal(err)
358 }
359
360 if len(extraFiles) > 0 {
361 log.Fatalf("unexpected files left in tmpdir: %q", extraFiles)
362 } else if len(extraDirs) > 0 {
363 log.Fatalf("unexpected subdirectories left in tmpdir: %q", extraDirs)
364 }
365
366 removeAll(topTmpdir)
367 }
368
369 os.Exit(r)
370 }
371
372 func isAlpineLinux() bool {
373 if runtime.GOOS != "linux" {
374 return false
375 }
376 fi, err := os.Lstat("/etc/alpine-release")
377 return err == nil && fi.Mode().IsRegular()
378 }
379
380
381
382
383
384 var mtimeTick time.Duration = 1 * time.Second
385
386
387 type testgoData struct {
388 t *testing.T
389 temps []string
390 env []string
391 tempdir string
392 ran bool
393 inParallel bool
394 stdout, stderr bytes.Buffer
395 execDir string
396 }
397
398
399 func skipIfGccgo(t *testing.T, msg string) {
400 if runtime.Compiler == "gccgo" {
401 t.Skipf("skipping test not supported on gccgo: %s", msg)
402 }
403 }
404
405
406 func testgo(t *testing.T) *testgoData {
407 t.Helper()
408 testenv.MustHaveGoBuild(t)
409 testenv.SkipIfShortAndSlow(t)
410
411 return &testgoData{t: t}
412 }
413
414
415 func (tg *testgoData) must(err error) {
416 tg.t.Helper()
417 if err != nil {
418 tg.t.Fatal(err)
419 }
420 }
421
422
423 func (tg *testgoData) check(err error) {
424 tg.t.Helper()
425 if err != nil {
426 tg.t.Error(err)
427 }
428 }
429
430
431 func (tg *testgoData) parallel() {
432 tg.t.Helper()
433 if tg.ran {
434 tg.t.Fatal("internal testsuite error: call to parallel after run")
435 }
436 for _, e := range tg.env {
437 if strings.HasPrefix(e, "GOROOT=") || strings.HasPrefix(e, "GOPATH=") || strings.HasPrefix(e, "GOBIN=") {
438 val := e[strings.Index(e, "=")+1:]
439 if strings.HasPrefix(val, "testdata") || strings.HasPrefix(val, "./testdata") {
440 tg.t.Fatalf("internal testsuite error: call to parallel with testdata in environment (%s)", e)
441 }
442 }
443 }
444 tg.inParallel = true
445 tg.t.Parallel()
446 }
447
448
449 func (tg *testgoData) pwd() string {
450 tg.t.Helper()
451 wd, err := os.Getwd()
452 if err != nil {
453 tg.t.Fatalf("could not get working directory: %v", err)
454 }
455 return wd
456 }
457
458
459
460
461 func (tg *testgoData) sleep() {
462 time.Sleep(mtimeTick)
463 }
464
465
466
467 func (tg *testgoData) setenv(name, val string) {
468 tg.t.Helper()
469 tg.unsetenv(name)
470 tg.env = append(tg.env, name+"="+val)
471 }
472
473
474 func (tg *testgoData) unsetenv(name string) {
475 if tg.env == nil {
476 tg.env = append([]string(nil), os.Environ()...)
477 tg.env = append(tg.env, "GO111MODULE=off", "TESTGONETWORK=panic")
478 if testing.Short() {
479 tg.env = append(tg.env, "TESTGOVCS=panic")
480 }
481 }
482 for i, v := range tg.env {
483 if strings.HasPrefix(v, name+"=") {
484 tg.env = append(tg.env[:i], tg.env[i+1:]...)
485 break
486 }
487 }
488 }
489
490 func (tg *testgoData) goTool() string {
491 return testGo
492 }
493
494
495
496 func (tg *testgoData) doRun(args []string) error {
497 tg.t.Helper()
498 if tg.inParallel {
499 for _, arg := range args {
500 if strings.HasPrefix(arg, "testdata") || strings.HasPrefix(arg, "./testdata") {
501 tg.t.Fatal("internal testsuite error: parallel run using testdata")
502 }
503 }
504 }
505
506 hasGoroot := false
507 for _, v := range tg.env {
508 if strings.HasPrefix(v, "GOROOT=") {
509 hasGoroot = true
510 break
511 }
512 }
513 prog := tg.goTool()
514 if !hasGoroot {
515 tg.setenv("GOROOT", testGOROOT)
516 }
517
518 tg.t.Logf("running testgo %v", args)
519 cmd := testenv.Command(tg.t, prog, args...)
520 tg.stdout.Reset()
521 tg.stderr.Reset()
522 cmd.Dir = tg.execDir
523 cmd.Stdout = &tg.stdout
524 cmd.Stderr = &tg.stderr
525 cmd.Env = tg.env
526 status := cmd.Run()
527 if tg.stdout.Len() > 0 {
528 tg.t.Log("standard output:")
529 tg.t.Log(tg.stdout.String())
530 }
531 if tg.stderr.Len() > 0 {
532 tg.t.Log("standard error:")
533 tg.t.Log(tg.stderr.String())
534 }
535 tg.ran = true
536 return status
537 }
538
539
540 func (tg *testgoData) run(args ...string) {
541 tg.t.Helper()
542 if status := tg.doRun(args); status != nil {
543 wd, _ := os.Getwd()
544 tg.t.Logf("go %v failed unexpectedly in %s: %v", args, wd, status)
545 tg.t.FailNow()
546 }
547 }
548
549
550 func (tg *testgoData) runFail(args ...string) {
551 tg.t.Helper()
552 if status := tg.doRun(args); status == nil {
553 tg.t.Fatal("testgo succeeded unexpectedly")
554 } else {
555 tg.t.Log("testgo failed as expected:", status)
556 }
557 }
558
559
560 func (tg *testgoData) getStdout() string {
561 tg.t.Helper()
562 if !tg.ran {
563 tg.t.Fatal("internal testsuite error: stdout called before run")
564 }
565 return tg.stdout.String()
566 }
567
568
569 func (tg *testgoData) getStderr() string {
570 tg.t.Helper()
571 if !tg.ran {
572 tg.t.Fatal("internal testsuite error: stdout called before run")
573 }
574 return tg.stderr.String()
575 }
576
577
578
579
580 func (tg *testgoData) doGrepMatch(match string, b *bytes.Buffer) bool {
581 tg.t.Helper()
582 if !tg.ran {
583 tg.t.Fatal("internal testsuite error: grep called before run")
584 }
585 re := regexp.MustCompile(match)
586 for _, ln := range bytes.Split(b.Bytes(), []byte{'\n'}) {
587 if re.Match(ln) {
588 return true
589 }
590 }
591 return false
592 }
593
594
595
596
597
598 func (tg *testgoData) doGrep(match string, b *bytes.Buffer, name, msg string) {
599 tg.t.Helper()
600 if !tg.doGrepMatch(match, b) {
601 tg.t.Log(msg)
602 tg.t.Logf("pattern %v not found in standard %s", match, name)
603 tg.t.FailNow()
604 }
605 }
606
607
608
609 func (tg *testgoData) grepStdout(match, msg string) {
610 tg.t.Helper()
611 tg.doGrep(match, &tg.stdout, "output", msg)
612 }
613
614
615
616 func (tg *testgoData) grepStderr(match, msg string) {
617 tg.t.Helper()
618 tg.doGrep(match, &tg.stderr, "error", msg)
619 }
620
621
622
623 func (tg *testgoData) grepBoth(match, msg string) {
624 tg.t.Helper()
625 if !tg.doGrepMatch(match, &tg.stdout) && !tg.doGrepMatch(match, &tg.stderr) {
626 tg.t.Log(msg)
627 tg.t.Logf("pattern %v not found in standard output or standard error", match)
628 tg.t.FailNow()
629 }
630 }
631
632
633
634 func (tg *testgoData) doGrepNot(match string, b *bytes.Buffer, name, msg string) {
635 tg.t.Helper()
636 if tg.doGrepMatch(match, b) {
637 tg.t.Log(msg)
638 tg.t.Logf("pattern %v found unexpectedly in standard %s", match, name)
639 tg.t.FailNow()
640 }
641 }
642
643
644
645 func (tg *testgoData) grepStdoutNot(match, msg string) {
646 tg.t.Helper()
647 tg.doGrepNot(match, &tg.stdout, "output", msg)
648 }
649
650
651
652 func (tg *testgoData) grepStderrNot(match, msg string) {
653 tg.t.Helper()
654 tg.doGrepNot(match, &tg.stderr, "error", msg)
655 }
656
657
658
659
660 func (tg *testgoData) grepBothNot(match, msg string) {
661 tg.t.Helper()
662 if tg.doGrepMatch(match, &tg.stdout) || tg.doGrepMatch(match, &tg.stderr) {
663 tg.t.Log(msg)
664 tg.t.Fatalf("pattern %v found unexpectedly in standard output or standard error", match)
665 }
666 }
667
668
669 func (tg *testgoData) doGrepCount(match string, b *bytes.Buffer) int {
670 tg.t.Helper()
671 if !tg.ran {
672 tg.t.Fatal("internal testsuite error: doGrepCount called before run")
673 }
674 re := regexp.MustCompile(match)
675 c := 0
676 for _, ln := range bytes.Split(b.Bytes(), []byte{'\n'}) {
677 if re.Match(ln) {
678 c++
679 }
680 }
681 return c
682 }
683
684
685
686 func (tg *testgoData) grepCountBoth(match string) int {
687 tg.t.Helper()
688 return tg.doGrepCount(match, &tg.stdout) + tg.doGrepCount(match, &tg.stderr)
689 }
690
691
692
693
694
695 func (tg *testgoData) creatingTemp(path string) {
696 tg.t.Helper()
697 if filepath.IsAbs(path) && !strings.HasPrefix(path, tg.tempdir) {
698 tg.t.Fatalf("internal testsuite error: creatingTemp(%q) with absolute path not in temporary directory", path)
699 }
700 tg.must(robustio.RemoveAll(path))
701 tg.temps = append(tg.temps, path)
702 }
703
704
705
706 func (tg *testgoData) makeTempdir() {
707 tg.t.Helper()
708 if tg.tempdir == "" {
709 var err error
710 tg.tempdir, err = os.MkdirTemp("", "gotest")
711 tg.must(err)
712 }
713 }
714
715
716 func (tg *testgoData) tempFile(path, contents string) {
717 tg.t.Helper()
718 tg.makeTempdir()
719 tg.must(os.MkdirAll(filepath.Join(tg.tempdir, filepath.Dir(path)), 0755))
720 bytes := []byte(contents)
721 if strings.HasSuffix(path, ".go") {
722 formatted, err := format.Source(bytes)
723 if err == nil {
724 bytes = formatted
725 }
726 }
727 tg.must(os.WriteFile(filepath.Join(tg.tempdir, path), bytes, 0644))
728 }
729
730
731 func (tg *testgoData) tempDir(path string) {
732 tg.t.Helper()
733 tg.makeTempdir()
734 if err := os.MkdirAll(filepath.Join(tg.tempdir, path), 0755); err != nil && !os.IsExist(err) {
735 tg.t.Fatal(err)
736 }
737 }
738
739
740
741 func (tg *testgoData) path(name string) string {
742 tg.t.Helper()
743 if tg.tempdir == "" {
744 tg.t.Fatalf("internal testsuite error: path(%q) with no tempdir", name)
745 }
746 if name == "." {
747 return tg.tempdir
748 }
749 return filepath.Join(tg.tempdir, name)
750 }
751
752
753 func (tg *testgoData) mustExist(path string) {
754 tg.t.Helper()
755 if _, err := os.Stat(path); err != nil {
756 if os.IsNotExist(err) {
757 tg.t.Fatalf("%s does not exist but should", path)
758 }
759 tg.t.Fatalf("%s stat failed: %v", path, err)
760 }
761 }
762
763
764 func (tg *testgoData) mustNotExist(path string) {
765 tg.t.Helper()
766 if _, err := os.Stat(path); err == nil || !os.IsNotExist(err) {
767 tg.t.Fatalf("%s exists but should not (%v)", path, err)
768 }
769 }
770
771
772 func (tg *testgoData) wantExecutable(path, msg string) {
773 tg.t.Helper()
774 if st, err := os.Stat(path); err != nil {
775 if !os.IsNotExist(err) {
776 tg.t.Log(err)
777 }
778 tg.t.Fatal(msg)
779 } else {
780 if runtime.GOOS != "windows" && st.Mode()&0111 == 0 {
781 tg.t.Fatalf("binary %s exists but is not executable", path)
782 }
783 }
784 }
785
786
787 func (tg *testgoData) isStale(pkg string) (bool, string) {
788 tg.t.Helper()
789 tg.run("list", "-f", "{{.Stale}}:{{.StaleReason}}", pkg)
790 v := strings.TrimSpace(tg.getStdout())
791 f := strings.SplitN(v, ":", 2)
792 if len(f) == 2 {
793 switch f[0] {
794 case "true":
795 return true, f[1]
796 case "false":
797 return false, f[1]
798 }
799 }
800 tg.t.Fatalf("unexpected output checking staleness of package %v: %v", pkg, v)
801 panic("unreachable")
802 }
803
804
805 func (tg *testgoData) wantStale(pkg, reason, msg string) {
806 tg.t.Helper()
807 stale, why := tg.isStale(pkg)
808 if !stale {
809 tg.t.Fatal(msg)
810 }
811
812
813
814
815 if reason == "" && why != "" || !strings.Contains(why, reason) && !strings.Contains(why, "not installed but available in build cache") {
816 tg.t.Errorf("wrong reason for Stale=true: %q, want %q", why, reason)
817 }
818 }
819
820
821 func (tg *testgoData) wantNotStale(pkg, reason, msg string) {
822 tg.t.Helper()
823 stale, why := tg.isStale(pkg)
824 if stale {
825 tg.t.Fatal(msg)
826 }
827 if reason == "" && why != "" || !strings.Contains(why, reason) {
828 tg.t.Errorf("wrong reason for Stale=false: %q, want %q", why, reason)
829 }
830 }
831
832
833
834
835 var testWork = flag.Bool("testwork", false, "")
836
837
838 func (tg *testgoData) cleanup() {
839 tg.t.Helper()
840 if *testWork {
841 if tg.tempdir != "" {
842 tg.t.Logf("TESTWORK=%s\n", tg.path("."))
843 }
844 return
845 }
846 for _, path := range tg.temps {
847 tg.check(removeAll(path))
848 }
849 if tg.tempdir != "" {
850 tg.check(removeAll(tg.tempdir))
851 }
852 }
853
854 func removeAll(dir string) error {
855
856
857 filepath.WalkDir(dir, func(path string, info fs.DirEntry, err error) error {
858
859
860 if err != nil || info.IsDir() {
861 os.Chmod(path, 0777)
862 }
863 return nil
864 })
865 return robustio.RemoveAll(dir)
866 }
867
868 func TestNewReleaseRebuildsStalePackagesInGOPATH(t *testing.T) {
869 if testing.Short() {
870 t.Skip("skipping lengthy test in short mode")
871 }
872
873 tg := testgo(t)
874 defer tg.cleanup()
875 tg.parallel()
876
877
878
879 tg.tempDir("gocache")
880 tg.setenv("GOCACHE", tg.path("gocache"))
881
882
883
884 var dirs []string
885 tg.run("list", "-deps", "runtime")
886 pkgs := strings.Split(strings.TrimSpace(tg.getStdout()), "\n")
887 for _, pkg := range pkgs {
888 dirs = append(dirs, filepath.Join("src", pkg))
889 }
890 dirs = append(dirs,
891 filepath.Join("pkg/tool", goHostOS+"_"+goHostArch),
892 "pkg/include",
893 )
894 for _, copydir := range dirs {
895 srcdir := filepath.Join(testGOROOT, copydir)
896 tg.tempDir(filepath.Join("goroot", copydir))
897 err := filepath.WalkDir(srcdir,
898 func(path string, info fs.DirEntry, err error) error {
899 if err != nil {
900 return err
901 }
902 if info.IsDir() {
903 return nil
904 }
905 srcrel, err := filepath.Rel(srcdir, path)
906 if err != nil {
907 return err
908 }
909 dest := filepath.Join("goroot", copydir, srcrel)
910 if _, err := os.Stat(dest); err == nil {
911 return nil
912 }
913 data, err := os.ReadFile(path)
914 if err != nil {
915 return err
916 }
917 tg.tempFile(dest, string(data))
918 if strings.Contains(copydir, filepath.Join("pkg", "tool")) {
919 os.Chmod(tg.path(dest), 0777)
920 }
921 return nil
922 })
923 if err != nil {
924 t.Fatal(err)
925 }
926 }
927 tg.setenv("GOROOT", tg.path("goroot"))
928
929 addVar := func(name string, idx int) (restore func()) {
930 data, err := os.ReadFile(name)
931 if err != nil {
932 t.Fatal(err)
933 }
934 old := data
935 data = append(data, fmt.Sprintf("var DummyUnusedVar%d bool\n", idx)...)
936 if err := os.WriteFile(name, append(data, '\n'), 0666); err != nil {
937 t.Fatal(err)
938 }
939 tg.sleep()
940 return func() {
941 if err := os.WriteFile(name, old, 0666); err != nil {
942 t.Fatal(err)
943 }
944 }
945 }
946
947
948 tg.tempFile("d1/src/p1/p1.go", `package main; func main(){}`)
949 tg.setenv("GOPATH", tg.path("d1"))
950
951 tg.run("install", "p1")
952 tg.wantNotStale("p1", "", "./testgo list claims p1 is stale, incorrectly, before any changes")
953
954
955
956
957 sys := tg.path("goroot/src/runtime/internal/sys/sys.go")
958 tg.sleep()
959 restore := addVar(sys, 0)
960 restore()
961 tg.wantNotStale("p1", "", "./testgo list claims p1 is stale, incorrectly, after updating mtime of runtime/internal/sys/sys.go")
962
963
964
965
966 restore = addVar(sys, 1)
967 defer restore()
968 tg.wantStale("p1", "stale dependency: runtime/internal", "./testgo list claims p1 is NOT stale, incorrectly, after changing sys.go")
969 restore()
970 tg.wantNotStale("p1", "", "./testgo list claims p1 is stale, incorrectly, after changing back to old release")
971 addVar(sys, 2)
972 tg.wantStale("p1", "stale dependency: runtime", "./testgo list claims p1 is NOT stale, incorrectly, after changing sys.go again")
973 tg.run("install", "p1")
974 tg.wantNotStale("p1", "", "./testgo list claims p1 is stale after building with new release")
975
976
977 restore()
978 tg.wantStale("p1", "stale dependency: runtime/internal", "./testgo list claims p1 is NOT stale, incorrectly, after restoring sys.go")
979 tg.run("install", "p1")
980 tg.wantNotStale("p1", "", "./testgo list claims p1 is stale after building with old release")
981 }
982
983 func TestPackageMainTestCompilerFlags(t *testing.T) {
984 tg := testgo(t)
985 defer tg.cleanup()
986 tg.parallel()
987 tg.makeTempdir()
988 tg.setenv("GOPATH", tg.path("."))
989 tg.tempFile("src/p1/p1.go", "package main\n")
990 tg.tempFile("src/p1/p1_test.go", "package main\nimport \"testing\"\nfunc Test(t *testing.T){}\n")
991 tg.run("test", "-c", "-n", "p1")
992 tg.grepBothNot(`([\\/]compile|gccgo).* (-p main|-fgo-pkgpath=main).*p1\.go`, "should not have run compile -p main p1.go")
993 tg.grepStderr(`([\\/]compile|gccgo).* (-p p1|-fgo-pkgpath=p1).*p1\.go`, "should have run compile -p p1 p1.go")
994 }
995
996
997 func TestGoTestWithPackageListedMultipleTimes(t *testing.T) {
998 tooSlow(t, "links and runs a test")
999
1000 tg := testgo(t)
1001 defer tg.cleanup()
1002 tg.parallel()
1003 tg.run("test", "errors", "errors", "errors", "errors", "errors")
1004 if strings.Contains(strings.TrimSpace(tg.getStdout()), "\n") {
1005 t.Error("go test errors errors errors errors errors tested the same package multiple times")
1006 }
1007 }
1008
1009 func TestGoListHasAConsistentOrder(t *testing.T) {
1010 tooSlow(t, "walks all of GOROOT/src twice")
1011
1012 tg := testgo(t)
1013 defer tg.cleanup()
1014 tg.parallel()
1015 tg.run("list", "std")
1016 first := tg.getStdout()
1017 tg.run("list", "std")
1018 if first != tg.getStdout() {
1019 t.Error("go list std ordering is inconsistent")
1020 }
1021 }
1022
1023 func TestGoListStdDoesNotIncludeCommands(t *testing.T) {
1024 tooSlow(t, "walks all of GOROOT/src")
1025
1026 tg := testgo(t)
1027 defer tg.cleanup()
1028 tg.parallel()
1029 tg.run("list", "std")
1030 tg.grepStdoutNot("cmd/", "go list std shows commands")
1031 }
1032
1033 func TestGoListCmdOnlyShowsCommands(t *testing.T) {
1034 skipIfGccgo(t, "gccgo does not have GOROOT")
1035 tooSlow(t, "walks all of GOROOT/src/cmd")
1036
1037 tg := testgo(t)
1038 defer tg.cleanup()
1039 tg.parallel()
1040 tg.run("list", "cmd")
1041 out := strings.TrimSpace(tg.getStdout())
1042 for _, line := range strings.Split(out, "\n") {
1043 if !strings.Contains(line, "cmd/") {
1044 t.Error("go list cmd shows non-commands")
1045 break
1046 }
1047 }
1048 }
1049
1050 func TestGoListDeps(t *testing.T) {
1051 tg := testgo(t)
1052 defer tg.cleanup()
1053 tg.parallel()
1054 tg.tempDir("src/p1/p2/p3/p4")
1055 tg.setenv("GOPATH", tg.path("."))
1056 tg.tempFile("src/p1/p.go", "package p1\nimport _ \"p1/p2\"\n")
1057 tg.tempFile("src/p1/p2/p.go", "package p2\nimport _ \"p1/p2/p3\"\n")
1058 tg.tempFile("src/p1/p2/p3/p.go", "package p3\nimport _ \"p1/p2/p3/p4\"\n")
1059 tg.tempFile("src/p1/p2/p3/p4/p.go", "package p4\n")
1060 tg.run("list", "-f", "{{.Deps}}", "p1")
1061 tg.grepStdout("p1/p2/p3/p4", "Deps(p1) does not mention p4")
1062
1063 tg.run("list", "-deps", "p1")
1064 tg.grepStdout("p1/p2/p3/p4", "-deps p1 does not mention p4")
1065
1066 if runtime.Compiler != "gccgo" {
1067
1068 tg.run("list", "-deps", "math")
1069 want := "internal/cpu\nunsafe\nmath/bits\nmath\n"
1070 out := tg.stdout.String()
1071 if !strings.Contains(out, "internal/cpu") {
1072
1073 want = "unsafe\nmath/bits\nmath\n"
1074 }
1075 if tg.stdout.String() != want {
1076 t.Fatalf("list -deps math: wrong order\nhave %q\nwant %q", tg.stdout.String(), want)
1077 }
1078 }
1079 }
1080
1081 func TestGoListTest(t *testing.T) {
1082 skipIfGccgo(t, "gccgo does not have standard packages")
1083 tg := testgo(t)
1084 defer tg.cleanup()
1085 tg.parallel()
1086 tg.makeTempdir()
1087 tg.setenv("GOCACHE", tg.tempdir)
1088
1089 tg.run("list", "-test", "-deps", "sort")
1090 tg.grepStdout(`^sort.test$`, "missing test main")
1091 tg.grepStdout(`^sort$`, "missing real sort")
1092 tg.grepStdout(`^sort \[sort.test\]$`, "missing test copy of sort")
1093 tg.grepStdout(`^testing \[sort.test\]$`, "missing test copy of testing")
1094 tg.grepStdoutNot(`^testing$`, "unexpected real copy of testing")
1095
1096 tg.run("list", "-test", "sort")
1097 tg.grepStdout(`^sort.test$`, "missing test main")
1098 tg.grepStdout(`^sort$`, "missing real sort")
1099 tg.grepStdout(`^sort \[sort.test\]$`, "unexpected test copy of sort")
1100 tg.grepStdoutNot(`^testing \[sort.test\]$`, "unexpected test copy of testing")
1101 tg.grepStdoutNot(`^testing$`, "unexpected real copy of testing")
1102
1103 tg.run("list", "-test", "cmd/buildid", "cmd/doc")
1104 tg.grepStdout(`^cmd/buildid$`, "missing cmd/buildid")
1105 tg.grepStdout(`^cmd/doc$`, "missing cmd/doc")
1106 tg.grepStdout(`^cmd/doc\.test$`, "missing cmd/doc test")
1107 tg.grepStdoutNot(`^cmd/buildid\.test$`, "unexpected cmd/buildid test")
1108 tg.grepStdoutNot(`^testing`, "unexpected testing")
1109
1110 tg.run("list", "-test", "runtime/cgo")
1111 tg.grepStdout(`^runtime/cgo$`, "missing runtime/cgo")
1112
1113 tg.run("list", "-deps", "-f", "{{if .DepOnly}}{{.ImportPath}}{{end}}", "sort")
1114 tg.grepStdout(`^internal/reflectlite$`, "missing internal/reflectlite")
1115 tg.grepStdoutNot(`^sort`, "unexpected sort")
1116 }
1117
1118 func TestGoListCompiledCgo(t *testing.T) {
1119 tooSlow(t, "compiles cgo files")
1120
1121 tg := testgo(t)
1122 defer tg.cleanup()
1123 tg.parallel()
1124 tg.makeTempdir()
1125 tg.setenv("GOCACHE", tg.tempdir)
1126
1127 tg.run("list", "-f", `{{join .CgoFiles "\n"}}`, "net")
1128 if tg.stdout.String() == "" {
1129 t.Skip("net does not use cgo")
1130 }
1131 if strings.Contains(tg.stdout.String(), tg.tempdir) {
1132 t.Fatalf(".CgoFiles unexpectedly mentioned cache %s", tg.tempdir)
1133 }
1134 tg.run("list", "-compiled", "-f", `{{.Dir}}{{"\n"}}{{join .CompiledGoFiles "\n"}}`, "net")
1135 if !strings.Contains(tg.stdout.String(), tg.tempdir) {
1136 t.Fatalf(".CompiledGoFiles with -compiled did not mention cache %s", tg.tempdir)
1137 }
1138 dir := ""
1139 for _, file := range strings.Split(tg.stdout.String(), "\n") {
1140 if file == "" {
1141 continue
1142 }
1143 if dir == "" {
1144 dir = file
1145 continue
1146 }
1147 if !strings.Contains(file, "/") && !strings.Contains(file, `\`) {
1148 file = filepath.Join(dir, file)
1149 }
1150 if _, err := os.Stat(file); err != nil {
1151 t.Fatalf("cannot find .CompiledGoFiles result %s: %v", file, err)
1152 }
1153 }
1154 }
1155
1156 func TestGoListExport(t *testing.T) {
1157 skipIfGccgo(t, "gccgo does not have standard packages")
1158 tg := testgo(t)
1159 defer tg.cleanup()
1160 tg.parallel()
1161 tg.makeTempdir()
1162 tg.setenv("GOCACHE", tg.tempdir)
1163
1164 tg.run("list", "-f", "{{.Export}}", "strings")
1165 if tg.stdout.String() != "" {
1166 t.Fatalf(".Export without -export unexpectedly set")
1167 }
1168 tg.run("list", "-export", "-f", "{{.Export}}", "strings")
1169 file := strings.TrimSpace(tg.stdout.String())
1170 if file == "" {
1171 t.Fatalf(".Export with -export was empty")
1172 }
1173 if _, err := os.Stat(file); err != nil {
1174 t.Fatalf("cannot find .Export result %s: %v", file, err)
1175 }
1176
1177 tg.run("list", "-export", "-f", "{{.BuildID}}", "strings")
1178 buildID := strings.TrimSpace(tg.stdout.String())
1179 if buildID == "" {
1180 t.Fatalf(".BuildID with -export was empty")
1181 }
1182
1183 tg.run("tool", "buildid", file)
1184 toolBuildID := strings.TrimSpace(tg.stdout.String())
1185 if buildID != toolBuildID {
1186 t.Fatalf(".BuildID with -export %q disagrees with 'go tool buildid' %q", buildID, toolBuildID)
1187 }
1188 }
1189
1190
1191 func TestUnsuccessfulGoInstallShouldMentionMissingPackage(t *testing.T) {
1192 tg := testgo(t)
1193 defer tg.cleanup()
1194 tg.parallel()
1195 tg.runFail("install", "foo/quxx")
1196 if tg.grepCountBoth(`cannot find package "foo/quxx" in any of`) != 1 {
1197 t.Error(`go install foo/quxx expected error: .*cannot find package "foo/quxx" in any of`)
1198 }
1199 }
1200
1201 func TestGOROOTSearchFailureReporting(t *testing.T) {
1202 tg := testgo(t)
1203 defer tg.cleanup()
1204 tg.parallel()
1205 tg.runFail("install", "foo/quxx")
1206 if tg.grepCountBoth(regexp.QuoteMeta(filepath.Join("foo", "quxx"))+` \(from \$GOROOT\)$`) != 1 {
1207 t.Error(`go install foo/quxx expected error: .*foo/quxx (from $GOROOT)`)
1208 }
1209 }
1210
1211 func TestMultipleGOPATHEntriesReportedSeparately(t *testing.T) {
1212 tg := testgo(t)
1213 defer tg.cleanup()
1214 tg.parallel()
1215 sep := string(filepath.ListSeparator)
1216 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata", "a")+sep+filepath.Join(tg.pwd(), "testdata", "b"))
1217 tg.runFail("install", "foo/quxx")
1218 if tg.grepCountBoth(`testdata[/\\].[/\\]src[/\\]foo[/\\]quxx`) != 2 {
1219 t.Error(`go install foo/quxx expected error: .*testdata/a/src/foo/quxx (from $GOPATH)\n.*testdata/b/src/foo/quxx`)
1220 }
1221 }
1222
1223
1224 func TestMentionGOPATHInFirstGOPATHEntry(t *testing.T) {
1225 tg := testgo(t)
1226 defer tg.cleanup()
1227 tg.parallel()
1228 sep := string(filepath.ListSeparator)
1229 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata", "a")+sep+filepath.Join(tg.pwd(), "testdata", "b"))
1230 tg.runFail("install", "foo/quxx")
1231 if tg.grepCountBoth(regexp.QuoteMeta(filepath.Join("testdata", "a", "src", "foo", "quxx"))+` \(from \$GOPATH\)$`) != 1 {
1232 t.Error(`go install foo/quxx expected error: .*testdata/a/src/foo/quxx (from $GOPATH)`)
1233 }
1234 }
1235
1236
1237 func TestMentionGOPATHNotOnSecondEntry(t *testing.T) {
1238 tg := testgo(t)
1239 defer tg.cleanup()
1240 tg.parallel()
1241 sep := string(filepath.ListSeparator)
1242 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata", "a")+sep+filepath.Join(tg.pwd(), "testdata", "b"))
1243 tg.runFail("install", "foo/quxx")
1244 if tg.grepCountBoth(regexp.QuoteMeta(filepath.Join("testdata", "b", "src", "foo", "quxx"))+`$`) != 1 {
1245 t.Error(`go install foo/quxx expected error: .*testdata/b/src/foo/quxx`)
1246 }
1247 }
1248
1249 func homeEnvName() string {
1250 switch runtime.GOOS {
1251 case "windows":
1252 return "USERPROFILE"
1253 case "plan9":
1254 return "home"
1255 default:
1256 return "HOME"
1257 }
1258 }
1259
1260 func tempEnvName() string {
1261 switch runtime.GOOS {
1262 case "windows":
1263 return "TMP"
1264 case "plan9":
1265 return "TMPDIR"
1266 default:
1267 return "TMPDIR"
1268 }
1269 }
1270
1271 func pathEnvName() string {
1272 switch runtime.GOOS {
1273 case "plan9":
1274 return "path"
1275 default:
1276 return "PATH"
1277 }
1278 }
1279
1280 func TestDefaultGOPATH(t *testing.T) {
1281 tg := testgo(t)
1282 defer tg.cleanup()
1283 tg.parallel()
1284 tg.tempDir("home/go")
1285 tg.setenv(homeEnvName(), tg.path("home"))
1286
1287 tg.run("env", "GOPATH")
1288 tg.grepStdout(regexp.QuoteMeta(tg.path("home/go")), "want GOPATH=$HOME/go")
1289
1290 tg.setenv("GOROOT", tg.path("home/go"))
1291 tg.run("env", "GOPATH")
1292 tg.grepStdoutNot(".", "want unset GOPATH because GOROOT=$HOME/go")
1293
1294 tg.setenv("GOROOT", tg.path("home/go")+"/")
1295 tg.run("env", "GOPATH")
1296 tg.grepStdoutNot(".", "want unset GOPATH because GOROOT=$HOME/go/")
1297 }
1298
1299 func TestDefaultGOPATHPrintedSearchList(t *testing.T) {
1300 tg := testgo(t)
1301 defer tg.cleanup()
1302 tg.parallel()
1303 tg.setenv("GOPATH", "")
1304 tg.tempDir("home")
1305 tg.setenv(homeEnvName(), tg.path("home"))
1306
1307 tg.runFail("install", "github.com/golang/example/hello")
1308 tg.grepStderr(regexp.QuoteMeta(tg.path("home/go/src/github.com/golang/example/hello"))+`.*from \$GOPATH`, "expected default GOPATH")
1309 }
1310
1311 func TestLdflagsArgumentsWithSpacesIssue3941(t *testing.T) {
1312 skipIfGccgo(t, "gccgo does not support -ldflags -X")
1313 tooSlow(t, "compiles and links a binary")
1314
1315 tg := testgo(t)
1316 defer tg.cleanup()
1317 tg.parallel()
1318 tg.tempFile("main.go", `package main
1319 var extern string
1320 func main() {
1321 println(extern)
1322 }`)
1323 tg.run("run", "-ldflags", `-X "main.extern=hello world"`, tg.path("main.go"))
1324 tg.grepStderr("^hello world", `ldflags -X "main.extern=hello world"' failed`)
1325 }
1326
1327 func TestLdFlagsLongArgumentsIssue42295(t *testing.T) {
1328
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