github.com/q45/go@v0.0.0-20151101211701-a4fb8c13db3f/src/cmd/go/go_test.go (about) 1 // Copyright 2015 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package main_test 6 7 import ( 8 "bytes" 9 "flag" 10 "fmt" 11 "go/build" 12 "go/format" 13 "internal/testenv" 14 "io" 15 "io/ioutil" 16 "os" 17 "os/exec" 18 "path/filepath" 19 "regexp" 20 "runtime" 21 "strconv" 22 "strings" 23 "testing" 24 "time" 25 ) 26 27 var ( 28 canRun = true // whether we can run go or ./testgo 29 canRace = false // whether we can run the race detector 30 canCgo = false // whether we can use cgo 31 32 exeSuffix string // ".exe" on Windows 33 34 skipExternal = false // skip external tests 35 ) 36 37 func init() { 38 switch runtime.GOOS { 39 case "android", "nacl": 40 canRun = false 41 case "darwin": 42 switch runtime.GOARCH { 43 case "arm", "arm64": 44 canRun = false 45 } 46 case "linux": 47 switch runtime.GOARCH { 48 case "arm": 49 // many linux/arm machines are too slow to run 50 // the full set of external tests. 51 skipExternal = true 52 } 53 case "freebsd": 54 switch runtime.GOARCH { 55 case "arm": 56 // many freebsd/arm machines are too slow to run 57 // the full set of external tests. 58 skipExternal = true 59 canRun = false 60 } 61 case "windows": 62 exeSuffix = ".exe" 63 } 64 } 65 66 // The TestMain function creates a go command for testing purposes and 67 // deletes it after the tests have been run. 68 func TestMain(m *testing.M) { 69 flag.Parse() 70 71 if canRun { 72 out, err := exec.Command("go", "build", "-tags", "testgo", "-o", "testgo"+exeSuffix).CombinedOutput() 73 if err != nil { 74 fmt.Fprintf(os.Stderr, "building testgo failed: %v\n%s", err, out) 75 os.Exit(2) 76 } 77 78 if out, err := exec.Command("./testgo"+exeSuffix, "env", "CGO_ENABLED").Output(); err != nil { 79 fmt.Fprintf(os.Stderr, "running testgo failed: %v\n", err) 80 canRun = false 81 } else { 82 canCgo, err = strconv.ParseBool(strings.TrimSpace(string(out))) 83 if err != nil { 84 fmt.Fprintf(os.Stderr, "can't parse go env CGO_ENABLED output: %v\n", strings.TrimSpace(string(out))) 85 } 86 } 87 88 switch runtime.GOOS { 89 case "linux", "darwin", "freebsd", "windows": 90 canRace = canCgo && runtime.GOARCH == "amd64" 91 } 92 93 measureTick("./testgo" + exeSuffix) 94 } 95 96 // Don't let these environment variables confuse the test. 97 os.Unsetenv("GOBIN") 98 os.Unsetenv("GOPATH") 99 100 r := m.Run() 101 102 if canRun { 103 os.Remove("testgo" + exeSuffix) 104 } 105 106 os.Exit(r) 107 } 108 109 // The length of an mtime tick on this system. This is an estimate of 110 // how long we need to sleep to ensure that the mtime of two files is 111 // different. 112 var mtimeTick time.Duration 113 114 // measureTick sets mtimeTick by looking at the rounding of the mtime 115 // of a file. 116 func measureTick(path string) { 117 st, err := os.Stat(path) 118 if err != nil { 119 // Default to one second, the most conservative value. 120 mtimeTick = time.Second 121 return 122 } 123 mtime := st.ModTime() 124 t := time.Microsecond 125 for mtime.Round(t).Equal(mtime) && t < time.Second { 126 t *= 10 127 } 128 mtimeTick = t 129 } 130 131 // Manage a single run of the testgo binary. 132 type testgoData struct { 133 t *testing.T 134 temps []string 135 wd string 136 env []string 137 tempdir string 138 ran bool 139 inParallel bool 140 stdout, stderr bytes.Buffer 141 } 142 143 // testgo sets up for a test that runs testgo. 144 func testgo(t *testing.T) *testgoData { 145 testenv.MustHaveGoBuild(t) 146 147 if skipExternal { 148 t.Skip("skipping external tests on %s/%s", runtime.GOOS, runtime.GOARCH) 149 } 150 151 return &testgoData{t: t} 152 } 153 154 // must gives a fatal error if err is not nil. 155 func (tg *testgoData) must(err error) { 156 if err != nil { 157 tg.t.Fatal(err) 158 } 159 } 160 161 // check gives a test non-fatal error if err is not nil. 162 func (tg *testgoData) check(err error) { 163 if err != nil { 164 tg.t.Error(err) 165 } 166 } 167 168 // parallel runs the test in parallel by calling t.Parallel. 169 func (tg *testgoData) parallel() { 170 if tg.ran { 171 tg.t.Fatal("internal testsuite error: call to parallel after run") 172 } 173 if tg.wd != "" { 174 tg.t.Fatal("internal testsuite error: call to parallel after cd") 175 } 176 for _, e := range tg.env { 177 if strings.HasPrefix(e, "GOROOT=") || strings.HasPrefix(e, "GOPATH=") || strings.HasPrefix(e, "GOBIN=") { 178 val := e[strings.Index(e, "=")+1:] 179 if strings.HasPrefix(val, "testdata") || strings.HasPrefix(val, "./testdata") { 180 tg.t.Fatalf("internal testsuite error: call to parallel with testdata in environment (%s)", e) 181 } 182 } 183 } 184 tg.inParallel = true 185 tg.t.Parallel() 186 } 187 188 // pwd returns the current directory. 189 func (tg *testgoData) pwd() string { 190 wd, err := os.Getwd() 191 if err != nil { 192 tg.t.Fatalf("could not get working directory: %v", err) 193 } 194 return wd 195 } 196 197 // cd changes the current directory to the named directory. Note that 198 // using this means that the test must not be run in parallel with any 199 // other tests. 200 func (tg *testgoData) cd(dir string) { 201 if tg.inParallel { 202 tg.t.Fatal("internal testsuite error: changing directory when running in parallel") 203 } 204 if tg.wd == "" { 205 tg.wd = tg.pwd() 206 } 207 abs, err := filepath.Abs(dir) 208 tg.must(os.Chdir(dir)) 209 if err == nil { 210 tg.setenv("PWD", abs) 211 } 212 } 213 214 // sleep sleeps for one tick, where a tick is a conservative estimate 215 // of how long it takes for a file modification to get a different 216 // mtime. 217 func (tg *testgoData) sleep() { 218 time.Sleep(mtimeTick) 219 } 220 221 // setenv sets an environment variable to use when running the test go 222 // command. 223 func (tg *testgoData) setenv(name, val string) { 224 if tg.inParallel && (name == "GOROOT" || name == "GOPATH" || name == "GOBIN") && (strings.HasPrefix(val, "testdata") || strings.HasPrefix(val, "./testdata")) { 225 tg.t.Fatalf("internal testsuite error: call to setenv with testdata (%s=%s) after parallel", name, val) 226 } 227 tg.unsetenv(name) 228 tg.env = append(tg.env, name+"="+val) 229 } 230 231 // unsetenv removes an environment variable. 232 func (tg *testgoData) unsetenv(name string) { 233 if tg.env == nil { 234 tg.env = append([]string(nil), os.Environ()...) 235 } 236 for i, v := range tg.env { 237 if strings.HasPrefix(v, name+"=") { 238 tg.env = append(tg.env[:i], tg.env[i+1:]...) 239 break 240 } 241 } 242 } 243 244 // doRun runs the test go command, recording stdout and stderr and 245 // returning exit status. 246 func (tg *testgoData) doRun(args []string) error { 247 if !canRun { 248 panic("testgoData.doRun called but canRun false") 249 } 250 if tg.inParallel { 251 for _, arg := range args { 252 if strings.HasPrefix(arg, "testdata") || strings.HasPrefix(arg, "./testdata") { 253 tg.t.Fatal("internal testsuite error: parallel run using testdata") 254 } 255 } 256 } 257 tg.t.Logf("running testgo %v", args) 258 var prog string 259 if tg.wd == "" { 260 prog = "./testgo" + exeSuffix 261 } else { 262 prog = filepath.Join(tg.wd, "testgo"+exeSuffix) 263 } 264 cmd := exec.Command(prog, args...) 265 tg.stdout.Reset() 266 tg.stderr.Reset() 267 cmd.Stdout = &tg.stdout 268 cmd.Stderr = &tg.stderr 269 cmd.Env = tg.env 270 status := cmd.Run() 271 if tg.stdout.Len() > 0 { 272 tg.t.Log("standard output:") 273 tg.t.Log(tg.stdout.String()) 274 } 275 if tg.stderr.Len() > 0 { 276 tg.t.Log("standard error:") 277 tg.t.Log(tg.stderr.String()) 278 } 279 tg.ran = true 280 return status 281 } 282 283 // run runs the test go command, and expects it to succeed. 284 func (tg *testgoData) run(args ...string) { 285 if status := tg.doRun(args); status != nil { 286 tg.t.Logf("go %v failed unexpectedly: %v", args, status) 287 tg.t.FailNow() 288 } 289 } 290 291 // runFail runs the test go command, and expects it to fail. 292 func (tg *testgoData) runFail(args ...string) { 293 if status := tg.doRun(args); status == nil { 294 tg.t.Fatal("testgo succeeded unexpectedly") 295 } else { 296 tg.t.Log("testgo failed as expected:", status) 297 } 298 } 299 300 // runGit runs a git command, and expects it to succeed. 301 func (tg *testgoData) runGit(dir string, args ...string) { 302 cmd := exec.Command("git", args...) 303 tg.stdout.Reset() 304 tg.stderr.Reset() 305 cmd.Stdout = &tg.stdout 306 cmd.Stderr = &tg.stderr 307 cmd.Dir = dir 308 cmd.Env = tg.env 309 status := cmd.Run() 310 if tg.stdout.Len() > 0 { 311 tg.t.Log("git standard output:") 312 tg.t.Log(tg.stdout.String()) 313 } 314 if tg.stderr.Len() > 0 { 315 tg.t.Log("git standard error:") 316 tg.t.Log(tg.stderr.String()) 317 } 318 if status != nil { 319 tg.t.Logf("git %v failed unexpectedly: %v", args, status) 320 tg.t.FailNow() 321 } 322 } 323 324 // getStdout returns standard output of the testgo run as a string. 325 func (tg *testgoData) getStdout() string { 326 if !tg.ran { 327 tg.t.Fatal("internal testsuite error: stdout called before run") 328 } 329 return tg.stdout.String() 330 } 331 332 // getStderr returns standard error of the testgo run as a string. 333 func (tg *testgoData) getStderr() string { 334 if !tg.ran { 335 tg.t.Fatal("internal testsuite error: stdout called before run") 336 } 337 return tg.stderr.String() 338 } 339 340 // doGrepMatch looks for a regular expression in a buffer, and returns 341 // whether it is found. The regular expression is matched against 342 // each line separately, as with the grep command. 343 func (tg *testgoData) doGrepMatch(match string, b *bytes.Buffer) bool { 344 if !tg.ran { 345 tg.t.Fatal("internal testsuite error: grep called before run") 346 } 347 re := regexp.MustCompile(match) 348 for _, ln := range bytes.Split(b.Bytes(), []byte{'\n'}) { 349 if re.Match(ln) { 350 return true 351 } 352 } 353 return false 354 } 355 356 // doGrep looks for a regular expression in a buffer and fails if it 357 // is not found. The name argument is the name of the output we are 358 // searching, "output" or "error". The msg argument is logged on 359 // failure. 360 func (tg *testgoData) doGrep(match string, b *bytes.Buffer, name, msg string) { 361 if !tg.doGrepMatch(match, b) { 362 tg.t.Log(msg) 363 tg.t.Logf("pattern %v not found in standard %s", match, name) 364 tg.t.FailNow() 365 } 366 } 367 368 // grepStdout looks for a regular expression in the test run's 369 // standard output and fails, logging msg, if it is not found. 370 func (tg *testgoData) grepStdout(match, msg string) { 371 tg.doGrep(match, &tg.stdout, "output", msg) 372 } 373 374 // grepStderr looks for a regular expression in the test run's 375 // standard error and fails, logging msg, if it is not found. 376 func (tg *testgoData) grepStderr(match, msg string) { 377 tg.doGrep(match, &tg.stderr, "error", msg) 378 } 379 380 // grepBoth looks for a regular expression in the test run's standard 381 // output or stand error and fails, logging msg, if it is not found. 382 func (tg *testgoData) grepBoth(match, msg string) { 383 if !tg.doGrepMatch(match, &tg.stdout) && !tg.doGrepMatch(match, &tg.stderr) { 384 tg.t.Log(msg) 385 tg.t.Logf("pattern %v not found in standard output or standard error", match) 386 tg.t.FailNow() 387 } 388 } 389 390 // doGrepNot looks for a regular expression in a buffer and fails if 391 // it is found. The name and msg arguments are as for doGrep. 392 func (tg *testgoData) doGrepNot(match string, b *bytes.Buffer, name, msg string) { 393 if tg.doGrepMatch(match, b) { 394 tg.t.Log(msg) 395 tg.t.Logf("pattern %v found unexpectedly in standard %s", match, name) 396 tg.t.FailNow() 397 } 398 } 399 400 // grepStdoutNot looks for a regular expression in the test run's 401 // standard output and fails, logging msg, if it is found. 402 func (tg *testgoData) grepStdoutNot(match, msg string) { 403 tg.doGrepNot(match, &tg.stdout, "output", msg) 404 } 405 406 // grepStderrNot looks for a regular expression in the test run's 407 // standard error and fails, logging msg, if it is found. 408 func (tg *testgoData) grepStderrNot(match, msg string) { 409 tg.doGrepNot(match, &tg.stderr, "error", msg) 410 } 411 412 // grepBothNot looks for a regular expression in the test run's 413 // standard output or stand error and fails, logging msg, if it is 414 // found. 415 func (tg *testgoData) grepBothNot(match, msg string) { 416 if tg.doGrepMatch(match, &tg.stdout) || tg.doGrepMatch(match, &tg.stderr) { 417 tg.t.Log(msg) 418 tg.t.Fatalf("pattern %v found unexpectedly in standard output or standard error", match) 419 } 420 } 421 422 // doGrepCount counts the number of times a regexp is seen in a buffer. 423 func (tg *testgoData) doGrepCount(match string, b *bytes.Buffer) int { 424 if !tg.ran { 425 tg.t.Fatal("internal testsuite error: doGrepCount called before run") 426 } 427 re := regexp.MustCompile(match) 428 c := 0 429 for _, ln := range bytes.Split(b.Bytes(), []byte{'\n'}) { 430 if re.Match(ln) { 431 c++ 432 } 433 } 434 return c 435 } 436 437 // grepCountStdout returns the number of times a regexp is seen in 438 // standard output. 439 func (tg *testgoData) grepCountStdout(match string) int { 440 return tg.doGrepCount(match, &tg.stdout) 441 } 442 443 // grepCountStderr returns the number of times a regexp is seen in 444 // standard error. 445 func (tg *testgoData) grepCountStderr(match string) int { 446 return tg.doGrepCount(match, &tg.stderr) 447 } 448 449 // grepCountBoth returns the number of times a regexp is seen in both 450 // standard output and standard error. 451 func (tg *testgoData) grepCountBoth(match string) int { 452 return tg.doGrepCount(match, &tg.stdout) + tg.doGrepCount(match, &tg.stderr) 453 } 454 455 // creatingTemp records that the test plans to create a temporary file 456 // or directory. If the file or directory exists already, it will be 457 // removed. When the test completes, the file or directory will be 458 // removed if it exists. 459 func (tg *testgoData) creatingTemp(path string) { 460 if filepath.IsAbs(path) && !strings.HasPrefix(path, tg.tempdir) { 461 tg.t.Fatalf("internal testsuite error: creatingTemp(%q) with absolute path not in temporary directory", path) 462 } 463 // If we have changed the working directory, make sure we have 464 // an absolute path, because we are going to change directory 465 // back before we remove the temporary. 466 if tg.wd != "" && !filepath.IsAbs(path) { 467 path = filepath.Join(tg.pwd(), path) 468 } 469 tg.must(os.RemoveAll(path)) 470 tg.temps = append(tg.temps, path) 471 } 472 473 // makeTempdir makes a temporary directory for a run of testgo. If 474 // the temporary directory was already created, this does nothing. 475 func (tg *testgoData) makeTempdir() { 476 if tg.tempdir == "" { 477 var err error 478 tg.tempdir, err = ioutil.TempDir("", "gotest") 479 tg.must(err) 480 } 481 } 482 483 // tempFile adds a temporary file for a run of testgo. 484 func (tg *testgoData) tempFile(path, contents string) { 485 tg.makeTempdir() 486 tg.must(os.MkdirAll(filepath.Join(tg.tempdir, filepath.Dir(path)), 0755)) 487 bytes := []byte(contents) 488 if strings.HasSuffix(path, ".go") { 489 formatted, err := format.Source(bytes) 490 if err == nil { 491 bytes = formatted 492 } 493 } 494 tg.must(ioutil.WriteFile(filepath.Join(tg.tempdir, path), bytes, 0644)) 495 } 496 497 // tempDir adds a temporary directory for a run of testgo. 498 func (tg *testgoData) tempDir(path string) { 499 tg.makeTempdir() 500 if err := os.MkdirAll(filepath.Join(tg.tempdir, path), 0755); err != nil && !os.IsExist(err) { 501 tg.t.Fatal(err) 502 } 503 } 504 505 // path returns the absolute pathname to file with the temporary 506 // directory. 507 func (tg *testgoData) path(name string) string { 508 if tg.tempdir == "" { 509 tg.t.Fatalf("internal testsuite error: path(%q) with no tempdir", name) 510 } 511 if name == "." { 512 return tg.tempdir 513 } 514 return filepath.Join(tg.tempdir, name) 515 } 516 517 // mustNotExist fails if path exists. 518 func (tg *testgoData) mustNotExist(path string) { 519 if _, err := os.Stat(path); err == nil || !os.IsNotExist(err) { 520 tg.t.Fatalf("%s exists but should not (%v)", path, err) 521 } 522 } 523 524 // wantExecutable fails with msg if path is not executable. 525 func (tg *testgoData) wantExecutable(path, msg string) { 526 if st, err := os.Stat(path); err != nil { 527 if !os.IsNotExist(err) { 528 tg.t.Log(err) 529 } 530 tg.t.Fatal(msg) 531 } else { 532 if runtime.GOOS != "windows" && st.Mode()&0111 == 0 { 533 tg.t.Fatalf("binary %s exists but is not executable", path) 534 } 535 } 536 } 537 538 // wantArchive fails if path is not an archive. 539 func (tg *testgoData) wantArchive(path string) { 540 f, err := os.Open(path) 541 if err != nil { 542 tg.t.Fatal(err) 543 } 544 buf := make([]byte, 100) 545 io.ReadFull(f, buf) 546 f.Close() 547 if !bytes.HasPrefix(buf, []byte("!<arch>\n")) { 548 tg.t.Fatalf("file %s exists but is not an archive", path) 549 } 550 } 551 552 // isStale returns whether pkg is stale. 553 func (tg *testgoData) isStale(pkg string) bool { 554 tg.run("list", "-f", "{{.Stale}}", pkg) 555 switch v := strings.TrimSpace(tg.getStdout()); v { 556 case "true": 557 return true 558 case "false": 559 return false 560 default: 561 tg.t.Fatalf("unexpected output checking staleness of package %v: %v", pkg, v) 562 panic("unreachable") 563 } 564 } 565 566 // wantStale fails with msg if pkg is not stale. 567 func (tg *testgoData) wantStale(pkg, msg string) { 568 if !tg.isStale(pkg) { 569 tg.t.Fatal(msg) 570 } 571 } 572 573 // wantNotStale fails with msg if pkg is stale. 574 func (tg *testgoData) wantNotStale(pkg, msg string) { 575 if tg.isStale(pkg) { 576 tg.t.Fatal(msg) 577 } 578 } 579 580 // cleanup cleans up a test that runs testgo. 581 func (tg *testgoData) cleanup() { 582 if tg.wd != "" { 583 if err := os.Chdir(tg.wd); err != nil { 584 // We are unlikely to be able to continue. 585 fmt.Fprintln(os.Stderr, "could not restore working directory, crashing:", err) 586 os.Exit(2) 587 } 588 } 589 for _, path := range tg.temps { 590 tg.check(os.RemoveAll(path)) 591 } 592 if tg.tempdir != "" { 593 tg.check(os.RemoveAll(tg.tempdir)) 594 } 595 } 596 597 // resetReadOnlyFlagAll resets windows read-only flag 598 // set on path and any children it contains. 599 // The flag is set by git and has to be removed. 600 // os.Remove refuses to remove files with read-only flag set. 601 func (tg *testgoData) resetReadOnlyFlagAll(path string) { 602 fi, err := os.Stat(path) 603 if err != nil { 604 tg.t.Fatalf("resetReadOnlyFlagAll(%q) failed: %v", path, err) 605 } 606 if !fi.IsDir() { 607 err := os.Chmod(path, 0666) 608 if err != nil { 609 tg.t.Fatalf("resetReadOnlyFlagAll(%q) failed: %v", path, err) 610 } 611 } 612 fd, err := os.Open(path) 613 if err != nil { 614 tg.t.Fatalf("resetReadOnlyFlagAll(%q) failed: %v", path, err) 615 } 616 defer fd.Close() 617 names, _ := fd.Readdirnames(-1) 618 for _, name := range names { 619 tg.resetReadOnlyFlagAll(path + string(filepath.Separator) + name) 620 } 621 } 622 623 // failSSH puts an ssh executable in the PATH that always fails. 624 // This is to stub out uses of ssh by go get. 625 func (tg *testgoData) failSSH() { 626 wd, err := os.Getwd() 627 if err != nil { 628 tg.t.Fatal(err) 629 } 630 fail := filepath.Join(wd, "testdata/failssh") 631 tg.setenv("PATH", fmt.Sprintf("%v%c%v", fail, filepath.ListSeparator, os.Getenv("PATH"))) 632 } 633 634 func TestFileLineInErrorMessages(t *testing.T) { 635 tg := testgo(t) 636 defer tg.cleanup() 637 tg.parallel() 638 tg.tempFile("err.go", `package main; import "bar"`) 639 path := tg.path("err.go") 640 tg.runFail("run", path) 641 shortPath := path 642 if rel, err := filepath.Rel(tg.pwd(), path); err == nil && len(rel) < len(path) { 643 shortPath = rel 644 } 645 tg.grepStderr("^"+regexp.QuoteMeta(shortPath)+":", "missing file:line in error message") 646 } 647 648 func TestProgramNameInCrashMessages(t *testing.T) { 649 tg := testgo(t) 650 defer tg.cleanup() 651 tg.parallel() 652 tg.tempFile("triv.go", `package main; func main() {}`) 653 tg.runFail("build", "-ldflags", "-crash_for_testing", tg.path("triv.go")) 654 tg.grepStderr(`[/\\]tool[/\\].*[/\\]link`, "missing linker name in error message") 655 } 656 657 func TestBrokenTestsWithoutTestFunctionsAllFail(t *testing.T) { 658 tg := testgo(t) 659 defer tg.cleanup() 660 tg.runFail("test", "./testdata/src/badtest/...") 661 tg.grepBothNot("^ok", "test passed unexpectedly") 662 tg.grepBoth("FAIL.*badtest/badexec", "test did not run everything") 663 tg.grepBoth("FAIL.*badtest/badsyntax", "test did not run everything") 664 tg.grepBoth("FAIL.*badtest/badvar", "test did not run everything") 665 } 666 667 func TestGoBuildDashAInDevBranch(t *testing.T) { 668 if testing.Short() { 669 t.Skip("don't rebuild the standard library in short mode") 670 } 671 672 tg := testgo(t) 673 defer tg.cleanup() 674 tg.run("install", "math") // should be up to date already but just in case 675 tg.setenv("TESTGO_IS_GO_RELEASE", "0") 676 tg.run("build", "-v", "-a", "math") 677 tg.grepStderr("runtime", "testgo build -a math in dev branch DID NOT build runtime, but should have") 678 } 679 680 func TestGoBuildDashAInReleaseBranch(t *testing.T) { 681 if testing.Short() { 682 t.Skip("don't rebuild the standard library in short mode") 683 } 684 685 tg := testgo(t) 686 defer tg.cleanup() 687 tg.run("install", "math") // should be up to date already but just in case 688 tg.setenv("TESTGO_IS_GO_RELEASE", "1") 689 tg.run("build", "-v", "-a", "math") 690 tg.grepStderr("runtime", "testgo build -a math in dev branch did not build runtime, but should have") 691 } 692 693 func TestGoInstallCleansUpAfterGoBuild(t *testing.T) { 694 tg := testgo(t) 695 defer tg.cleanup() 696 tg.tempFile("src/mycmd/main.go", `package main; func main(){}`) 697 tg.setenv("GOPATH", tg.path(".")) 698 tg.cd(tg.path("src/mycmd")) 699 700 doesNotExist := func(file, msg string) { 701 if _, err := os.Stat(file); err == nil { 702 t.Fatal(msg) 703 } else if !os.IsNotExist(err) { 704 t.Fatal(msg, "error:", err) 705 } 706 } 707 708 tg.run("build") 709 tg.wantExecutable("mycmd"+exeSuffix, "testgo build did not write command binary") 710 tg.run("install") 711 doesNotExist("mycmd"+exeSuffix, "testgo install did not remove command binary") 712 tg.run("build") 713 tg.wantExecutable("mycmd"+exeSuffix, "testgo build did not write command binary (second time)") 714 // Running install with arguments does not remove the target, 715 // even in the same directory. 716 tg.run("install", "mycmd") 717 tg.wantExecutable("mycmd"+exeSuffix, "testgo install mycmd removed command binary when run in mycmd") 718 tg.run("build") 719 tg.wantExecutable("mycmd"+exeSuffix, "testgo build did not write command binary (third time)") 720 // And especially not outside the directory. 721 tg.cd(tg.path(".")) 722 if data, err := ioutil.ReadFile("src/mycmd/mycmd" + exeSuffix); err != nil { 723 t.Fatal("could not read file:", err) 724 } else { 725 if err := ioutil.WriteFile("mycmd"+exeSuffix, data, 0555); err != nil { 726 t.Fatal("could not write file:", err) 727 } 728 } 729 tg.run("install", "mycmd") 730 tg.wantExecutable("src/mycmd/mycmd"+exeSuffix, "testgo install mycmd removed command binary from its source dir when run outside mycmd") 731 tg.wantExecutable("mycmd"+exeSuffix, "testgo install mycmd removed command binary from current dir when run outside mycmd") 732 } 733 734 func TestGoInstallRebuildsStalePackagesInOtherGOPATH(t *testing.T) { 735 tg := testgo(t) 736 defer tg.cleanup() 737 tg.parallel() 738 tg.tempFile("d1/src/p1/p1.go", `package p1 739 import "p2" 740 func F() { p2.F() }`) 741 tg.tempFile("d2/src/p2/p2.go", `package p2 742 func F() {}`) 743 sep := string(filepath.ListSeparator) 744 tg.setenv("GOPATH", tg.path("d1")+sep+tg.path("d2")) 745 tg.run("install", "p1") 746 tg.wantNotStale("p1", "./testgo list mypkg claims p1 is stale, incorrectly") 747 tg.wantNotStale("p2", "./testgo list mypkg claims p2 is stale, incorrectly") 748 tg.sleep() 749 if f, err := os.OpenFile(tg.path("d2/src/p2/p2.go"), os.O_WRONLY|os.O_APPEND, 0); err != nil { 750 t.Fatal(err) 751 } else if _, err = f.WriteString(`func G() {}`); err != nil { 752 t.Fatal(err) 753 } else { 754 tg.must(f.Close()) 755 } 756 tg.wantStale("p2", "./testgo list mypkg claims p2 is NOT stale, incorrectly") 757 tg.wantStale("p1", "./testgo list mypkg claims p1 is NOT stale, incorrectly") 758 759 tg.run("install", "p1") 760 tg.wantNotStale("p2", "./testgo list mypkg claims p2 is stale after reinstall, incorrectly") 761 tg.wantNotStale("p1", "./testgo list mypkg claims p1 is stale after reinstall, incorrectly") 762 } 763 764 func TestGoInstallDetectsRemovedFiles(t *testing.T) { 765 tg := testgo(t) 766 defer tg.cleanup() 767 tg.parallel() 768 tg.tempFile("src/mypkg/x.go", `package mypkg`) 769 tg.tempFile("src/mypkg/y.go", `package mypkg`) 770 tg.tempFile("src/mypkg/z.go", `// +build missingtag 771 772 package mypkg`) 773 tg.setenv("GOPATH", tg.path(".")) 774 tg.run("install", "mypkg") 775 tg.wantNotStale("mypkg", "./testgo list mypkg claims mypkg is stale, incorrectly") 776 // z.go was not part of the build; removing it is okay. 777 tg.must(os.Remove(tg.path("src/mypkg/z.go"))) 778 tg.wantNotStale("mypkg", "./testgo list mypkg claims mypkg is stale after removing z.go; should not be stale") 779 // y.go was part of the package; removing it should be detected. 780 tg.must(os.Remove(tg.path("src/mypkg/y.go"))) 781 tg.wantStale("mypkg", "./testgo list mypkg claims mypkg is NOT stale after removing y.go; should be stale") 782 } 783 784 func TestGoInstallErrorOnCrossCompileToBin(t *testing.T) { 785 if testing.Short() { 786 t.Skip("don't install into GOROOT in short mode") 787 } 788 789 tg := testgo(t) 790 defer tg.cleanup() 791 tg.tempFile("src/mycmd/x.go", `package main 792 func main() {}`) 793 tg.setenv("GOPATH", tg.path(".")) 794 tg.cd(tg.path("src/mycmd")) 795 796 tg.run("build", "mycmd") 797 798 goarch := "386" 799 if runtime.GOARCH == "386" { 800 goarch = "amd64" 801 } 802 tg.setenv("GOOS", "linux") 803 tg.setenv("GOARCH", goarch) 804 tg.run("install", "mycmd") 805 tg.setenv("GOBIN", tg.path(".")) 806 tg.runFail("install", "mycmd") 807 tg.run("install", "cmd/pack") 808 } 809 810 func TestGoInstallDetectsRemovedFilesInPackageMain(t *testing.T) { 811 tg := testgo(t) 812 defer tg.cleanup() 813 tg.parallel() 814 tg.tempFile("src/mycmd/x.go", `package main 815 func main() {}`) 816 tg.tempFile("src/mycmd/y.go", `package main`) 817 tg.tempFile("src/mycmd/z.go", `// +build missingtag 818 819 package main`) 820 tg.setenv("GOPATH", tg.path(".")) 821 tg.run("install", "mycmd") 822 tg.wantNotStale("mycmd", "./testgo list mypkg claims mycmd is stale, incorrectly") 823 // z.go was not part of the build; removing it is okay. 824 tg.must(os.Remove(tg.path("src/mycmd/z.go"))) 825 tg.wantNotStale("mycmd", "./testgo list mycmd claims mycmd is stale after removing z.go; should not be stale") 826 // y.go was part of the package; removing it should be detected. 827 tg.must(os.Remove(tg.path("src/mycmd/y.go"))) 828 tg.wantStale("mycmd", "./testgo list mycmd claims mycmd is NOT stale after removing y.go; should be stale") 829 } 830 831 func testLocalRun(tg *testgoData, exepath, local, match string) { 832 out, err := exec.Command(exepath).Output() 833 if err != nil { 834 tg.t.Fatalf("error running %v: %v", exepath, err) 835 } 836 if !regexp.MustCompile(match).Match(out) { 837 tg.t.Log(string(out)) 838 tg.t.Errorf("testdata/%s/easy.go did not generate expected output", local) 839 } 840 } 841 842 func testLocalEasy(tg *testgoData, local string) { 843 exepath := "./easy" + exeSuffix 844 tg.creatingTemp(exepath) 845 tg.run("build", "-o", exepath, filepath.Join("testdata", local, "easy.go")) 846 testLocalRun(tg, exepath, local, `(?m)^easysub\.Hello`) 847 } 848 849 func testLocalEasySub(tg *testgoData, local string) { 850 exepath := "./easysub" + exeSuffix 851 tg.creatingTemp(exepath) 852 tg.run("build", "-o", exepath, filepath.Join("testdata", local, "easysub", "main.go")) 853 testLocalRun(tg, exepath, local, `(?m)^easysub\.Hello`) 854 } 855 856 func testLocalHard(tg *testgoData, local string) { 857 exepath := "./hard" + exeSuffix 858 tg.creatingTemp(exepath) 859 tg.run("build", "-o", exepath, filepath.Join("testdata", local, "hard.go")) 860 testLocalRun(tg, exepath, local, `(?m)^sub\.Hello`) 861 } 862 863 func testLocalInstall(tg *testgoData, local string) { 864 tg.runFail("install", filepath.Join("testdata", local, "easy.go")) 865 } 866 867 func TestLocalImportsEasy(t *testing.T) { 868 tg := testgo(t) 869 defer tg.cleanup() 870 testLocalEasy(tg, "local") 871 } 872 873 func TestLocalImportsEasySub(t *testing.T) { 874 tg := testgo(t) 875 defer tg.cleanup() 876 testLocalEasySub(tg, "local") 877 } 878 879 func TestLocalImportsHard(t *testing.T) { 880 tg := testgo(t) 881 defer tg.cleanup() 882 testLocalHard(tg, "local") 883 } 884 885 func TestLocalImportsGoInstallShouldFail(t *testing.T) { 886 tg := testgo(t) 887 defer tg.cleanup() 888 testLocalInstall(tg, "local") 889 } 890 891 const badDirName = `#$%:, &()*;<=>?\^{}` 892 893 func copyBad(tg *testgoData) { 894 if runtime.GOOS == "windows" { 895 tg.t.Skipf("skipping test because %q is an invalid directory name", badDirName) 896 } 897 898 tg.must(filepath.Walk("testdata/local", 899 func(path string, info os.FileInfo, err error) error { 900 if err != nil { 901 return err 902 } 903 if info.IsDir() { 904 return nil 905 } 906 var data []byte 907 data, err = ioutil.ReadFile(path) 908 if err != nil { 909 return err 910 } 911 newpath := strings.Replace(path, "local", badDirName, 1) 912 tg.tempFile(newpath, string(data)) 913 return nil 914 })) 915 tg.cd(tg.path(".")) 916 } 917 918 func TestBadImportsEasy(t *testing.T) { 919 tg := testgo(t) 920 defer tg.cleanup() 921 copyBad(tg) 922 testLocalEasy(tg, badDirName) 923 } 924 925 func TestBadImportsEasySub(t *testing.T) { 926 tg := testgo(t) 927 defer tg.cleanup() 928 copyBad(tg) 929 testLocalEasySub(tg, badDirName) 930 } 931 932 func TestBadImportsHard(t *testing.T) { 933 tg := testgo(t) 934 defer tg.cleanup() 935 copyBad(tg) 936 testLocalHard(tg, badDirName) 937 } 938 939 func TestBadImportsGoInstallShouldFail(t *testing.T) { 940 tg := testgo(t) 941 defer tg.cleanup() 942 copyBad(tg) 943 testLocalInstall(tg, badDirName) 944 } 945 946 func TestInternalPackagesInGOROOTAreRespected(t *testing.T) { 947 tg := testgo(t) 948 defer tg.cleanup() 949 tg.runFail("build", "-v", "./testdata/testinternal") 950 tg.grepBoth("use of internal package not allowed", "wrong error message for testdata/testinternal") 951 } 952 953 func TestInternalPackagesOutsideGOROOTAreRespected(t *testing.T) { 954 tg := testgo(t) 955 defer tg.cleanup() 956 tg.runFail("build", "-v", "./testdata/testinternal2") 957 tg.grepBoth("use of internal package not allowed", "wrote error message for testdata/testinternal2") 958 } 959 960 func testMove(t *testing.T, vcs, url, base, config string) { 961 testenv.MustHaveExternalNetwork(t) 962 963 tg := testgo(t) 964 defer tg.cleanup() 965 tg.parallel() 966 tg.tempDir("src") 967 tg.setenv("GOPATH", tg.path(".")) 968 tg.run("get", "-d", url) 969 tg.run("get", "-d", "-u", url) 970 switch vcs { 971 case "svn": 972 // SVN doesn't believe in text files so we can't just edit the config. 973 // Check out a different repo into the wrong place. 974 tg.must(os.RemoveAll(tg.path("src/code.google.com/p/rsc-svn"))) 975 tg.run("get", "-d", "-u", "code.google.com/p/rsc-svn2/trunk") 976 tg.must(os.Rename(tg.path("src/code.google.com/p/rsc-svn2"), tg.path("src/code.google.com/p/rsc-svn"))) 977 default: 978 path := tg.path(filepath.Join("src", config)) 979 data, err := ioutil.ReadFile(path) 980 tg.must(err) 981 data = bytes.Replace(data, []byte(base), []byte(base+"XXX"), -1) 982 tg.must(ioutil.WriteFile(path, data, 0644)) 983 } 984 if vcs == "git" { 985 // git will ask for a username and password when we 986 // run go get -d -f -u. An empty username and 987 // password will work. Prevent asking by setting 988 // GIT_ASKPASS. 989 tg.creatingTemp("sink" + exeSuffix) 990 tg.tempFile("src/sink/sink.go", `package main; func main() {}`) 991 tg.run("build", "-o", "sink"+exeSuffix, "sink") 992 tg.setenv("GIT_ASKPASS", filepath.Join(tg.pwd(), "sink"+exeSuffix)) 993 } 994 tg.runFail("get", "-d", "-u", url) 995 tg.grepStderr("is a custom import path for", "go get -d -u "+url+" failed for wrong reason") 996 tg.runFail("get", "-d", "-f", "-u", url) 997 tg.grepStderr("validating server certificate|not found", "go get -d -f -u "+url+" failed for wrong reason") 998 } 999 1000 func TestInternalPackageErrorsAreHandled(t *testing.T) { 1001 tg := testgo(t) 1002 defer tg.cleanup() 1003 tg.run("list", "./testdata/testinternal3") 1004 } 1005 1006 func TestInternalCache(t *testing.T) { 1007 tg := testgo(t) 1008 defer tg.cleanup() 1009 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/testinternal4")) 1010 tg.runFail("build", "p") 1011 tg.grepStderr("internal", "did not fail to build p") 1012 } 1013 1014 func TestMoveGit(t *testing.T) { 1015 testMove(t, "git", "rsc.io/pdf", "pdf", "rsc.io/pdf/.git/config") 1016 } 1017 1018 // TODO(rsc): Set up a test case on bitbucket for hg. 1019 // func TestMoveHG(t *testing.T) { 1020 // testMove(t, "hg", "rsc.io/x86/x86asm", "x86", "rsc.io/x86/.hg/hgrc") 1021 // } 1022 1023 // TODO(rsc): Set up a test case on SourceForge (?) for svn. 1024 // func testMoveSVN(t *testing.T) { 1025 // testMove(t, "svn", "code.google.com/p/rsc-svn/trunk", "-", "-") 1026 // } 1027 1028 func TestImportCommandMatch(t *testing.T) { 1029 tg := testgo(t) 1030 defer tg.cleanup() 1031 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/importcom")) 1032 tg.run("build", "./testdata/importcom/works.go") 1033 } 1034 1035 func TestImportCommentMismatch(t *testing.T) { 1036 tg := testgo(t) 1037 defer tg.cleanup() 1038 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/importcom")) 1039 tg.runFail("build", "./testdata/importcom/wrongplace.go") 1040 tg.grepStderr(`wrongplace expects import "my/x"`, "go build did not mention incorrect import") 1041 } 1042 1043 func TestImportCommentSyntaxError(t *testing.T) { 1044 tg := testgo(t) 1045 defer tg.cleanup() 1046 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/importcom")) 1047 tg.runFail("build", "./testdata/importcom/bad.go") 1048 tg.grepStderr("cannot parse import comment", "go build did not mention syntax error") 1049 } 1050 1051 func TestImportCommentConflict(t *testing.T) { 1052 tg := testgo(t) 1053 defer tg.cleanup() 1054 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/importcom")) 1055 tg.runFail("build", "./testdata/importcom/conflict.go") 1056 tg.grepStderr("found import comments", "go build did not mention comment conflict") 1057 } 1058 1059 // cmd/go: custom import path checking should not apply to github.com/xxx/yyy. 1060 func TestIssue10952(t *testing.T) { 1061 testenv.MustHaveExternalNetwork(t) 1062 1063 if _, err := exec.LookPath("git"); err != nil { 1064 t.Skip("skipping because git binary not found") 1065 } 1066 1067 tg := testgo(t) 1068 defer tg.cleanup() 1069 tg.parallel() 1070 tg.tempDir("src") 1071 tg.setenv("GOPATH", tg.path(".")) 1072 const importPath = "github.com/zombiezen/go-get-issue-10952" 1073 tg.run("get", "-d", "-u", importPath) 1074 repoDir := tg.path("src/" + importPath) 1075 defer tg.resetReadOnlyFlagAll(repoDir) 1076 tg.runGit(repoDir, "remote", "set-url", "origin", "https://"+importPath+".git") 1077 tg.run("get", "-d", "-u", importPath) 1078 } 1079 1080 func TestDisallowedCSourceFiles(t *testing.T) { 1081 tg := testgo(t) 1082 defer tg.cleanup() 1083 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) 1084 tg.runFail("build", "badc") 1085 tg.grepStderr("C source files not allowed", "go test did not say C source files not allowed") 1086 } 1087 1088 func TestErrorMessageForSyntaxErrorInTestGoFileSaysFAIL(t *testing.T) { 1089 tg := testgo(t) 1090 defer tg.cleanup() 1091 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) 1092 tg.runFail("test", "syntaxerror") 1093 tg.grepStderr("FAIL", "go test did not say FAIL") 1094 } 1095 1096 func TestWildcardsDoNotLookInUselessDirectories(t *testing.T) { 1097 tg := testgo(t) 1098 defer tg.cleanup() 1099 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) 1100 tg.runFail("list", "...") 1101 tg.grepBoth("badpkg", "go list ... failure does not mention badpkg") 1102 tg.run("list", "m...") 1103 } 1104 1105 func TestRelativeImportsGoTest(t *testing.T) { 1106 tg := testgo(t) 1107 defer tg.cleanup() 1108 tg.run("test", "./testdata/testimport") 1109 } 1110 1111 func TestRelativeImportsGoTestDashI(t *testing.T) { 1112 tg := testgo(t) 1113 defer tg.cleanup() 1114 tg.run("test", "-i", "./testdata/testimport") 1115 } 1116 1117 func TestRelativeImportsInCommandLinePackage(t *testing.T) { 1118 tg := testgo(t) 1119 defer tg.cleanup() 1120 files, err := filepath.Glob("./testdata/testimport/*.go") 1121 tg.must(err) 1122 tg.run(append([]string{"test"}, files...)...) 1123 } 1124 1125 func TestVersionControlErrorMessageIncludesCorrectDirectory(t *testing.T) { 1126 tg := testgo(t) 1127 defer tg.cleanup() 1128 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/shadow/root1")) 1129 tg.runFail("get", "-u", "foo") 1130 1131 // TODO(iant): We should not have to use strconv.Quote here. 1132 // The code in vcs.go should be changed so that it is not required. 1133 quoted := strconv.Quote(filepath.Join("testdata", "shadow", "root1", "src", "foo")) 1134 quoted = quoted[1 : len(quoted)-1] 1135 1136 tg.grepStderr(regexp.QuoteMeta(quoted), "go get -u error does not mention shadow/root1/src/foo") 1137 } 1138 1139 func TestInstallFailsWithNoBuildableFiles(t *testing.T) { 1140 tg := testgo(t) 1141 defer tg.cleanup() 1142 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) 1143 tg.setenv("CGO_ENABLED", "0") 1144 tg.runFail("install", "cgotest") 1145 tg.grepStderr("no buildable Go source files", "go install cgotest did not report 'no buildable Go Source files'") 1146 } 1147 1148 func TestRelativeGOBINFail(t *testing.T) { 1149 tg := testgo(t) 1150 defer tg.cleanup() 1151 tg.tempFile("triv.go", `package main; func main() {}`) 1152 tg.setenv("GOBIN", ".") 1153 tg.runFail("install") 1154 tg.grepStderr("cannot install, GOBIN must be an absolute path", "go install must fail if $GOBIN is a relative path") 1155 } 1156 1157 // Test that without $GOBIN set, binaries get installed 1158 // into the GOPATH bin directory. 1159 func TestInstallIntoGOPATH(t *testing.T) { 1160 tg := testgo(t) 1161 defer tg.cleanup() 1162 tg.creatingTemp("testdata/bin/go-cmd-test" + exeSuffix) 1163 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) 1164 tg.run("install", "go-cmd-test") 1165 tg.wantExecutable("testdata/bin/go-cmd-test"+exeSuffix, "go install go-cmd-test did not write to testdata/bin/go-cmd-test") 1166 } 1167 1168 func TestPackageMainTestImportsArchiveNotBinary(t *testing.T) { 1169 tg := testgo(t) 1170 defer tg.cleanup() 1171 gobin := filepath.Join(tg.pwd(), "testdata", "bin") 1172 tg.creatingTemp(gobin) 1173 tg.setenv("GOBIN", gobin) 1174 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) 1175 tg.must(os.Chtimes("./testdata/src/main_test/m.go", time.Now(), time.Now())) 1176 tg.sleep() 1177 tg.run("test", "main_test") 1178 tg.run("install", "main_test") 1179 tg.wantNotStale("main_test", "after go install, main listed as stale") 1180 tg.run("test", "main_test") 1181 } 1182 1183 // With $GOBIN set, binaries get installed to $GOBIN. 1184 func TestInstallIntoGOBIN(t *testing.T) { 1185 tg := testgo(t) 1186 defer tg.cleanup() 1187 gobin := filepath.Join(tg.pwd(), "testdata", "bin1") 1188 tg.creatingTemp(gobin) 1189 tg.setenv("GOBIN", gobin) 1190 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) 1191 tg.run("install", "go-cmd-test") 1192 tg.wantExecutable("testdata/bin1/go-cmd-test"+exeSuffix, "go install go-cmd-test did not write to testdata/bin1/go-cmd-test") 1193 } 1194 1195 // Issue 11065 1196 func TestInstallToCurrentDirectoryCreatesExecutable(t *testing.T) { 1197 tg := testgo(t) 1198 defer tg.cleanup() 1199 pkg := filepath.Join(tg.pwd(), "testdata", "src", "go-cmd-test") 1200 tg.creatingTemp(filepath.Join(pkg, "go-cmd-test"+exeSuffix)) 1201 tg.setenv("GOBIN", pkg) 1202 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) 1203 tg.cd(pkg) 1204 tg.run("install") 1205 tg.wantExecutable("go-cmd-test"+exeSuffix, "go install did not write to current directory") 1206 } 1207 1208 // Without $GOBIN set, installing a program outside $GOPATH should fail 1209 // (there is nowhere to install it). 1210 func TestInstallWithoutDestinationFails(t *testing.T) { 1211 tg := testgo(t) 1212 defer tg.cleanup() 1213 tg.runFail("install", "testdata/src/go-cmd-test/helloworld.go") 1214 tg.grepStderr("no install location for .go files listed on command line", "wrong error") 1215 } 1216 1217 // With $GOBIN set, should install there. 1218 func TestInstallToGOBINCommandLinePackage(t *testing.T) { 1219 tg := testgo(t) 1220 defer tg.cleanup() 1221 gobin := filepath.Join(tg.pwd(), "testdata", "bin1") 1222 tg.creatingTemp(gobin) 1223 tg.setenv("GOBIN", gobin) 1224 tg.run("install", "testdata/src/go-cmd-test/helloworld.go") 1225 tg.wantExecutable("testdata/bin1/helloworld"+exeSuffix, "go install testdata/src/go-cmd-test/helloworld.go did not write testdata/bin1/helloworld") 1226 } 1227 1228 func TestGodocInstalls(t *testing.T) { 1229 testenv.MustHaveExternalNetwork(t) 1230 1231 // godoc installs into GOBIN 1232 tg := testgo(t) 1233 defer tg.cleanup() 1234 tg.parallel() 1235 tg.tempDir("gobin") 1236 tg.setenv("GOPATH", tg.path(".")) 1237 tg.setenv("GOBIN", tg.path("gobin")) 1238 tg.run("get", "golang.org/x/tools/cmd/godoc") 1239 tg.wantExecutable(tg.path("gobin/godoc"), "did not install godoc to $GOBIN") 1240 tg.unsetenv("GOBIN") 1241 1242 // godoc installs into GOROOT 1243 goroot := runtime.GOROOT() 1244 tg.setenv("GOROOT", goroot) 1245 tg.check(os.RemoveAll(filepath.Join(goroot, "bin", "godoc"))) 1246 tg.run("install", "golang.org/x/tools/cmd/godoc") 1247 tg.wantExecutable(filepath.Join(goroot, "bin", "godoc"), "did not install godoc to $GOROOT/bin") 1248 } 1249 1250 func TestGoGetNonPkg(t *testing.T) { 1251 testenv.MustHaveExternalNetwork(t) 1252 1253 tg := testgo(t) 1254 defer tg.cleanup() 1255 tg.tempDir("gobin") 1256 tg.setenv("GOPATH", tg.path(".")) 1257 tg.setenv("GOBIN", tg.path("gobin")) 1258 tg.runFail("get", "-d", "golang.org/x/tools") 1259 tg.grepStderr("golang.org/x/tools: no buildable Go source files", "missing error") 1260 tg.runFail("get", "-d", "-u", "golang.org/x/tools") 1261 tg.grepStderr("golang.org/x/tools: no buildable Go source files", "missing error") 1262 tg.runFail("get", "-d", "golang.org/x/tools") 1263 tg.grepStderr("golang.org/x/tools: no buildable Go source files", "missing error") 1264 } 1265 1266 func TestInstalls(t *testing.T) { 1267 if testing.Short() { 1268 t.Skip("don't install into GOROOT in short mode") 1269 } 1270 1271 tg := testgo(t) 1272 defer tg.cleanup() 1273 tg.parallel() 1274 tg.tempDir("gobin") 1275 tg.setenv("GOPATH", tg.path(".")) 1276 goroot := runtime.GOROOT() 1277 tg.setenv("GOROOT", goroot) 1278 1279 // cmd/fix installs into tool 1280 tg.run("env", "GOOS") 1281 goos := strings.TrimSpace(tg.getStdout()) 1282 tg.setenv("GOOS", goos) 1283 tg.run("env", "GOARCH") 1284 goarch := strings.TrimSpace(tg.getStdout()) 1285 tg.setenv("GOARCH", goarch) 1286 fixbin := filepath.Join(goroot, "pkg", "tool", goos+"_"+goarch, "fix") + exeSuffix 1287 tg.must(os.RemoveAll(fixbin)) 1288 tg.run("install", "cmd/fix") 1289 tg.wantExecutable(fixbin, "did not install cmd/fix to $GOROOT/pkg/tool") 1290 tg.must(os.Remove(fixbin)) 1291 tg.setenv("GOBIN", tg.path("gobin")) 1292 tg.run("install", "cmd/fix") 1293 tg.wantExecutable(fixbin, "did not install cmd/fix to $GOROOT/pkg/tool with $GOBIN set") 1294 tg.unsetenv("GOBIN") 1295 1296 // gopath program installs into GOBIN 1297 tg.tempFile("src/progname/p.go", `package main; func main() {}`) 1298 tg.setenv("GOBIN", tg.path("gobin")) 1299 tg.run("install", "progname") 1300 tg.unsetenv("GOBIN") 1301 tg.wantExecutable(tg.path("gobin/progname")+exeSuffix, "did not install progname to $GOBIN/progname") 1302 1303 // gopath program installs into GOPATH/bin 1304 tg.run("install", "progname") 1305 tg.wantExecutable(tg.path("bin/progname")+exeSuffix, "did not install progname to $GOPATH/bin/progname") 1306 } 1307 1308 func TestRejectRelativeDotPathInGOPATHCommandLinePackage(t *testing.T) { 1309 tg := testgo(t) 1310 defer tg.cleanup() 1311 tg.setenv("GOPATH", ".") 1312 tg.runFail("build", "testdata/src/go-cmd-test/helloworld.go") 1313 tg.grepStderr("GOPATH entry is relative", "expected an error message rejecting relative GOPATH entries") 1314 } 1315 1316 func TestRejectRelativePathsInGOPATH(t *testing.T) { 1317 tg := testgo(t) 1318 defer tg.cleanup() 1319 sep := string(filepath.ListSeparator) 1320 tg.setenv("GOPATH", sep+filepath.Join(tg.pwd(), "testdata")+sep+".") 1321 tg.runFail("build", "go-cmd-test") 1322 tg.grepStderr("GOPATH entry is relative", "expected an error message rejecting relative GOPATH entries") 1323 } 1324 1325 func TestRejectRelativePathsInGOPATHCommandLinePackage(t *testing.T) { 1326 tg := testgo(t) 1327 defer tg.cleanup() 1328 tg.setenv("GOPATH", "testdata") 1329 tg.runFail("build", "testdata/src/go-cmd-test/helloworld.go") 1330 tg.grepStderr("GOPATH entry is relative", "expected an error message rejecting relative GOPATH entries") 1331 } 1332 1333 // Issue 4104. 1334 func TestGoTestWithPackageListedMultipleTimes(t *testing.T) { 1335 tg := testgo(t) 1336 defer tg.cleanup() 1337 tg.parallel() 1338 tg.run("test", "errors", "errors", "errors", "errors", "errors") 1339 if strings.Index(strings.TrimSpace(tg.getStdout()), "\n") != -1 { 1340 t.Error("go test errors errors errors errors errors tested the same package multiple times") 1341 } 1342 } 1343 1344 func TestGoListHasAConsistentOrder(t *testing.T) { 1345 tg := testgo(t) 1346 defer tg.cleanup() 1347 tg.run("list", "std") 1348 first := tg.getStdout() 1349 tg.run("list", "std") 1350 if first != tg.getStdout() { 1351 t.Error("go list std ordering is inconsistent") 1352 } 1353 } 1354 1355 func TestGoListStdDoesNotIncludeCommands(t *testing.T) { 1356 tg := testgo(t) 1357 defer tg.cleanup() 1358 tg.run("list", "std") 1359 tg.grepStdoutNot("cmd/", "go list std shows commands") 1360 } 1361 1362 func TestGoListCmdOnlyShowsCommands(t *testing.T) { 1363 tg := testgo(t) 1364 defer tg.cleanup() 1365 tg.run("list", "cmd") 1366 out := strings.TrimSpace(tg.getStdout()) 1367 for _, line := range strings.Split(out, "\n") { 1368 if strings.Index(line, "cmd/") == -1 { 1369 t.Error("go list cmd shows non-commands") 1370 break 1371 } 1372 } 1373 } 1374 1375 func TestGoListDedupsPackages(t *testing.T) { 1376 tg := testgo(t) 1377 defer tg.cleanup() 1378 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) 1379 tg.run("list", "xtestonly", "./testdata/src/xtestonly/...") 1380 got := strings.TrimSpace(tg.getStdout()) 1381 const want = "xtestonly" 1382 if got != want { 1383 t.Errorf("got %q; want %q", got, want) 1384 } 1385 } 1386 1387 // Issue 4096. Validate the output of unsuccessful go install foo/quxx. 1388 func TestUnsuccessfulGoInstallShouldMentionMissingPackage(t *testing.T) { 1389 tg := testgo(t) 1390 defer tg.cleanup() 1391 tg.runFail("install", "foo/quxx") 1392 if tg.grepCountBoth(`cannot find package "foo/quxx" in any of`) != 1 { 1393 t.Error(`go install foo/quxx expected error: .*cannot find package "foo/quxx" in any of`) 1394 } 1395 } 1396 1397 func TestGOROOTSearchFailureReporting(t *testing.T) { 1398 tg := testgo(t) 1399 defer tg.cleanup() 1400 tg.runFail("install", "foo/quxx") 1401 if tg.grepCountBoth(regexp.QuoteMeta(filepath.Join("foo", "quxx"))+` \(from \$GOROOT\)$`) != 1 { 1402 t.Error(`go install foo/quxx expected error: .*foo/quxx (from $GOROOT)`) 1403 } 1404 } 1405 1406 func TestMultipleGOPATHEntriesReportedSeparately(t *testing.T) { 1407 tg := testgo(t) 1408 defer tg.cleanup() 1409 sep := string(filepath.ListSeparator) 1410 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata", "a")+sep+filepath.Join(tg.pwd(), "testdata", "b")) 1411 tg.runFail("install", "foo/quxx") 1412 if tg.grepCountBoth(`testdata[/\\].[/\\]src[/\\]foo[/\\]quxx`) != 2 { 1413 t.Error(`go install foo/quxx expected error: .*testdata/a/src/foo/quxx (from $GOPATH)\n.*testdata/b/src/foo/quxx`) 1414 } 1415 } 1416 1417 // Test (from $GOPATH) annotation is reported for the first GOPATH entry, 1418 func TestMentionGOPATHInFirstGOPATHEntry(t *testing.T) { 1419 tg := testgo(t) 1420 defer tg.cleanup() 1421 sep := string(filepath.ListSeparator) 1422 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata", "a")+sep+filepath.Join(tg.pwd(), "testdata", "b")) 1423 tg.runFail("install", "foo/quxx") 1424 if tg.grepCountBoth(regexp.QuoteMeta(filepath.Join("testdata", "a", "src", "foo", "quxx"))+` \(from \$GOPATH\)$`) != 1 { 1425 t.Error(`go install foo/quxx expected error: .*testdata/a/src/foo/quxx (from $GOPATH)`) 1426 } 1427 } 1428 1429 // but not on the second. 1430 func TestMentionGOPATHNotOnSecondEntry(t *testing.T) { 1431 tg := testgo(t) 1432 defer tg.cleanup() 1433 sep := string(filepath.ListSeparator) 1434 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata", "a")+sep+filepath.Join(tg.pwd(), "testdata", "b")) 1435 tg.runFail("install", "foo/quxx") 1436 if tg.grepCountBoth(regexp.QuoteMeta(filepath.Join("testdata", "b", "src", "foo", "quxx"))+`$`) != 1 { 1437 t.Error(`go install foo/quxx expected error: .*testdata/b/src/foo/quxx`) 1438 } 1439 } 1440 1441 // Test missing GOPATH is reported. 1442 func TestMissingGOPATHIsReported(t *testing.T) { 1443 tg := testgo(t) 1444 defer tg.cleanup() 1445 tg.setenv("GOPATH", "") 1446 tg.runFail("install", "foo/quxx") 1447 if tg.grepCountBoth(`\(\$GOPATH not set\)$`) != 1 { 1448 t.Error(`go install foo/quxx expected error: ($GOPATH not set)`) 1449 } 1450 } 1451 1452 // Issue 4186. go get cannot be used to download packages to $GOROOT. 1453 // Test that without GOPATH set, go get should fail. 1454 func TestWithoutGOPATHGoGetFails(t *testing.T) { 1455 testenv.MustHaveExternalNetwork(t) 1456 1457 tg := testgo(t) 1458 defer tg.cleanup() 1459 tg.parallel() 1460 tg.tempDir("src") 1461 tg.setenv("GOPATH", "") 1462 tg.setenv("GOROOT", tg.path(".")) 1463 tg.runFail("get", "-d", "golang.org/x/codereview/cmd/hgpatch") 1464 } 1465 1466 // Test that with GOPATH=$GOROOT, go get should fail. 1467 func TestWithGOPATHEqualsGOROOTGoGetFails(t *testing.T) { 1468 testenv.MustHaveExternalNetwork(t) 1469 1470 tg := testgo(t) 1471 defer tg.cleanup() 1472 tg.parallel() 1473 tg.tempDir("src") 1474 tg.setenv("GOPATH", tg.path(".")) 1475 tg.setenv("GOROOT", tg.path(".")) 1476 tg.runFail("get", "-d", "golang.org/x/codereview/cmd/hgpatch") 1477 } 1478 1479 func TestLdflagsArgumentsWithSpacesIssue3941(t *testing.T) { 1480 tg := testgo(t) 1481 defer tg.cleanup() 1482 tg.parallel() 1483 tg.tempFile("main.go", `package main 1484 var extern string 1485 func main() { 1486 println(extern) 1487 }`) 1488 tg.run("run", "-ldflags", `-X main.extern "hello world"`, tg.path("main.go")) 1489 tg.grepStderr("^hello world", `ldflags -X main.extern 'hello world' failed`) 1490 } 1491 1492 func TestGoTestCpuprofileLeavesBinaryBehind(t *testing.T) { 1493 tg := testgo(t) 1494 defer tg.cleanup() 1495 tg.makeTempdir() 1496 tg.cd(tg.path(".")) 1497 tg.run("test", "-cpuprofile", "errors.prof", "errors") 1498 tg.wantExecutable("errors.test"+exeSuffix, "go test -cpuprofile did not create errors.test") 1499 } 1500 1501 func TestGoTestCpuprofileDashOControlsBinaryLocation(t *testing.T) { 1502 tg := testgo(t) 1503 defer tg.cleanup() 1504 tg.makeTempdir() 1505 tg.cd(tg.path(".")) 1506 tg.run("test", "-cpuprofile", "errors.prof", "-o", "myerrors.test"+exeSuffix, "errors") 1507 tg.wantExecutable("myerrors.test"+exeSuffix, "go test -cpuprofile -o myerrors.test did not create myerrors.test") 1508 } 1509 1510 func TestGoTestDashCDashOControlsBinaryLocation(t *testing.T) { 1511 tg := testgo(t) 1512 defer tg.cleanup() 1513 tg.parallel() 1514 tg.makeTempdir() 1515 tg.run("test", "-c", "-o", tg.path("myerrors.test"+exeSuffix), "errors") 1516 tg.wantExecutable(tg.path("myerrors.test"+exeSuffix), "go test -c -o myerrors.test did not create myerrors.test") 1517 } 1518 1519 func TestGoTestDashOWritesBinary(t *testing.T) { 1520 tg := testgo(t) 1521 defer tg.cleanup() 1522 tg.parallel() 1523 tg.makeTempdir() 1524 tg.run("test", "-o", tg.path("myerrors.test"+exeSuffix), "errors") 1525 tg.wantExecutable(tg.path("myerrors.test"+exeSuffix), "go test -o myerrors.test did not create myerrors.test") 1526 } 1527 1528 // Issue 4568. 1529 func TestSymlinksDoNotConfuseGoList(t *testing.T) { 1530 switch runtime.GOOS { 1531 case "plan9", "windows": 1532 t.Skipf("skipping symlink test on %s", runtime.GOOS) 1533 } 1534 1535 tg := testgo(t) 1536 defer tg.cleanup() 1537 tg.tempDir("src") 1538 tg.must(os.Symlink(tg.path("."), tg.path("src/dir1"))) 1539 tg.tempFile("src/dir1/p.go", "package p") 1540 tg.setenv("GOPATH", tg.path(".")) 1541 tg.cd(tg.path("src")) 1542 tg.run("list", "-f", "{{.Root}}", "dir1") 1543 if strings.TrimSpace(tg.getStdout()) != tg.path(".") { 1544 t.Error("confused by symlinks") 1545 } 1546 } 1547 1548 // Issue 4515. 1549 func TestInstallWithTags(t *testing.T) { 1550 tg := testgo(t) 1551 defer tg.cleanup() 1552 tg.parallel() 1553 tg.tempDir("bin") 1554 tg.tempFile("src/example/a/main.go", `package main 1555 func main() {}`) 1556 tg.tempFile("src/example/b/main.go", `// +build mytag 1557 1558 package main 1559 func main() {}`) 1560 tg.setenv("GOPATH", tg.path(".")) 1561 tg.run("install", "-tags", "mytag", "example/a", "example/b") 1562 tg.wantExecutable(tg.path("bin/a"+exeSuffix), "go install example/a example/b did not install binaries") 1563 tg.wantExecutable(tg.path("bin/b"+exeSuffix), "go install example/a example/b did not install binaries") 1564 tg.must(os.Remove(tg.path("bin/a" + exeSuffix))) 1565 tg.must(os.Remove(tg.path("bin/b" + exeSuffix))) 1566 tg.run("install", "-tags", "mytag", "example/...") 1567 tg.wantExecutable(tg.path("bin/a"+exeSuffix), "go install example/... did not install binaries") 1568 tg.wantExecutable(tg.path("bin/b"+exeSuffix), "go install example/... did not install binaries") 1569 tg.run("list", "-tags", "mytag", "example/b...") 1570 if strings.TrimSpace(tg.getStdout()) != "example/b" { 1571 t.Error("go list example/b did not find example/b") 1572 } 1573 } 1574 1575 // Issue 4773 1576 func TestCaseCollisions(t *testing.T) { 1577 tg := testgo(t) 1578 defer tg.cleanup() 1579 tg.parallel() 1580 tg.tempDir("src/example/a/pkg") 1581 tg.tempDir("src/example/a/Pkg") 1582 tg.tempDir("src/example/b") 1583 tg.setenv("GOPATH", tg.path(".")) 1584 tg.tempFile("src/example/a/a.go", `package p 1585 import ( 1586 _ "example/a/pkg" 1587 _ "example/a/Pkg" 1588 )`) 1589 tg.tempFile("src/example/a/pkg/pkg.go", `package pkg`) 1590 tg.tempFile("src/example/a/Pkg/pkg.go", `package pkg`) 1591 tg.runFail("list", "example/a") 1592 tg.grepStderr("case-insensitive import collision", "go list example/a did not report import collision") 1593 tg.tempFile("src/example/b/file.go", `package b`) 1594 tg.tempFile("src/example/b/FILE.go", `package b`) 1595 f, err := os.Open(tg.path("src/example/b")) 1596 tg.must(err) 1597 names, err := f.Readdirnames(0) 1598 tg.must(err) 1599 tg.check(f.Close()) 1600 args := []string{"list"} 1601 if len(names) == 2 { 1602 // case-sensitive file system, let directory read find both files 1603 args = append(args, "example/b") 1604 } else { 1605 // case-insensitive file system, list files explicitly on command line 1606 args = append(args, tg.path("src/example/b/file.go"), tg.path("src/example/b/FILE.go")) 1607 } 1608 tg.runFail(args...) 1609 tg.grepStderr("case-insensitive file name collision", "go list example/b did not report file name collision") 1610 } 1611 1612 // Issue 8181. 1613 func TestGoGetDashTIssue8181(t *testing.T) { 1614 if testing.Short() { 1615 t.Skip("skipping test that uses network in short mode") 1616 } 1617 1618 tg := testgo(t) 1619 defer tg.cleanup() 1620 tg.parallel() 1621 tg.makeTempdir() 1622 tg.setenv("GOPATH", tg.path(".")) 1623 tg.run("get", "-v", "-t", "github.com/rsc/go-get-issue-8181/a", "github.com/rsc/go-get-issue-8181/b") 1624 tg.run("list", "...") 1625 tg.grepStdout("x/build/cmd/cl", "missing expected x/build/cmd/cl") 1626 } 1627 1628 func TestIssue11307(t *testing.T) { 1629 // go get -u was not working except in checkout directory 1630 if testing.Short() { 1631 t.Skip("skipping test that uses network in short mode") 1632 } 1633 1634 tg := testgo(t) 1635 defer tg.cleanup() 1636 tg.parallel() 1637 tg.makeTempdir() 1638 tg.setenv("GOPATH", tg.path(".")) 1639 tg.run("get", "github.com/rsc/go-get-issue-11307") 1640 tg.run("get", "-u", "github.com/rsc/go-get-issue-11307") // was failing 1641 } 1642 1643 func TestShadowingLogic(t *testing.T) { 1644 tg := testgo(t) 1645 defer tg.cleanup() 1646 pwd := tg.pwd() 1647 sep := string(filepath.ListSeparator) 1648 tg.setenv("GOPATH", filepath.Join(pwd, "testdata", "shadow", "root1")+sep+filepath.Join(pwd, "testdata", "shadow", "root2")) 1649 1650 // The math in root1 is not "math" because the standard math is. 1651 tg.run("list", "-f", "({{.ImportPath}}) ({{.ConflictDir}})", "./testdata/shadow/root1/src/math") 1652 pwdForwardSlash := strings.Replace(pwd, string(os.PathSeparator), "/", -1) 1653 if !strings.HasPrefix(pwdForwardSlash, "/") { 1654 pwdForwardSlash = "/" + pwdForwardSlash 1655 } 1656 // The output will have makeImportValid applies, but we only 1657 // bother to deal with characters we might reasonably see. 1658 pwdForwardSlash = strings.Replace(pwdForwardSlash, ":", "_", -1) 1659 want := "(_" + pwdForwardSlash + "/testdata/shadow/root1/src/math) (" + filepath.Join(runtime.GOROOT(), "src", "math") + ")" 1660 if strings.TrimSpace(tg.getStdout()) != want { 1661 t.Error("shadowed math is not shadowed; looking for", want) 1662 } 1663 1664 // The foo in root1 is "foo". 1665 tg.run("list", "-f", "({{.ImportPath}}) ({{.ConflictDir}})", "./testdata/shadow/root1/src/foo") 1666 if strings.TrimSpace(tg.getStdout()) != "(foo) ()" { 1667 t.Error("unshadowed foo is shadowed") 1668 } 1669 1670 // The foo in root2 is not "foo" because the foo in root1 got there first. 1671 tg.run("list", "-f", "({{.ImportPath}}) ({{.ConflictDir}})", "./testdata/shadow/root2/src/foo") 1672 want = "(_" + pwdForwardSlash + "/testdata/shadow/root2/src/foo) (" + filepath.Join(pwd, "testdata", "shadow", "root1", "src", "foo") + ")" 1673 if strings.TrimSpace(tg.getStdout()) != want { 1674 t.Error("shadowed foo is not shadowed; looking for", want) 1675 } 1676 1677 // The error for go install should mention the conflicting directory. 1678 tg.runFail("install", "./testdata/shadow/root2/src/foo") 1679 want = "go install: no install location for " + filepath.Join(pwd, "testdata", "shadow", "root2", "src", "foo") + ": hidden by " + filepath.Join(pwd, "testdata", "shadow", "root1", "src", "foo") 1680 if strings.TrimSpace(tg.getStderr()) != want { 1681 t.Error("wrong shadowed install error; looking for", want) 1682 } 1683 } 1684 1685 // Only succeeds if source order is preserved. 1686 func TestSourceFileNameOrderPreserved(t *testing.T) { 1687 tg := testgo(t) 1688 defer tg.cleanup() 1689 tg.run("test", "testdata/example1_test.go", "testdata/example2_test.go") 1690 } 1691 1692 // Check that coverage analysis works at all. 1693 // Don't worry about the exact numbers but require not 0.0%. 1694 func checkCoverage(tg *testgoData, data string) { 1695 if regexp.MustCompile(`[^0-9]0\.0%`).MatchString(data) { 1696 tg.t.Error("some coverage results are 0.0%") 1697 } 1698 tg.t.Log(data) 1699 } 1700 1701 func TestCoverageRuns(t *testing.T) { 1702 if testing.Short() { 1703 t.Skip("don't build libraries for coverage in short mode") 1704 } 1705 tg := testgo(t) 1706 defer tg.cleanup() 1707 tg.run("test", "-short", "-coverpkg=strings", "strings", "regexp") 1708 data := tg.getStdout() + tg.getStderr() 1709 tg.run("test", "-short", "-cover", "strings", "math", "regexp") 1710 data += tg.getStdout() + tg.getStderr() 1711 checkCoverage(tg, data) 1712 } 1713 1714 // Check that coverage analysis uses set mode. 1715 func TestCoverageUsesSetMode(t *testing.T) { 1716 if testing.Short() { 1717 t.Skip("don't build libraries for coverage in short mode") 1718 } 1719 tg := testgo(t) 1720 defer tg.cleanup() 1721 tg.creatingTemp("testdata/cover.out") 1722 tg.run("test", "-short", "-coverprofile=testdata/cover.out", "encoding/binary") 1723 data := tg.getStdout() + tg.getStderr() 1724 if out, err := ioutil.ReadFile("testdata/cover.out"); err != nil { 1725 t.Error(err) 1726 } else { 1727 if !bytes.Contains(out, []byte("mode: set")) { 1728 t.Error("missing mode: set") 1729 } 1730 } 1731 checkCoverage(tg, data) 1732 } 1733 1734 func TestCoverageUsesAtomicModeForRace(t *testing.T) { 1735 if testing.Short() { 1736 t.Skip("don't build libraries for coverage in short mode") 1737 } 1738 if !canRace { 1739 t.Skip("skipping because race detector not supported") 1740 } 1741 1742 tg := testgo(t) 1743 defer tg.cleanup() 1744 tg.creatingTemp("testdata/cover.out") 1745 tg.run("test", "-short", "-race", "-coverprofile=testdata/cover.out", "encoding/binary") 1746 data := tg.getStdout() + tg.getStderr() 1747 if out, err := ioutil.ReadFile("testdata/cover.out"); err != nil { 1748 t.Error(err) 1749 } else { 1750 if !bytes.Contains(out, []byte("mode: atomic")) { 1751 t.Error("missing mode: atomic") 1752 } 1753 } 1754 checkCoverage(tg, data) 1755 } 1756 1757 func TestCoverageUsesActualSettingToOverrideEvenForRace(t *testing.T) { 1758 if testing.Short() { 1759 t.Skip("don't build libraries for coverage in short mode") 1760 } 1761 if !canRace { 1762 t.Skip("skipping because race detector not supported") 1763 } 1764 1765 tg := testgo(t) 1766 defer tg.cleanup() 1767 tg.creatingTemp("testdata/cover.out") 1768 tg.run("test", "-short", "-race", "-covermode=count", "-coverprofile=testdata/cover.out", "encoding/binary") 1769 data := tg.getStdout() + tg.getStderr() 1770 if out, err := ioutil.ReadFile("testdata/cover.out"); err != nil { 1771 t.Error(err) 1772 } else { 1773 if !bytes.Contains(out, []byte("mode: count")) { 1774 t.Error("missing mode: count") 1775 } 1776 } 1777 checkCoverage(tg, data) 1778 } 1779 1780 func TestCoverageWithCgo(t *testing.T) { 1781 if !canCgo { 1782 t.Skip("skipping because cgo not enabled") 1783 } 1784 1785 tg := testgo(t) 1786 defer tg.cleanup() 1787 tg.run("test", "-short", "-cover", "./testdata/cgocover") 1788 data := tg.getStdout() + tg.getStderr() 1789 checkCoverage(tg, data) 1790 } 1791 1792 func TestCgoDependsOnSyscall(t *testing.T) { 1793 if testing.Short() { 1794 t.Skip("skipping test that removes $GOROOT/pkg/*_race in short mode") 1795 } 1796 if !canCgo { 1797 t.Skip("skipping because cgo not enabled") 1798 } 1799 if !canRace { 1800 t.Skip("skipping because race detector not supported") 1801 } 1802 1803 tg := testgo(t) 1804 defer tg.cleanup() 1805 files, err := filepath.Glob(filepath.Join(runtime.GOROOT(), "pkg", "*_race")) 1806 tg.must(err) 1807 for _, file := range files { 1808 tg.check(os.RemoveAll(file)) 1809 } 1810 tg.tempFile("src/foo/foo.go", ` 1811 package foo 1812 //#include <stdio.h> 1813 import "C"`) 1814 tg.setenv("GOPATH", tg.path(".")) 1815 tg.run("build", "-race", "foo") 1816 } 1817 1818 func TestCgoShowsFullPathNames(t *testing.T) { 1819 if !canCgo { 1820 t.Skip("skipping because cgo not enabled") 1821 } 1822 1823 tg := testgo(t) 1824 defer tg.cleanup() 1825 tg.parallel() 1826 tg.tempFile("src/x/y/dirname/foo.go", ` 1827 package foo 1828 import "C" 1829 func f() {`) 1830 tg.setenv("GOPATH", tg.path(".")) 1831 tg.runFail("build", "x/y/dirname") 1832 tg.grepBoth("x/y/dirname", "error did not use full path") 1833 } 1834 1835 func TestCgoHandlesWlORIGIN(t *testing.T) { 1836 if !canCgo { 1837 t.Skip("skipping because cgo not enabled") 1838 } 1839 1840 tg := testgo(t) 1841 defer tg.cleanup() 1842 tg.parallel() 1843 tg.tempFile("src/origin/origin.go", `package origin 1844 // #cgo !darwin LDFLAGS: -Wl,-rpath -Wl,$ORIGIN 1845 // void f(void) {} 1846 import "C" 1847 func f() { C.f() }`) 1848 tg.setenv("GOPATH", tg.path(".")) 1849 tg.run("build", "origin") 1850 } 1851 1852 // "go test -c -test.bench=XXX errors" should not hang 1853 func TestIssue6480(t *testing.T) { 1854 tg := testgo(t) 1855 defer tg.cleanup() 1856 tg.makeTempdir() 1857 tg.cd(tg.path(".")) 1858 tg.run("test", "-c", "-test.bench=XXX", "errors") 1859 } 1860 1861 // cmd/cgo: undefined reference when linking a C-library using gccgo 1862 func TestIssue7573(t *testing.T) { 1863 if !canCgo { 1864 t.Skip("skipping because cgo not enabled") 1865 } 1866 if _, err := exec.LookPath("gccgo"); err != nil { 1867 t.Skip("skipping because no gccgo compiler found") 1868 } 1869 1870 tg := testgo(t) 1871 defer tg.cleanup() 1872 tg.parallel() 1873 tg.tempFile("src/cgoref/cgoref.go", ` 1874 package main 1875 // #cgo LDFLAGS: -L alibpath -lalib 1876 // void f(void) {} 1877 import "C" 1878 1879 func main() { C.f() }`) 1880 tg.setenv("GOPATH", tg.path(".")) 1881 tg.run("build", "-n", "-compiler", "gccgo", "cgoref") 1882 tg.grepStderr(`gccgo.*\-L alibpath \-lalib`, `no Go-inline "#cgo LDFLAGS:" ("-L alibpath -lalib") passed to gccgo linking stage`) 1883 } 1884 1885 func TestListTemplateCanUseContextFunction(t *testing.T) { 1886 tg := testgo(t) 1887 defer tg.cleanup() 1888 tg.run("list", "-f", "GOARCH: {{context.GOARCH}}") 1889 } 1890 1891 // cmd/go: "go test" should fail if package does not build 1892 func TestIssue7108(t *testing.T) { 1893 tg := testgo(t) 1894 defer tg.cleanup() 1895 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) 1896 tg.runFail("test", "notest") 1897 } 1898 1899 // cmd/go: go test -a foo does not rebuild regexp. 1900 func TestIssue6844(t *testing.T) { 1901 if testing.Short() { 1902 t.Skip("don't rebuild the standard libary in short mode") 1903 } 1904 1905 tg := testgo(t) 1906 defer tg.cleanup() 1907 tg.creatingTemp("deps.test" + exeSuffix) 1908 tg.run("test", "-x", "-a", "-c", "testdata/dep_test.go") 1909 tg.grepStderr("regexp", "go test -x -a -c testdata/dep-test.go did not rebuild regexp") 1910 } 1911 1912 func TestBuildDashIInstallsDependencies(t *testing.T) { 1913 tg := testgo(t) 1914 defer tg.cleanup() 1915 tg.parallel() 1916 tg.tempFile("src/x/y/foo/foo.go", `package foo 1917 func F() {}`) 1918 tg.tempFile("src/x/y/bar/bar.go", `package bar 1919 import "x/y/foo" 1920 func F() { foo.F() }`) 1921 tg.setenv("GOPATH", tg.path(".")) 1922 1923 checkbar := func(desc string) { 1924 tg.sleep() 1925 tg.must(os.Chtimes(tg.path("src/x/y/foo/foo.go"), time.Now(), time.Now())) 1926 tg.sleep() 1927 tg.run("build", "-v", "-i", "x/y/bar") 1928 tg.grepBoth("x/y/foo", "first build -i "+desc+" did not build x/y/foo") 1929 tg.run("build", "-v", "-i", "x/y/bar") 1930 tg.grepBothNot("x/y/foo", "second build -i "+desc+" built x/y/foo") 1931 } 1932 checkbar("pkg") 1933 tg.creatingTemp("bar" + exeSuffix) 1934 tg.tempFile("src/x/y/bar/bar.go", `package main 1935 import "x/y/foo" 1936 func main() { foo.F() }`) 1937 checkbar("cmd") 1938 } 1939 1940 func TestGoBuildInTestOnlyDirectoryFailsWithAGoodError(t *testing.T) { 1941 tg := testgo(t) 1942 defer tg.cleanup() 1943 tg.runFail("build", "./testdata/testonly") 1944 tg.grepStderr("no buildable Go", "go build ./testdata/testonly produced unexpected error") 1945 } 1946 1947 func TestGoTestDetectsTestOnlyImportCycles(t *testing.T) { 1948 tg := testgo(t) 1949 defer tg.cleanup() 1950 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) 1951 tg.runFail("test", "-c", "testcycle/p3") 1952 tg.grepStderr("import cycle not allowed in test", "go test testcycle/p3 produced unexpected error") 1953 1954 tg.runFail("test", "-c", "testcycle/q1") 1955 tg.grepStderr("import cycle not allowed in test", "go test testcycle/q1 produced unexpected error") 1956 } 1957 1958 func TestGoTestFooTestWorks(t *testing.T) { 1959 tg := testgo(t) 1960 defer tg.cleanup() 1961 tg.run("test", "testdata/standalone_test.go") 1962 } 1963 1964 func TestGoTestFlagsAfterPackage(t *testing.T) { 1965 tg := testgo(t) 1966 defer tg.cleanup() 1967 tg.run("test", "-v", "testdata/flag_test.go", "-v=7") // Two distinct -v flags. 1968 } 1969 1970 func TestGoTestXtestonlyWorks(t *testing.T) { 1971 tg := testgo(t) 1972 defer tg.cleanup() 1973 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) 1974 tg.run("clean", "-i", "xtestonly") 1975 tg.run("test", "xtestonly") 1976 } 1977 1978 func TestGoTestBuildsAnXtestContainingOnlyNonRunnableExamples(t *testing.T) { 1979 tg := testgo(t) 1980 defer tg.cleanup() 1981 tg.run("test", "-v", "./testdata/norunexample") 1982 tg.grepStdout("File with non-runnable example was built.", "file with non-runnable example was not built") 1983 } 1984 1985 func TestGoGenerateHandlesSimpleCommand(t *testing.T) { 1986 if runtime.GOOS == "windows" { 1987 t.Skip("skipping because windows has no echo command") 1988 } 1989 1990 tg := testgo(t) 1991 defer tg.cleanup() 1992 tg.run("generate", "./testdata/generate/test1.go") 1993 tg.grepStdout("Success", "go generate ./testdata/generate/test1.go generated wrong output") 1994 } 1995 1996 func TestGoGenerateHandlesCommandAlias(t *testing.T) { 1997 if runtime.GOOS == "windows" { 1998 t.Skip("skipping because windows has no echo command") 1999 } 2000 2001 tg := testgo(t) 2002 defer tg.cleanup() 2003 tg.run("generate", "./testdata/generate/test2.go") 2004 tg.grepStdout("Now is the time for all good men", "go generate ./testdata/generate/test2.go generated wrong output") 2005 } 2006 2007 func TestGoGenerateVariableSubstitution(t *testing.T) { 2008 if runtime.GOOS == "windows" { 2009 t.Skip("skipping because windows has no echo command") 2010 } 2011 2012 tg := testgo(t) 2013 defer tg.cleanup() 2014 tg.run("generate", "./testdata/generate/test3.go") 2015 tg.grepStdout(runtime.GOARCH+" test3.go:7 pabc xyzp/test3.go/123", "go generate ./testdata/generate/test3.go generated wrong output") 2016 } 2017 2018 func TestGoGenerateRunFlag(t *testing.T) { 2019 if runtime.GOOS == "windows" { 2020 t.Skip("skipping because windows has no echo command") 2021 } 2022 2023 tg := testgo(t) 2024 defer tg.cleanup() 2025 tg.run("generate", "-run", "y.s", "./testdata/generate/test4.go") 2026 tg.grepStdout("yes", "go generate -run yes ./testdata/generate/test4.go did not select yes") 2027 tg.grepStdoutNot("no", "go generate -run yes ./testdata/generate/test4.go selected no") 2028 } 2029 2030 func TestGoGetCustomDomainWildcard(t *testing.T) { 2031 testenv.MustHaveExternalNetwork(t) 2032 2033 tg := testgo(t) 2034 defer tg.cleanup() 2035 tg.makeTempdir() 2036 tg.setenv("GOPATH", tg.path(".")) 2037 tg.run("get", "-u", "rsc.io/pdf/...") 2038 tg.wantExecutable(tg.path("bin/pdfpasswd"+exeSuffix), "did not build rsc/io/pdf/pdfpasswd") 2039 } 2040 2041 func TestGoGetInternalWildcard(t *testing.T) { 2042 testenv.MustHaveExternalNetwork(t) 2043 2044 tg := testgo(t) 2045 defer tg.cleanup() 2046 tg.makeTempdir() 2047 tg.setenv("GOPATH", tg.path(".")) 2048 // used to fail with errors about internal packages 2049 tg.run("get", "github.com/rsc/go-get-issue-11960/...") 2050 } 2051 2052 func TestGoVetWithExternalTests(t *testing.T) { 2053 testenv.MustHaveExternalNetwork(t) 2054 2055 tg := testgo(t) 2056 defer tg.cleanup() 2057 tg.makeTempdir() 2058 tg.setenv("GOPATH", tg.path(".")) 2059 tg.run("get", "golang.org/x/tools/cmd/vet") 2060 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) 2061 tg.runFail("vet", "vetpkg") 2062 tg.grepBoth("missing argument for Printf", "go vet vetpkg did not find missing argument for Printf") 2063 } 2064 2065 func TestGoVetWithTags(t *testing.T) { 2066 testenv.MustHaveExternalNetwork(t) 2067 2068 tg := testgo(t) 2069 defer tg.cleanup() 2070 tg.makeTempdir() 2071 tg.setenv("GOPATH", tg.path(".")) 2072 tg.run("get", "golang.org/x/tools/cmd/vet") 2073 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) 2074 tg.runFail("vet", "-tags", "tagtest", "vetpkg") 2075 tg.grepBoth(`c\.go.*wrong number of args for format`, "go get vetpkg did not run scan tagged file") 2076 } 2077 2078 // Issue 9767. 2079 func TestGoGetRscIoToolstash(t *testing.T) { 2080 testenv.MustHaveExternalNetwork(t) 2081 2082 tg := testgo(t) 2083 defer tg.cleanup() 2084 tg.tempDir("src/rsc.io") 2085 tg.setenv("GOPATH", tg.path(".")) 2086 tg.cd(tg.path("src/rsc.io")) 2087 tg.run("get", "./toolstash") 2088 } 2089 2090 // Test that you can not import a main package. 2091 func TestIssue4210(t *testing.T) { 2092 tg := testgo(t) 2093 defer tg.cleanup() 2094 tg.tempFile("src/x/main.go", `package main 2095 var X int 2096 func main() {}`) 2097 tg.tempFile("src/y/main.go", `package main 2098 import "fmt" 2099 import xmain "x" 2100 func main() { 2101 fmt.Println(xmain.X) 2102 }`) 2103 tg.setenv("GOPATH", tg.path(".")) 2104 tg.runFail("build", "y") 2105 tg.grepBoth("is a program", `did not find expected error message ("is a program")`) 2106 } 2107 2108 func TestGoGetInsecure(t *testing.T) { 2109 testenv.MustHaveExternalNetwork(t) 2110 2111 tg := testgo(t) 2112 defer tg.cleanup() 2113 tg.makeTempdir() 2114 tg.setenv("GOPATH", tg.path(".")) 2115 tg.failSSH() 2116 2117 const repo = "wh3rd.net/git.git" 2118 2119 // Try go get -d of HTTP-only repo (should fail). 2120 tg.runFail("get", "-d", repo) 2121 2122 // Try again with -insecure (should succeed). 2123 tg.run("get", "-d", "-insecure", repo) 2124 2125 // Try updating without -insecure (should fail). 2126 tg.runFail("get", "-d", "-u", "-f", repo) 2127 } 2128 2129 func TestGoGetUpdateInsecure(t *testing.T) { 2130 testenv.MustHaveExternalNetwork(t) 2131 2132 tg := testgo(t) 2133 defer tg.cleanup() 2134 tg.makeTempdir() 2135 tg.setenv("GOPATH", tg.path(".")) 2136 2137 const repo = "github.com/golang/example" 2138 2139 // Clone the repo via HTTP manually. 2140 cmd := exec.Command("git", "clone", "-q", "http://"+repo, tg.path("src/"+repo)) 2141 if out, err := cmd.CombinedOutput(); err != nil { 2142 t.Fatalf("cloning %v repo: %v\n%s", repo, err, out) 2143 } 2144 2145 // Update without -insecure should fail. 2146 // Update with -insecure should succeed. 2147 // We need -f to ignore import comments. 2148 const pkg = repo + "/hello" 2149 tg.runFail("get", "-d", "-u", "-f", pkg) 2150 tg.run("get", "-d", "-u", "-f", "-insecure", pkg) 2151 } 2152 2153 func TestGoGetInsecureCustomDomain(t *testing.T) { 2154 testenv.MustHaveExternalNetwork(t) 2155 2156 tg := testgo(t) 2157 defer tg.cleanup() 2158 tg.makeTempdir() 2159 tg.setenv("GOPATH", tg.path(".")) 2160 2161 const repo = "wh3rd.net/repo" 2162 tg.runFail("get", "-d", repo) 2163 tg.run("get", "-d", "-insecure", repo) 2164 } 2165 2166 func TestIssue10193(t *testing.T) { 2167 testenv.MustHaveExternalNetwork(t) 2168 2169 tg := testgo(t) 2170 defer tg.cleanup() 2171 tg.parallel() 2172 tg.tempDir("src") 2173 tg.setenv("GOPATH", tg.path(".")) 2174 tg.runFail("get", "code.google.com/p/rsc/pdf") 2175 tg.grepStderr("is shutting down", "missed warning about code.google.com") 2176 } 2177 2178 func TestGoRunDirs(t *testing.T) { 2179 tg := testgo(t) 2180 defer tg.cleanup() 2181 tg.cd("testdata/rundir") 2182 tg.runFail("run", "x.go", "sub/sub.go") 2183 tg.grepStderr("named files must all be in one directory; have ./ and sub/", "wrong output") 2184 tg.runFail("run", "sub/sub.go", "x.go") 2185 tg.grepStderr("named files must all be in one directory; have sub/ and ./", "wrong output") 2186 } 2187 2188 func TestGoInstallPkgdir(t *testing.T) { 2189 tg := testgo(t) 2190 defer tg.cleanup() 2191 tg.makeTempdir() 2192 pkg := tg.path(".") 2193 tg.run("install", "-pkgdir", pkg, "errors") 2194 _, err := os.Stat(filepath.Join(pkg, "errors.a")) 2195 tg.must(err) 2196 _, err = os.Stat(filepath.Join(pkg, "runtime.a")) 2197 tg.must(err) 2198 } 2199 2200 func TestGoTestRaceInstallCgo(t *testing.T) { 2201 switch sys := runtime.GOOS + "/" + runtime.GOARCH; sys { 2202 case "darwin/amd64", "freebsd/amd64", "linux/amd64", "windows/amd64": 2203 // ok 2204 default: 2205 t.Skip("no race detector on %s", sys) 2206 } 2207 2208 if !build.Default.CgoEnabled { 2209 t.Skip("no race detector without cgo") 2210 } 2211 2212 // golang.org/issue/10500. 2213 // This used to install a race-enabled cgo. 2214 tg := testgo(t) 2215 defer tg.cleanup() 2216 tg.run("tool", "-n", "cgo") 2217 cgo := strings.TrimSpace(tg.stdout.String()) 2218 old, err := os.Stat(cgo) 2219 tg.must(err) 2220 tg.run("test", "-race", "-i", "runtime/race") 2221 new, err := os.Stat(cgo) 2222 tg.must(err) 2223 if new.ModTime() != old.ModTime() { 2224 t.Fatalf("go test -i runtime/race reinstalled cmd/cgo") 2225 } 2226 } 2227 2228 func TestGoTestImportErrorStack(t *testing.T) { 2229 const out = `package testdep/p1 (test) 2230 imports testdep/p2 2231 imports testdep/p3: no buildable Go source files` 2232 2233 tg := testgo(t) 2234 defer tg.cleanup() 2235 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) 2236 tg.runFail("test", "testdep/p1") 2237 if !strings.Contains(tg.stderr.String(), out) { 2238 t.Fatalf("did not give full import stack:\n\n%s", tg.stderr.String()) 2239 } 2240 } 2241 2242 func TestGoGetUpdate(t *testing.T) { 2243 // golang.org/issue/9224. 2244 // The recursive updating was trying to walk to 2245 // former dependencies, not current ones. 2246 2247 testenv.MustHaveExternalNetwork(t) 2248 2249 tg := testgo(t) 2250 defer tg.cleanup() 2251 tg.makeTempdir() 2252 tg.setenv("GOPATH", tg.path(".")) 2253 2254 rewind := func() { 2255 tg.run("get", "github.com/rsc/go-get-issue-9224-cmd") 2256 cmd := exec.Command("git", "reset", "--hard", "HEAD~") 2257 cmd.Dir = tg.path("src/github.com/rsc/go-get-issue-9224-lib") 2258 out, err := cmd.CombinedOutput() 2259 if err != nil { 2260 t.Fatalf("git: %v\n%s", err, out) 2261 } 2262 } 2263 2264 rewind() 2265 tg.run("get", "-u", "github.com/rsc/go-get-issue-9224-cmd") 2266 2267 // Again with -d -u. 2268 rewind() 2269 tg.run("get", "-d", "-u", "github.com/rsc/go-get-issue-9224-cmd") 2270 } 2271 2272 func TestGoGetDomainRoot(t *testing.T) { 2273 // golang.org/issue/9357. 2274 // go get foo.io (not foo.io/subdir) was not working consistently. 2275 2276 testenv.MustHaveExternalNetwork(t) 2277 2278 tg := testgo(t) 2279 defer tg.cleanup() 2280 tg.makeTempdir() 2281 tg.setenv("GOPATH", tg.path(".")) 2282 2283 // go-get-issue-9357.appspot.com is running 2284 // the code at github.com/rsc/go-get-issue-9357, 2285 // a trivial Go on App Engine app that serves a 2286 // <meta> tag for the domain root. 2287 tg.run("get", "-d", "go-get-issue-9357.appspot.com") 2288 tg.run("get", "go-get-issue-9357.appspot.com") 2289 tg.run("get", "-u", "go-get-issue-9357.appspot.com") 2290 2291 tg.must(os.RemoveAll(tg.path("src/go-get-issue-9357.appspot.com"))) 2292 tg.run("get", "go-get-issue-9357.appspot.com") 2293 2294 tg.must(os.RemoveAll(tg.path("src/go-get-issue-9357.appspot.com"))) 2295 tg.run("get", "-u", "go-get-issue-9357.appspot.com") 2296 } 2297 2298 func TestGoInstallShadowedGOPATH(t *testing.T) { 2299 // golang.org/issue/3652. 2300 // go get foo.io (not foo.io/subdir) was not working consistently. 2301 2302 testenv.MustHaveExternalNetwork(t) 2303 2304 tg := testgo(t) 2305 defer tg.cleanup() 2306 tg.makeTempdir() 2307 tg.setenv("GOPATH", tg.path("gopath1")+string(filepath.ListSeparator)+tg.path("gopath2")) 2308 2309 tg.tempDir("gopath1/src/test") 2310 tg.tempDir("gopath2/src/test") 2311 tg.tempFile("gopath2/src/test/main.go", "package main\nfunc main(){}\n") 2312 2313 tg.cd(tg.path("gopath2/src/test")) 2314 tg.runFail("install") 2315 tg.grepStderr("no install location for.*gopath2.src.test: hidden by .*gopath1.src.test", "missing error") 2316 } 2317 2318 func TestIssue11709(t *testing.T) { 2319 tg := testgo(t) 2320 defer tg.cleanup() 2321 tg.tempFile("run.go", ` 2322 package main 2323 import "os" 2324 func main() { 2325 if os.Getenv("TERM") != "" { 2326 os.Exit(1) 2327 } 2328 }`) 2329 tg.unsetenv("TERM") 2330 tg.run("run", tg.path("run.go")) 2331 } 2332 2333 func TestIssue12096(t *testing.T) { 2334 tg := testgo(t) 2335 defer tg.cleanup() 2336 tg.tempFile("test_test.go", ` 2337 package main 2338 import ("os"; "testing") 2339 func TestEnv(t *testing.T) { 2340 if os.Getenv("TERM") != "" { 2341 t.Fatal("TERM is set") 2342 } 2343 }`) 2344 tg.unsetenv("TERM") 2345 tg.run("test", tg.path("test_test.go")) 2346 } 2347 2348 func TestGoBuildOutput(t *testing.T) { 2349 tg := testgo(t) 2350 defer tg.cleanup() 2351 2352 tg.makeTempdir() 2353 tg.cd(tg.path(".")) 2354 2355 nonExeSuffix := ".exe" 2356 if exeSuffix == ".exe" { 2357 nonExeSuffix = "" 2358 } 2359 2360 tg.tempFile("x.go", "package main\nfunc main(){}\n") 2361 tg.run("build", "x.go") 2362 tg.wantExecutable("x"+exeSuffix, "go build x.go did not write x"+exeSuffix) 2363 tg.must(os.Remove(tg.path("x" + exeSuffix))) 2364 tg.mustNotExist("x" + nonExeSuffix) 2365 2366 tg.run("build", "-o", "myprog", "x.go") 2367 tg.mustNotExist("x") 2368 tg.mustNotExist("x.exe") 2369 tg.wantExecutable("myprog", "go build -o myprog x.go did not write myprog") 2370 tg.mustNotExist("myprog.exe") 2371 2372 tg.tempFile("p.go", "package p\n") 2373 tg.run("build", "p.go") 2374 tg.mustNotExist("p") 2375 tg.mustNotExist("p.a") 2376 tg.mustNotExist("p.o") 2377 tg.mustNotExist("p.exe") 2378 2379 tg.run("build", "-o", "p.a", "p.go") 2380 tg.wantArchive("p.a") 2381 2382 tg.run("build", "cmd/gofmt") 2383 tg.wantExecutable("gofmt"+exeSuffix, "go build cmd/gofmt did not write gofmt"+exeSuffix) 2384 tg.must(os.Remove(tg.path("gofmt" + exeSuffix))) 2385 tg.mustNotExist("gofmt" + nonExeSuffix) 2386 2387 tg.run("build", "-o", "mygofmt", "cmd/gofmt") 2388 tg.wantExecutable("mygofmt", "go build -o mygofmt cmd/gofmt did not write mygofmt") 2389 tg.mustNotExist("mygofmt.exe") 2390 tg.mustNotExist("gofmt") 2391 tg.mustNotExist("gofmt.exe") 2392 2393 tg.run("build", "sync/atomic") 2394 tg.mustNotExist("atomic") 2395 tg.mustNotExist("atomic.exe") 2396 2397 tg.run("build", "-o", "myatomic.a", "sync/atomic") 2398 tg.wantArchive("myatomic.a") 2399 tg.mustNotExist("atomic") 2400 tg.mustNotExist("atomic.a") 2401 tg.mustNotExist("atomic.exe") 2402 2403 tg.runFail("build", "-o", "whatever", "cmd/gofmt", "sync/atomic") 2404 tg.grepStderr("multiple packages", "did not reject -o with multiple packages") 2405 } 2406 2407 func TestGoBuildARM(t *testing.T) { 2408 if testing.Short() { 2409 t.Skip("skipping cross-compile in short mode") 2410 } 2411 2412 tg := testgo(t) 2413 defer tg.cleanup() 2414 2415 tg.makeTempdir() 2416 tg.cd(tg.path(".")) 2417 2418 tg.setenv("GOARCH", "arm") 2419 tg.setenv("GOOS", "linux") 2420 tg.setenv("GOARM", "5") 2421 tg.tempFile("hello.go", `package main 2422 func main() {}`) 2423 tg.run("build", "hello.go") 2424 tg.grepStderrNot("unable to find math.a", "did not build math.a correctly") 2425 }