Commit 350f71f4 authored by Bryan C. Mills's avatar Bryan C. Mills

cmd/go: in tests, don't assume that the 'git' binary is present

Add a helper-function to testenv to make these skips more ergonomic.
Also update a few existing skips in cmd/go/... to use it.

Updates #25300

Change-Id: I4205b4fb2b685dfac1cff3c999f954bff7b0f3c1
Reviewed-on: https://go-review.googlesource.com/c/go/+/181538Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
parent 8f296f59
...@@ -1222,10 +1222,12 @@ func TestInternalCache(t *testing.T) { ...@@ -1222,10 +1222,12 @@ func TestInternalCache(t *testing.T) {
} }
func TestMoveGit(t *testing.T) { func TestMoveGit(t *testing.T) {
testenv.MustHaveExecPath(t, "git")
testMove(t, "git", "rsc.io/pdf", "pdf", "rsc.io/pdf/.git/config") testMove(t, "git", "rsc.io/pdf", "pdf", "rsc.io/pdf/.git/config")
} }
func TestMoveHG(t *testing.T) { func TestMoveHG(t *testing.T) {
testenv.MustHaveExecPath(t, "hg")
testMove(t, "hg", "vcs-test.golang.org/go/custom-hg-hello", "custom-hg-hello", "vcs-test.golang.org/go/custom-hg-hello/.hg/hgrc") testMove(t, "hg", "vcs-test.golang.org/go/custom-hg-hello", "custom-hg-hello", "vcs-test.golang.org/go/custom-hg-hello/.hg/hgrc")
} }
...@@ -1287,9 +1289,7 @@ func TestImportCycle(t *testing.T) { ...@@ -1287,9 +1289,7 @@ func TestImportCycle(t *testing.T) {
// cmd/go: custom import path checking should not apply to Go packages without import comment. // cmd/go: custom import path checking should not apply to Go packages without import comment.
func TestIssue10952(t *testing.T) { func TestIssue10952(t *testing.T) {
testenv.MustHaveExternalNetwork(t) testenv.MustHaveExternalNetwork(t)
if _, err := exec.LookPath("git"); err != nil { testenv.MustHaveExecPath(t, "git")
t.Skip("skipping because git binary not found")
}
tg := testgo(t) tg := testgo(t)
defer tg.cleanup() defer tg.cleanup()
...@@ -1305,9 +1305,7 @@ func TestIssue10952(t *testing.T) { ...@@ -1305,9 +1305,7 @@ func TestIssue10952(t *testing.T) {
func TestIssue16471(t *testing.T) { func TestIssue16471(t *testing.T) {
testenv.MustHaveExternalNetwork(t) testenv.MustHaveExternalNetwork(t)
if _, err := exec.LookPath("git"); err != nil { testenv.MustHaveExecPath(t, "git")
t.Skip("skipping because git binary not found")
}
tg := testgo(t) tg := testgo(t)
defer tg.cleanup() defer tg.cleanup()
...@@ -1323,9 +1321,7 @@ func TestIssue16471(t *testing.T) { ...@@ -1323,9 +1321,7 @@ func TestIssue16471(t *testing.T) {
// Test git clone URL that uses SCP-like syntax and custom import path checking. // Test git clone URL that uses SCP-like syntax and custom import path checking.
func TestIssue11457(t *testing.T) { func TestIssue11457(t *testing.T) {
testenv.MustHaveExternalNetwork(t) testenv.MustHaveExternalNetwork(t)
if _, err := exec.LookPath("git"); err != nil { testenv.MustHaveExecPath(t, "git")
t.Skip("skipping because git binary not found")
}
tg := testgo(t) tg := testgo(t)
defer tg.cleanup() defer tg.cleanup()
...@@ -1350,9 +1346,7 @@ func TestIssue11457(t *testing.T) { ...@@ -1350,9 +1346,7 @@ func TestIssue11457(t *testing.T) {
func TestGetGitDefaultBranch(t *testing.T) { func TestGetGitDefaultBranch(t *testing.T) {
testenv.MustHaveExternalNetwork(t) testenv.MustHaveExternalNetwork(t)
if _, err := exec.LookPath("git"); err != nil { testenv.MustHaveExecPath(t, "git")
t.Skip("skipping because git binary not found")
}
tg := testgo(t) tg := testgo(t)
defer tg.cleanup() defer tg.cleanup()
...@@ -1378,9 +1372,7 @@ func TestGetGitDefaultBranch(t *testing.T) { ...@@ -1378,9 +1372,7 @@ func TestGetGitDefaultBranch(t *testing.T) {
// Security issue. Don't disable. See golang.org/issue/22125. // Security issue. Don't disable. See golang.org/issue/22125.
func TestAccidentalGitCheckout(t *testing.T) { func TestAccidentalGitCheckout(t *testing.T) {
testenv.MustHaveExternalNetwork(t) testenv.MustHaveExternalNetwork(t)
if _, err := exec.LookPath("git"); err != nil { testenv.MustHaveExecPath(t, "git")
t.Skip("skipping because git binary not found")
}
tg := testgo(t) tg := testgo(t)
defer tg.cleanup() defer tg.cleanup()
...@@ -1653,6 +1645,7 @@ func TestInstallToGOBINCommandLinePackage(t *testing.T) { ...@@ -1653,6 +1645,7 @@ func TestInstallToGOBINCommandLinePackage(t *testing.T) {
func TestGoGetNonPkg(t *testing.T) { func TestGoGetNonPkg(t *testing.T) {
testenv.MustHaveExternalNetwork(t) testenv.MustHaveExternalNetwork(t)
testenv.MustHaveExecPath(t, "git")
tg := testgo(t) tg := testgo(t)
defer tg.cleanup() defer tg.cleanup()
...@@ -1669,6 +1662,7 @@ func TestGoGetNonPkg(t *testing.T) { ...@@ -1669,6 +1662,7 @@ func TestGoGetNonPkg(t *testing.T) {
func TestGoGetTestOnlyPkg(t *testing.T) { func TestGoGetTestOnlyPkg(t *testing.T) {
testenv.MustHaveExternalNetwork(t) testenv.MustHaveExternalNetwork(t)
testenv.MustHaveExecPath(t, "git")
tg := testgo(t) tg := testgo(t)
defer tg.cleanup() defer tg.cleanup()
...@@ -2058,6 +2052,7 @@ func TestDefaultGOPATH(t *testing.T) { ...@@ -2058,6 +2052,7 @@ func TestDefaultGOPATH(t *testing.T) {
func TestDefaultGOPATHGet(t *testing.T) { func TestDefaultGOPATHGet(t *testing.T) {
testenv.MustHaveExternalNetwork(t) testenv.MustHaveExternalNetwork(t)
testenv.MustHaveExecPath(t, "git")
tg := testgo(t) tg := testgo(t)
defer tg.cleanup() defer tg.cleanup()
...@@ -2439,6 +2434,7 @@ func TestSymlinkWarning(t *testing.T) { ...@@ -2439,6 +2434,7 @@ func TestSymlinkWarning(t *testing.T) {
// Issue 8181. // Issue 8181.
func TestGoGetDashTIssue8181(t *testing.T) { func TestGoGetDashTIssue8181(t *testing.T) {
testenv.MustHaveExternalNetwork(t) testenv.MustHaveExternalNetwork(t)
testenv.MustHaveExecPath(t, "git")
tg := testgo(t) tg := testgo(t)
defer tg.cleanup() defer tg.cleanup()
...@@ -2453,6 +2449,7 @@ func TestGoGetDashTIssue8181(t *testing.T) { ...@@ -2453,6 +2449,7 @@ func TestGoGetDashTIssue8181(t *testing.T) {
func TestIssue11307(t *testing.T) { func TestIssue11307(t *testing.T) {
// go get -u was not working except in checkout directory // go get -u was not working except in checkout directory
testenv.MustHaveExternalNetwork(t) testenv.MustHaveExternalNetwork(t)
testenv.MustHaveExecPath(t, "git")
tg := testgo(t) tg := testgo(t)
defer tg.cleanup() defer tg.cleanup()
...@@ -2931,6 +2928,7 @@ func TestCgoPkgConfig(t *testing.T) { ...@@ -2931,6 +2928,7 @@ func TestCgoPkgConfig(t *testing.T) {
tg.run("env", "PKG_CONFIG") tg.run("env", "PKG_CONFIG")
pkgConfig := strings.TrimSpace(tg.getStdout()) pkgConfig := strings.TrimSpace(tg.getStdout())
testenv.MustHaveExecPath(t, pkgConfig)
if out, err := exec.Command(pkgConfig, "--atleast-pkgconfig-version", "0.24").CombinedOutput(); err != nil { if out, err := exec.Command(pkgConfig, "--atleast-pkgconfig-version", "0.24").CombinedOutput(); err != nil {
t.Skipf("%s --atleast-pkgconfig-version 0.24: %v\n%s", pkgConfig, err, out) t.Skipf("%s --atleast-pkgconfig-version 0.24: %v\n%s", pkgConfig, err, out)
} }
...@@ -3033,9 +3031,7 @@ func TestIssue7573(t *testing.T) { ...@@ -3033,9 +3031,7 @@ func TestIssue7573(t *testing.T) {
if !canCgo { if !canCgo {
t.Skip("skipping because cgo not enabled") t.Skip("skipping because cgo not enabled")
} }
if _, err := exec.LookPath("gccgo"); err != nil { testenv.MustHaveExecPath(t, "gccgo")
t.Skip("skipping because no gccgo compiler found")
}
tg := testgo(t) tg := testgo(t)
defer tg.cleanup() defer tg.cleanup()
...@@ -3324,6 +3320,7 @@ func TestGoGenerateBadImports(t *testing.T) { ...@@ -3324,6 +3320,7 @@ func TestGoGenerateBadImports(t *testing.T) {
func TestGoGetCustomDomainWildcard(t *testing.T) { func TestGoGetCustomDomainWildcard(t *testing.T) {
testenv.MustHaveExternalNetwork(t) testenv.MustHaveExternalNetwork(t)
testenv.MustHaveExecPath(t, "git")
tg := testgo(t) tg := testgo(t)
defer tg.cleanup() defer tg.cleanup()
...@@ -3335,6 +3332,7 @@ func TestGoGetCustomDomainWildcard(t *testing.T) { ...@@ -3335,6 +3332,7 @@ func TestGoGetCustomDomainWildcard(t *testing.T) {
func TestGoGetInternalWildcard(t *testing.T) { func TestGoGetInternalWildcard(t *testing.T) {
testenv.MustHaveExternalNetwork(t) testenv.MustHaveExternalNetwork(t)
testenv.MustHaveExecPath(t, "git")
tg := testgo(t) tg := testgo(t)
defer tg.cleanup() defer tg.cleanup()
...@@ -3407,6 +3405,7 @@ func TestVetWithOnlyCgoFiles(t *testing.T) { ...@@ -3407,6 +3405,7 @@ func TestVetWithOnlyCgoFiles(t *testing.T) {
// Issue 9767, 19769. // Issue 9767, 19769.
func TestGoGetDotSlashDownload(t *testing.T) { func TestGoGetDotSlashDownload(t *testing.T) {
testenv.MustHaveExternalNetwork(t) testenv.MustHaveExternalNetwork(t)
testenv.MustHaveExecPath(t, "git")
tg := testgo(t) tg := testgo(t)
defer tg.cleanup() defer tg.cleanup()
...@@ -3662,6 +3661,7 @@ func TestImportLocal(t *testing.T) { ...@@ -3662,6 +3661,7 @@ func TestImportLocal(t *testing.T) {
func TestGoGetInsecure(t *testing.T) { func TestGoGetInsecure(t *testing.T) {
test := func(t *testing.T, modules bool) { test := func(t *testing.T, modules bool) {
testenv.MustHaveExternalNetwork(t) testenv.MustHaveExternalNetwork(t)
testenv.MustHaveExecPath(t, "git")
tg := testgo(t) tg := testgo(t)
defer tg.cleanup() defer tg.cleanup()
...@@ -3702,6 +3702,7 @@ func TestGoGetInsecure(t *testing.T) { ...@@ -3702,6 +3702,7 @@ func TestGoGetInsecure(t *testing.T) {
func TestGoGetUpdateInsecure(t *testing.T) { func TestGoGetUpdateInsecure(t *testing.T) {
testenv.MustHaveExternalNetwork(t) testenv.MustHaveExternalNetwork(t)
testenv.MustHaveExecPath(t, "git")
tg := testgo(t) tg := testgo(t)
defer tg.cleanup() defer tg.cleanup()
...@@ -3726,6 +3727,7 @@ func TestGoGetUpdateInsecure(t *testing.T) { ...@@ -3726,6 +3727,7 @@ func TestGoGetUpdateInsecure(t *testing.T) {
func TestGoGetUpdateUnknownProtocol(t *testing.T) { func TestGoGetUpdateUnknownProtocol(t *testing.T) {
testenv.MustHaveExternalNetwork(t) testenv.MustHaveExternalNetwork(t)
testenv.MustHaveExecPath(t, "git")
tg := testgo(t) tg := testgo(t)
defer tg.cleanup() defer tg.cleanup()
...@@ -3760,6 +3762,7 @@ func TestGoGetUpdateUnknownProtocol(t *testing.T) { ...@@ -3760,6 +3762,7 @@ func TestGoGetUpdateUnknownProtocol(t *testing.T) {
func TestGoGetInsecureCustomDomain(t *testing.T) { func TestGoGetInsecureCustomDomain(t *testing.T) {
testenv.MustHaveExternalNetwork(t) testenv.MustHaveExternalNetwork(t)
testenv.MustHaveExecPath(t, "git")
tg := testgo(t) tg := testgo(t)
defer tg.cleanup() defer tg.cleanup()
...@@ -3862,6 +3865,7 @@ func TestGoGetUpdate(t *testing.T) { ...@@ -3862,6 +3865,7 @@ func TestGoGetUpdate(t *testing.T) {
// former dependencies, not current ones. // former dependencies, not current ones.
testenv.MustHaveExternalNetwork(t) testenv.MustHaveExternalNetwork(t)
testenv.MustHaveExecPath(t, "git")
tg := testgo(t) tg := testgo(t)
defer tg.cleanup() defer tg.cleanup()
...@@ -3889,6 +3893,7 @@ func TestGoGetUpdate(t *testing.T) { ...@@ -3889,6 +3893,7 @@ func TestGoGetUpdate(t *testing.T) {
// Issue #20512. // Issue #20512.
func TestGoGetRace(t *testing.T) { func TestGoGetRace(t *testing.T) {
testenv.MustHaveExternalNetwork(t) testenv.MustHaveExternalNetwork(t)
testenv.MustHaveExecPath(t, "git")
if !canRace { if !canRace {
t.Skip("skipping because race detector not supported") t.Skip("skipping because race detector not supported")
} }
...@@ -3905,6 +3910,7 @@ func TestGoGetDomainRoot(t *testing.T) { ...@@ -3905,6 +3910,7 @@ func TestGoGetDomainRoot(t *testing.T) {
// go get foo.io (not foo.io/subdir) was not working consistently. // go get foo.io (not foo.io/subdir) was not working consistently.
testenv.MustHaveExternalNetwork(t) testenv.MustHaveExternalNetwork(t)
testenv.MustHaveExecPath(t, "git")
tg := testgo(t) tg := testgo(t)
defer tg.cleanup() defer tg.cleanup()
...@@ -4295,6 +4301,7 @@ func TestGenerateUsesBuildContext(t *testing.T) { ...@@ -4295,6 +4301,7 @@ func TestGenerateUsesBuildContext(t *testing.T) {
// Issue 14450: go get -u .../ tried to import not downloaded package // Issue 14450: go get -u .../ tried to import not downloaded package
func TestGoGetUpdateWithWildcard(t *testing.T) { func TestGoGetUpdateWithWildcard(t *testing.T) {
testenv.MustHaveExternalNetwork(t) testenv.MustHaveExternalNetwork(t)
testenv.MustHaveExecPath(t, "git")
tg := testgo(t) tg := testgo(t)
defer tg.cleanup() defer tg.cleanup()
...@@ -5043,9 +5050,8 @@ func TestExecBuildX(t *testing.T) { ...@@ -5043,9 +5050,8 @@ func TestExecBuildX(t *testing.T) {
t.Skip("skipping because cgo not enabled") t.Skip("skipping because cgo not enabled")
} }
if runtime.GOOS == "plan9" || runtime.GOOS == "windows" { testenv.MustHaveExecPath(t, "/usr/bin/env")
t.Skipf("skipping because unix shell is not supported on %s", runtime.GOOS) testenv.MustHaveExecPath(t, "bash")
}
tg := testgo(t) tg := testgo(t)
defer tg.cleanup() defer tg.cleanup()
...@@ -5126,9 +5132,10 @@ func TestUpxCompression(t *testing.T) { ...@@ -5126,9 +5132,10 @@ func TestUpxCompression(t *testing.T) {
t.Skipf("skipping upx test on %s/%s", runtime.GOOS, runtime.GOARCH) t.Skipf("skipping upx test on %s/%s", runtime.GOOS, runtime.GOARCH)
} }
testenv.MustHaveExecPath(t, "upx")
out, err := exec.Command("upx", "--version").CombinedOutput() out, err := exec.Command("upx", "--version").CombinedOutput()
if err != nil { if err != nil {
t.Skip("skipping because upx is not available") t.Fatalf("upx --version failed: %v", err)
} }
// upx --version prints `upx <version>` in the first line of output: // upx --version prints `upx <version>` in the first line of output:
...@@ -5137,13 +5144,13 @@ func TestUpxCompression(t *testing.T) { ...@@ -5137,13 +5144,13 @@ func TestUpxCompression(t *testing.T) {
re := regexp.MustCompile(`([[:digit:]]+)\.([[:digit:]]+)`) re := regexp.MustCompile(`([[:digit:]]+)\.([[:digit:]]+)`)
upxVersion := re.FindStringSubmatch(string(out)) upxVersion := re.FindStringSubmatch(string(out))
if len(upxVersion) != 3 { if len(upxVersion) != 3 {
t.Errorf("bad upx version string: %s", upxVersion) t.Fatalf("bad upx version string: %s", upxVersion)
} }
major, err1 := strconv.Atoi(upxVersion[1]) major, err1 := strconv.Atoi(upxVersion[1])
minor, err2 := strconv.Atoi(upxVersion[2]) minor, err2 := strconv.Atoi(upxVersion[2])
if err1 != nil || err2 != nil { if err1 != nil || err2 != nil {
t.Errorf("bad upx version string: %s", upxVersion[0]) t.Fatalf("bad upx version string: %s", upxVersion[0])
} }
// Anything below 3.94 is known not to work with go binaries // Anything below 3.94 is known not to work with go binaries
...@@ -5196,26 +5203,29 @@ func TestQEMUUserMode(t *testing.T) { ...@@ -5196,26 +5203,29 @@ func TestQEMUUserMode(t *testing.T) {
src, obj := tg.path("main.go"), tg.path("main") src, obj := tg.path("main.go"), tg.path("main")
for _, arch := range testArchs { for _, arch := range testArchs {
out, err := exec.Command("qemu-"+arch.qemu, "--version").CombinedOutput() arch := arch
if err != nil { t.Run(arch.g, func(t *testing.T) {
t.Logf("Skipping %s test (qemu-%s not available)", arch.g, arch.qemu) qemu := "qemu-" + arch.qemu
continue testenv.MustHaveExecPath(t, qemu)
}
out, err := exec.Command(qemu, "--version").CombinedOutput()
if err != nil {
t.Fatalf("%s --version failed: %v", qemu, err)
}
tg.setenv("GOARCH", arch.g) tg.setenv("GOARCH", arch.g)
tg.run("build", "-o", obj, src) tg.run("build", "-o", obj, src)
out, err = exec.Command("qemu-"+arch.qemu, obj).CombinedOutput() out, err = exec.Command(qemu, obj).CombinedOutput()
if err != nil { if err != nil {
t.Logf("qemu-%s output:\n%s\n", arch.qemu, out) t.Logf("%s output:\n%s\n", qemu, out)
t.Errorf("qemu-%s failed with %v", arch.qemu, err) t.Fatalf("%s failed with %v", qemu, err)
continue }
} if want := "hello qemu-user"; string(out) != want {
if want := "hello qemu-user"; string(out) != want { t.Errorf("bad output from %s:\ngot %s; want %s", qemu, out, want)
t.Errorf("bad output from qemu-%s:\ngot %s; want %s", arch.qemu, out, want) }
} })
} }
} }
func TestCacheListStale(t *testing.T) { func TestCacheListStale(t *testing.T) {
......
...@@ -48,11 +48,12 @@ const ( ...@@ -48,11 +48,12 @@ const (
vgotest1hg = "vcs-test.golang.org/hg/vgotest1.hg" vgotest1hg = "vcs-test.golang.org/hg/vgotest1.hg"
) )
var altVgotests = []string{ var altVgotests = map[string]string{
vgotest1hg, "hg": vgotest1hg,
} }
type codeRepoTest struct { type codeRepoTest struct {
vcs string
path string path string
lookerr string lookerr string
mpath string mpath string
...@@ -70,6 +71,7 @@ type codeRepoTest struct { ...@@ -70,6 +71,7 @@ type codeRepoTest struct {
var codeRepoTests = []codeRepoTest{ var codeRepoTests = []codeRepoTest{
{ {
vcs: "git",
path: "github.com/rsc/vgotest1", path: "github.com/rsc/vgotest1",
rev: "v0.0.0", rev: "v0.0.0",
version: "v0.0.0", version: "v0.0.0",
...@@ -83,6 +85,7 @@ var codeRepoTests = []codeRepoTest{ ...@@ -83,6 +85,7 @@ var codeRepoTests = []codeRepoTest{
}, },
}, },
{ {
vcs: "git",
path: "github.com/rsc/vgotest1", path: "github.com/rsc/vgotest1",
rev: "v1.0.0", rev: "v1.0.0",
version: "v1.0.0", version: "v1.0.0",
...@@ -96,6 +99,7 @@ var codeRepoTests = []codeRepoTest{ ...@@ -96,6 +99,7 @@ var codeRepoTests = []codeRepoTest{
}, },
}, },
{ {
vcs: "git",
path: "github.com/rsc/vgotest1/v2", path: "github.com/rsc/vgotest1/v2",
rev: "v2.0.0", rev: "v2.0.0",
version: "v2.0.0", version: "v2.0.0",
...@@ -105,6 +109,7 @@ var codeRepoTests = []codeRepoTest{ ...@@ -105,6 +109,7 @@ var codeRepoTests = []codeRepoTest{
ziperr: "missing github.com/rsc/vgotest1/go.mod and .../v2/go.mod at revision v2.0.0", ziperr: "missing github.com/rsc/vgotest1/go.mod and .../v2/go.mod at revision v2.0.0",
}, },
{ {
vcs: "git",
path: "github.com/rsc/vgotest1", path: "github.com/rsc/vgotest1",
rev: "80d85c5", rev: "80d85c5",
version: "v1.0.0", version: "v1.0.0",
...@@ -118,6 +123,7 @@ var codeRepoTests = []codeRepoTest{ ...@@ -118,6 +123,7 @@ var codeRepoTests = []codeRepoTest{
}, },
}, },
{ {
vcs: "git",
path: "github.com/rsc/vgotest1", path: "github.com/rsc/vgotest1",
rev: "mytag", rev: "mytag",
version: "v1.0.0", version: "v1.0.0",
...@@ -131,6 +137,7 @@ var codeRepoTests = []codeRepoTest{ ...@@ -131,6 +137,7 @@ var codeRepoTests = []codeRepoTest{
}, },
}, },
{ {
vcs: "git",
path: "github.com/rsc/vgotest1/v2", path: "github.com/rsc/vgotest1/v2",
rev: "45f53230a", rev: "45f53230a",
version: "v2.0.0", version: "v2.0.0",
...@@ -141,6 +148,7 @@ var codeRepoTests = []codeRepoTest{ ...@@ -141,6 +148,7 @@ var codeRepoTests = []codeRepoTest{
ziperr: "missing github.com/rsc/vgotest1/go.mod and .../v2/go.mod at revision v2.0.0", ziperr: "missing github.com/rsc/vgotest1/go.mod and .../v2/go.mod at revision v2.0.0",
}, },
{ {
vcs: "git",
path: "github.com/rsc/vgotest1/v54321", path: "github.com/rsc/vgotest1/v54321",
rev: "80d85c5", rev: "80d85c5",
version: "v54321.0.0-20180219231006-80d85c5d4d17", version: "v54321.0.0-20180219231006-80d85c5d4d17",
...@@ -150,16 +158,19 @@ var codeRepoTests = []codeRepoTest{ ...@@ -150,16 +158,19 @@ var codeRepoTests = []codeRepoTest{
ziperr: "missing github.com/rsc/vgotest1/go.mod and .../v54321/go.mod at revision 80d85c5d4d17", ziperr: "missing github.com/rsc/vgotest1/go.mod and .../v54321/go.mod at revision 80d85c5d4d17",
}, },
{ {
vcs: "git",
path: "github.com/rsc/vgotest1/submod", path: "github.com/rsc/vgotest1/submod",
rev: "v1.0.0", rev: "v1.0.0",
err: "unknown revision submod/v1.0.0", err: "unknown revision submod/v1.0.0",
}, },
{ {
vcs: "git",
path: "github.com/rsc/vgotest1/submod", path: "github.com/rsc/vgotest1/submod",
rev: "v1.0.3", rev: "v1.0.3",
err: "unknown revision submod/v1.0.3", err: "unknown revision submod/v1.0.3",
}, },
{ {
vcs: "git",
path: "github.com/rsc/vgotest1/submod", path: "github.com/rsc/vgotest1/submod",
rev: "v1.0.4", rev: "v1.0.4",
version: "v1.0.4", version: "v1.0.4",
...@@ -174,6 +185,7 @@ var codeRepoTests = []codeRepoTest{ ...@@ -174,6 +185,7 @@ var codeRepoTests = []codeRepoTest{
}, },
}, },
{ {
vcs: "git",
path: "github.com/rsc/vgotest1", path: "github.com/rsc/vgotest1",
rev: "v1.1.0", rev: "v1.1.0",
version: "v1.1.0", version: "v1.1.0",
...@@ -189,6 +201,7 @@ var codeRepoTests = []codeRepoTest{ ...@@ -189,6 +201,7 @@ var codeRepoTests = []codeRepoTest{
}, },
}, },
{ {
vcs: "git",
path: "github.com/rsc/vgotest1/v2", path: "github.com/rsc/vgotest1/v2",
rev: "v2.0.1", rev: "v2.0.1",
version: "v2.0.1", version: "v2.0.1",
...@@ -198,6 +211,7 @@ var codeRepoTests = []codeRepoTest{ ...@@ -198,6 +211,7 @@ var codeRepoTests = []codeRepoTest{
gomod: "module \"github.com/rsc/vgotest1/v2\" // root go.mod\n", gomod: "module \"github.com/rsc/vgotest1/v2\" // root go.mod\n",
}, },
{ {
vcs: "git",
path: "github.com/rsc/vgotest1/v2", path: "github.com/rsc/vgotest1/v2",
rev: "v2.0.3", rev: "v2.0.3",
version: "v2.0.3", version: "v2.0.3",
...@@ -207,6 +221,7 @@ var codeRepoTests = []codeRepoTest{ ...@@ -207,6 +221,7 @@ var codeRepoTests = []codeRepoTest{
gomoderr: "github.com/rsc/vgotest1/v2/go.mod has non-.../v2 module path \"github.com/rsc/vgotest\" at revision v2.0.3", gomoderr: "github.com/rsc/vgotest1/v2/go.mod has non-.../v2 module path \"github.com/rsc/vgotest\" at revision v2.0.3",
}, },
{ {
vcs: "git",
path: "github.com/rsc/vgotest1/v2", path: "github.com/rsc/vgotest1/v2",
rev: "v2.0.4", rev: "v2.0.4",
version: "v2.0.4", version: "v2.0.4",
...@@ -216,6 +231,7 @@ var codeRepoTests = []codeRepoTest{ ...@@ -216,6 +231,7 @@ var codeRepoTests = []codeRepoTest{
gomoderr: "github.com/rsc/vgotest1/go.mod and .../v2/go.mod both have .../v2 module paths at revision v2.0.4", gomoderr: "github.com/rsc/vgotest1/go.mod and .../v2/go.mod both have .../v2 module paths at revision v2.0.4",
}, },
{ {
vcs: "git",
path: "github.com/rsc/vgotest1/v2", path: "github.com/rsc/vgotest1/v2",
rev: "v2.0.5", rev: "v2.0.5",
version: "v2.0.5", version: "v2.0.5",
...@@ -226,6 +242,7 @@ var codeRepoTests = []codeRepoTest{ ...@@ -226,6 +242,7 @@ var codeRepoTests = []codeRepoTest{
}, },
{ {
// redirect to github // redirect to github
vcs: "git",
path: "rsc.io/quote", path: "rsc.io/quote",
rev: "v1.0.0", rev: "v1.0.0",
version: "v1.0.0", version: "v1.0.0",
...@@ -236,6 +253,7 @@ var codeRepoTests = []codeRepoTest{ ...@@ -236,6 +253,7 @@ var codeRepoTests = []codeRepoTest{
}, },
{ {
// redirect to static hosting proxy // redirect to static hosting proxy
vcs: "mod",
path: "swtch.com/testmod", path: "swtch.com/testmod",
rev: "v1.0.0", rev: "v1.0.0",
version: "v1.0.0", version: "v1.0.0",
...@@ -245,6 +263,7 @@ var codeRepoTests = []codeRepoTest{ ...@@ -245,6 +263,7 @@ var codeRepoTests = []codeRepoTest{
}, },
{ {
// redirect to googlesource // redirect to googlesource
vcs: "git",
path: "golang.org/x/text", path: "golang.org/x/text",
rev: "4e4a3210bb", rev: "4e4a3210bb",
version: "v0.3.1-0.20180208041248-4e4a3210bb54", version: "v0.3.1-0.20180208041248-4e4a3210bb54",
...@@ -253,6 +272,7 @@ var codeRepoTests = []codeRepoTest{ ...@@ -253,6 +272,7 @@ var codeRepoTests = []codeRepoTest{
time: time.Date(2018, 2, 8, 4, 12, 48, 0, time.UTC), time: time.Date(2018, 2, 8, 4, 12, 48, 0, time.UTC),
}, },
{ {
vcs: "git",
path: "github.com/pkg/errors", path: "github.com/pkg/errors",
rev: "v0.8.0", rev: "v0.8.0",
version: "v0.8.0", version: "v0.8.0",
...@@ -264,17 +284,20 @@ var codeRepoTests = []codeRepoTest{ ...@@ -264,17 +284,20 @@ var codeRepoTests = []codeRepoTest{
// package in subdirectory - custom domain // package in subdirectory - custom domain
// In general we can't reject these definitively in Lookup, // In general we can't reject these definitively in Lookup,
// but gopkg.in is special. // but gopkg.in is special.
vcs: "git",
path: "gopkg.in/yaml.v2/abc", path: "gopkg.in/yaml.v2/abc",
lookerr: "invalid module path \"gopkg.in/yaml.v2/abc\"", lookerr: "invalid module path \"gopkg.in/yaml.v2/abc\"",
}, },
{ {
// package in subdirectory - github // package in subdirectory - github
// Because it's a package, Stat should fail entirely. // Because it's a package, Stat should fail entirely.
vcs: "git",
path: "github.com/rsc/quote/buggy", path: "github.com/rsc/quote/buggy",
rev: "c4d4236f", rev: "c4d4236f",
err: "missing github.com/rsc/quote/buggy/go.mod at revision c4d4236f9242", err: "missing github.com/rsc/quote/buggy/go.mod at revision c4d4236f9242",
}, },
{ {
vcs: "git",
path: "gopkg.in/yaml.v2", path: "gopkg.in/yaml.v2",
rev: "d670f940", rev: "d670f940",
version: "v2.0.0", version: "v2.0.0",
...@@ -284,6 +307,7 @@ var codeRepoTests = []codeRepoTest{ ...@@ -284,6 +307,7 @@ var codeRepoTests = []codeRepoTest{
gomod: "module gopkg.in/yaml.v2\n", gomod: "module gopkg.in/yaml.v2\n",
}, },
{ {
vcs: "git",
path: "gopkg.in/check.v1", path: "gopkg.in/check.v1",
rev: "20d25e280405", rev: "20d25e280405",
version: "v1.0.0-20161208181325-20d25e280405", version: "v1.0.0-20161208181325-20d25e280405",
...@@ -293,6 +317,7 @@ var codeRepoTests = []codeRepoTest{ ...@@ -293,6 +317,7 @@ var codeRepoTests = []codeRepoTest{
gomod: "module gopkg.in/check.v1\n", gomod: "module gopkg.in/check.v1\n",
}, },
{ {
vcs: "git",
path: "gopkg.in/yaml.v2", path: "gopkg.in/yaml.v2",
rev: "v2", rev: "v2",
version: "v2.2.3-0.20190319135612-7b8349ac747c", version: "v2.2.3-0.20190319135612-7b8349ac747c",
...@@ -302,6 +327,7 @@ var codeRepoTests = []codeRepoTest{ ...@@ -302,6 +327,7 @@ var codeRepoTests = []codeRepoTest{
gomod: "module \"gopkg.in/yaml.v2\"\n\nrequire (\n\t\"gopkg.in/check.v1\" v0.0.0-20161208181325-20d25e280405\n)\n", gomod: "module \"gopkg.in/yaml.v2\"\n\nrequire (\n\t\"gopkg.in/check.v1\" v0.0.0-20161208181325-20d25e280405\n)\n",
}, },
{ {
vcs: "git",
path: "vcs-test.golang.org/go/mod/gitrepo1", path: "vcs-test.golang.org/go/mod/gitrepo1",
rev: "master", rev: "master",
version: "v1.2.4-annotated", version: "v1.2.4-annotated",
...@@ -311,6 +337,7 @@ var codeRepoTests = []codeRepoTest{ ...@@ -311,6 +337,7 @@ var codeRepoTests = []codeRepoTest{
gomod: "module vcs-test.golang.org/go/mod/gitrepo1\n", gomod: "module vcs-test.golang.org/go/mod/gitrepo1\n",
}, },
{ {
vcs: "git",
path: "gopkg.in/natefinch/lumberjack.v2", path: "gopkg.in/natefinch/lumberjack.v2",
rev: "latest", rev: "latest",
version: "v2.0.0-20170531160350-a96e63847dc3", version: "v2.0.0-20170531160350-a96e63847dc3",
...@@ -320,6 +347,7 @@ var codeRepoTests = []codeRepoTest{ ...@@ -320,6 +347,7 @@ var codeRepoTests = []codeRepoTest{
gomod: "module gopkg.in/natefinch/lumberjack.v2\n", gomod: "module gopkg.in/natefinch/lumberjack.v2\n",
}, },
{ {
vcs: "git",
path: "gopkg.in/natefinch/lumberjack.v2", path: "gopkg.in/natefinch/lumberjack.v2",
// This repo has a v2.1 tag. // This repo has a v2.1 tag.
// We only allow semver references to tags that are fully qualified, as in v2.1.0. // We only allow semver references to tags that are fully qualified, as in v2.1.0.
...@@ -335,6 +363,7 @@ var codeRepoTests = []codeRepoTest{ ...@@ -335,6 +363,7 @@ var codeRepoTests = []codeRepoTest{
gomod: "module gopkg.in/natefinch/lumberjack.v2\n", gomod: "module gopkg.in/natefinch/lumberjack.v2\n",
}, },
{ {
vcs: "git",
path: "vcs-test.golang.org/go/v2module/v2", path: "vcs-test.golang.org/go/v2module/v2",
rev: "v2.0.0", rev: "v2.0.0",
version: "v2.0.0", version: "v2.0.0",
...@@ -359,6 +388,9 @@ func TestCodeRepo(t *testing.T) { ...@@ -359,6 +388,9 @@ func TestCodeRepo(t *testing.T) {
f := func(tt codeRepoTest) func(t *testing.T) { f := func(tt codeRepoTest) func(t *testing.T) {
return func(t *testing.T) { return func(t *testing.T) {
t.Parallel() t.Parallel()
if tt.vcs != "mod" {
testenv.MustHaveExecPath(t, tt.vcs)
}
repo, err := Lookup("direct", tt.path) repo, err := Lookup("direct", tt.path)
if tt.lookerr != "" { if tt.lookerr != "" {
...@@ -457,9 +489,10 @@ func TestCodeRepo(t *testing.T) { ...@@ -457,9 +489,10 @@ func TestCodeRepo(t *testing.T) {
} }
t.Run(strings.ReplaceAll(tt.path, "/", "_")+"/"+tt.rev, f(tt)) t.Run(strings.ReplaceAll(tt.path, "/", "_")+"/"+tt.rev, f(tt))
if strings.HasPrefix(tt.path, vgotest1git) { if strings.HasPrefix(tt.path, vgotest1git) {
for _, alt := range altVgotests { for vcs, alt := range altVgotests {
// Note: Communicating with f through tt; should be cleaned up. // Note: Communicating with f through tt; should be cleaned up.
old := tt old := tt
tt.vcs = vcs
tt.path = alt + strings.TrimPrefix(tt.path, vgotest1git) tt.path = alt + strings.TrimPrefix(tt.path, vgotest1git)
if strings.HasPrefix(tt.mpath, vgotest1git) { if strings.HasPrefix(tt.mpath, vgotest1git) {
tt.mpath = alt + strings.TrimPrefix(tt.mpath, vgotest1git) tt.mpath = alt + strings.TrimPrefix(tt.mpath, vgotest1git)
...@@ -515,32 +548,39 @@ func remap(name string, m map[string]string) string { ...@@ -515,32 +548,39 @@ func remap(name string, m map[string]string) string {
} }
var codeRepoVersionsTests = []struct { var codeRepoVersionsTests = []struct {
vcs string
path string path string
prefix string prefix string
versions []string versions []string
}{ }{
{ {
vcs: "git",
path: "github.com/rsc/vgotest1", path: "github.com/rsc/vgotest1",
versions: []string{"v0.0.0", "v0.0.1", "v1.0.0", "v1.0.1", "v1.0.2", "v1.0.3", "v1.1.0", "v2.0.0+incompatible"}, versions: []string{"v0.0.0", "v0.0.1", "v1.0.0", "v1.0.1", "v1.0.2", "v1.0.3", "v1.1.0", "v2.0.0+incompatible"},
}, },
{ {
vcs: "git",
path: "github.com/rsc/vgotest1", path: "github.com/rsc/vgotest1",
prefix: "v1.0", prefix: "v1.0",
versions: []string{"v1.0.0", "v1.0.1", "v1.0.2", "v1.0.3"}, versions: []string{"v1.0.0", "v1.0.1", "v1.0.2", "v1.0.3"},
}, },
{ {
vcs: "git",
path: "github.com/rsc/vgotest1/v2", path: "github.com/rsc/vgotest1/v2",
versions: []string{"v2.0.0", "v2.0.1", "v2.0.2", "v2.0.3", "v2.0.4", "v2.0.5", "v2.0.6"}, versions: []string{"v2.0.0", "v2.0.1", "v2.0.2", "v2.0.3", "v2.0.4", "v2.0.5", "v2.0.6"},
}, },
{ {
vcs: "mod",
path: "swtch.com/testmod", path: "swtch.com/testmod",
versions: []string{"v1.0.0", "v1.1.1"}, versions: []string{"v1.0.0", "v1.1.1"},
}, },
{ {
vcs: "git",
path: "gopkg.in/russross/blackfriday.v2", path: "gopkg.in/russross/blackfriday.v2",
versions: []string{"v2.0.0", "v2.0.1"}, versions: []string{"v2.0.0", "v2.0.1"},
}, },
{ {
vcs: "git",
path: "gopkg.in/natefinch/lumberjack.v2", path: "gopkg.in/natefinch/lumberjack.v2",
versions: []string{"v2.0.0"}, versions: []string{"v2.0.0"},
}, },
...@@ -560,6 +600,9 @@ func TestCodeRepoVersions(t *testing.T) { ...@@ -560,6 +600,9 @@ func TestCodeRepoVersions(t *testing.T) {
t.Run(strings.ReplaceAll(tt.path, "/", "_"), func(t *testing.T) { t.Run(strings.ReplaceAll(tt.path, "/", "_"), func(t *testing.T) {
tt := tt tt := tt
t.Parallel() t.Parallel()
if tt.vcs != "mod" {
testenv.MustHaveExecPath(t, tt.vcs)
}
repo, err := Lookup("direct", tt.path) repo, err := Lookup("direct", tt.path)
if err != nil { if err != nil {
...@@ -578,23 +621,28 @@ func TestCodeRepoVersions(t *testing.T) { ...@@ -578,23 +621,28 @@ func TestCodeRepoVersions(t *testing.T) {
} }
var latestTests = []struct { var latestTests = []struct {
vcs string
path string path string
version string version string
err string err string
}{ }{
{ {
vcs: "git",
path: "github.com/rsc/empty", path: "github.com/rsc/empty",
err: "no commits", err: "no commits",
}, },
{ {
vcs: "git",
path: "github.com/rsc/vgotest1", path: "github.com/rsc/vgotest1",
version: "v0.0.0-20180219223237-a08abb797a67", version: "v0.0.0-20180219223237-a08abb797a67",
}, },
{ {
vcs: "git",
path: "github.com/rsc/vgotest1/subdir", path: "github.com/rsc/vgotest1/subdir",
err: "missing github.com/rsc/vgotest1/subdir/go.mod at revision a08abb797a67", err: "missing github.com/rsc/vgotest1/subdir/go.mod at revision a08abb797a67",
}, },
{ {
vcs: "mod",
path: "swtch.com/testmod", path: "swtch.com/testmod",
version: "v1.1.1", version: "v1.1.1",
}, },
...@@ -615,6 +663,9 @@ func TestLatest(t *testing.T) { ...@@ -615,6 +663,9 @@ func TestLatest(t *testing.T) {
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
tt := tt tt := tt
t.Parallel() t.Parallel()
if tt.vcs != "mod" {
testenv.MustHaveExecPath(t, tt.vcs)
}
repo, err := Lookup("direct", tt.path) repo, err := Lookup("direct", tt.path)
if err != nil { if err != nil {
......
...@@ -43,6 +43,7 @@ var importTests = []struct { ...@@ -43,6 +43,7 @@ var importTests = []struct {
func TestImport(t *testing.T) { func TestImport(t *testing.T) {
testenv.MustHaveExternalNetwork(t) testenv.MustHaveExternalNetwork(t)
testenv.MustHaveExecPath(t, "git")
for _, tt := range importTests { for _, tt := range importTests {
t.Run(strings.ReplaceAll(tt.path, "/", "_"), func(t *testing.T) { t.Run(strings.ReplaceAll(tt.path, "/", "_"), func(t *testing.T) {
......
...@@ -136,6 +136,7 @@ var queryTests = []struct { ...@@ -136,6 +136,7 @@ var queryTests = []struct {
func TestQuery(t *testing.T) { func TestQuery(t *testing.T) {
testenv.MustHaveExternalNetwork(t) testenv.MustHaveExternalNetwork(t)
testenv.MustHaveExecPath(t, "git")
for _, tt := range queryTests { for _, tt := range queryTests {
allow := tt.allow allow := tt.allow
......
# golang.org/issue/13037: 'go get' was not parsing <meta> tags in 404 served over HTTPS. # golang.org/issue/13037: 'go get' was not parsing <meta> tags in 404 served over HTTPS.
[!net] skip [!net] skip
[!exec:git] skip
env GO111MODULE=off env GO111MODULE=off
go get -d -insecure bazil.org/fuse/fs/fstestutil go get -d -insecure bazil.org/fuse/fs/fstestutil
......
# golang.org/issue/29591: 'go get' was following plain-HTTP redirects even without -insecure. # golang.org/issue/29591: 'go get' was following plain-HTTP redirects even without -insecure.
[!net] skip [!net] skip
[!exec:git] skip
env GO111MODULE=on env GO111MODULE=on
env GOPROXY=direct env GOPROXY=direct
......
...@@ -2,6 +2,7 @@ env GO111MODULE=on ...@@ -2,6 +2,7 @@ env GO111MODULE=on
env GOPROXY=direct env GOPROXY=direct
env GOSUMDB=off env GOSUMDB=off
[!net] skip [!net] skip
[!exec:git] skip
# fetch commit hash reachable from refs/heads/* and refs/tags/* is OK # fetch commit hash reachable from refs/heads/* and refs/tags/* is OK
go list -m golang.org/x/time@8be79e1e0910c292df4e79c241bb7e8f7e725959 # on master branch go list -m golang.org/x/time@8be79e1e0910c292df4e79c241bb7e8f7e725959 # on master branch
...@@ -16,4 +17,3 @@ stderr 'unknown revision' ...@@ -16,4 +17,3 @@ stderr 'unknown revision'
-- go.mod -- -- go.mod --
module m module m
...@@ -16,6 +16,7 @@ go get rsc.io/quote ...@@ -16,6 +16,7 @@ go get rsc.io/quote
# and GONOPROXY bypasses proxy # and GONOPROXY bypasses proxy
[!net] skip [!net] skip
[!exec:git] skip
env GONOPROXY='*/fortune' env GONOPROXY='*/fortune'
! go get rsc.io/fortune # does not exist in real world, only on test proxy ! go get rsc.io/fortune # does not exist in real world, only on test proxy
stderr 'git ls-remote' stderr 'git ls-remote'
......
...@@ -8,6 +8,7 @@ cp go.mod.empty go.mod ...@@ -8,6 +8,7 @@ cp go.mod.empty go.mod
go list go list
[!net] skip [!net] skip
[!exec:git] skip
env GOPROXY=direct env GOPROXY=direct
env GOSUMDB=off env GOSUMDB=off
......
...@@ -11,6 +11,7 @@ stdout '^sum.golang.org$' ...@@ -11,6 +11,7 @@ stdout '^sum.golang.org$'
# download direct from github # download direct from github
[!net] skip [!net] skip
[!exec:git] skip
env GOSUMDB=sum.golang.org env GOSUMDB=sum.golang.org
env GOPROXY=direct env GOPROXY=direct
go get -d rsc.io/quote go get -d rsc.io/quote
......
...@@ -181,6 +181,7 @@ func TestVendorGet(t *testing.T) { ...@@ -181,6 +181,7 @@ func TestVendorGet(t *testing.T) {
func TestVendorGetUpdate(t *testing.T) { func TestVendorGetUpdate(t *testing.T) {
testenv.MustHaveExternalNetwork(t) testenv.MustHaveExternalNetwork(t)
testenv.MustHaveExecPath(t, "git")
tg := testgo(t) tg := testgo(t)
defer tg.cleanup() defer tg.cleanup()
...@@ -192,6 +193,7 @@ func TestVendorGetUpdate(t *testing.T) { ...@@ -192,6 +193,7 @@ func TestVendorGetUpdate(t *testing.T) {
func TestVendorGetU(t *testing.T) { func TestVendorGetU(t *testing.T) {
testenv.MustHaveExternalNetwork(t) testenv.MustHaveExternalNetwork(t)
testenv.MustHaveExecPath(t, "git")
tg := testgo(t) tg := testgo(t)
defer tg.cleanup() defer tg.cleanup()
...@@ -202,6 +204,7 @@ func TestVendorGetU(t *testing.T) { ...@@ -202,6 +204,7 @@ func TestVendorGetU(t *testing.T) {
func TestVendorGetTU(t *testing.T) { func TestVendorGetTU(t *testing.T) {
testenv.MustHaveExternalNetwork(t) testenv.MustHaveExternalNetwork(t)
testenv.MustHaveExecPath(t, "git")
tg := testgo(t) tg := testgo(t)
defer tg.cleanup() defer tg.cleanup()
...@@ -212,6 +215,7 @@ func TestVendorGetTU(t *testing.T) { ...@@ -212,6 +215,7 @@ func TestVendorGetTU(t *testing.T) {
func TestVendorGetBadVendor(t *testing.T) { func TestVendorGetBadVendor(t *testing.T) {
testenv.MustHaveExternalNetwork(t) testenv.MustHaveExternalNetwork(t)
testenv.MustHaveExecPath(t, "git")
for _, suffix := range []string{"bad/imp", "bad/imp2", "bad/imp3", "..."} { for _, suffix := range []string{"bad/imp", "bad/imp2", "bad/imp3", "..."} {
t.Run(suffix, func(t *testing.T) { t.Run(suffix, func(t *testing.T) {
...@@ -228,6 +232,7 @@ func TestVendorGetBadVendor(t *testing.T) { ...@@ -228,6 +232,7 @@ func TestVendorGetBadVendor(t *testing.T) {
func TestGetSubmodules(t *testing.T) { func TestGetSubmodules(t *testing.T) {
testenv.MustHaveExternalNetwork(t) testenv.MustHaveExternalNetwork(t)
testenv.MustHaveExecPath(t, "git")
tg := testgo(t) tg := testgo(t)
defer tg.cleanup() defer tg.cleanup()
...@@ -248,6 +253,7 @@ func TestVendorCache(t *testing.T) { ...@@ -248,6 +253,7 @@ func TestVendorCache(t *testing.T) {
func TestVendorTest2(t *testing.T) { func TestVendorTest2(t *testing.T) {
testenv.MustHaveExternalNetwork(t) testenv.MustHaveExternalNetwork(t)
testenv.MustHaveExecPath(t, "git")
tg := testgo(t) tg := testgo(t)
defer tg.cleanup() defer tg.cleanup()
...@@ -273,6 +279,7 @@ func TestVendorTest2(t *testing.T) { ...@@ -273,6 +279,7 @@ func TestVendorTest2(t *testing.T) {
func TestVendorTest3(t *testing.T) { func TestVendorTest3(t *testing.T) {
testenv.MustHaveExternalNetwork(t) testenv.MustHaveExternalNetwork(t)
testenv.MustHaveExecPath(t, "git")
tg := testgo(t) tg := testgo(t)
defer tg.cleanup() defer tg.cleanup()
...@@ -299,6 +306,7 @@ func TestVendorTest3(t *testing.T) { ...@@ -299,6 +306,7 @@ func TestVendorTest3(t *testing.T) {
func TestVendorList(t *testing.T) { func TestVendorList(t *testing.T) {
testenv.MustHaveExternalNetwork(t) testenv.MustHaveExternalNetwork(t)
testenv.MustHaveExecPath(t, "git")
tg := testgo(t) tg := testgo(t)
defer tg.cleanup() defer tg.cleanup()
...@@ -349,6 +357,7 @@ func TestLegacyMod(t *testing.T) { ...@@ -349,6 +357,7 @@ func TestLegacyMod(t *testing.T) {
func TestLegacyModGet(t *testing.T) { func TestLegacyModGet(t *testing.T) {
testenv.MustHaveExternalNetwork(t) testenv.MustHaveExternalNetwork(t)
testenv.MustHaveExecPath(t, "git")
tg := testgo(t) tg := testgo(t)
defer tg.cleanup() defer tg.cleanup()
......
...@@ -19,6 +19,7 @@ import ( ...@@ -19,6 +19,7 @@ import (
"runtime" "runtime"
"strconv" "strconv"
"strings" "strings"
"sync"
"testing" "testing"
) )
...@@ -146,6 +147,24 @@ func MustHaveExec(t testing.TB) { ...@@ -146,6 +147,24 @@ func MustHaveExec(t testing.TB) {
} }
} }
var execPaths sync.Map // path -> error
// MustHaveExecPath checks that the current system can start the named executable
// using os.StartProcess or (more commonly) exec.Command.
// If not, MustHaveExecPath calls t.Skip with an explanation.
func MustHaveExecPath(t testing.TB, path string) {
MustHaveExec(t)
err, found := execPaths.Load(path)
if !found {
_, err = exec.LookPath(path)
err, _ = execPaths.LoadOrStore(path, err)
}
if err != nil {
t.Skipf("skipping test: %s: %s", path, err)
}
}
// HasExternalNetwork reports whether the current system can use // HasExternalNetwork reports whether the current system can use
// external (non-localhost) networks. // external (non-localhost) networks.
func HasExternalNetwork() bool { func HasExternalNetwork() bool {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment