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