mirror of
https://github.com/golang/go.git
synced 2025-05-05 15:43:04 +00:00
all: skip tests if required tools are not found
Fixes golang/go#33950 Change-Id: Iefcb757e773bc052793611c099c25a457fd7e243 Reviewed-on: https://go-review.googlesource.com/c/tools/+/192400 Run-TryBot: Bryan C. Mills <bcmills@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Cottrell <iancottrell@google.com>
This commit is contained in:
parent
f340ed3ae2
commit
c17b040389
@ -17,6 +17,8 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"golang.org/x/tools/internal/testenv"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -32,6 +34,8 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestCallgraph(t *testing.T) {
|
func TestCallgraph(t *testing.T) {
|
||||||
|
testenv.NeedsTool(t, "go")
|
||||||
|
|
||||||
gopath, err := filepath.Abs("testdata")
|
gopath, err := filepath.Abs("testdata")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
@ -16,6 +16,8 @@ import (
|
|||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"golang.org/x/tools/internal/testenv"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -44,6 +46,8 @@ var debug = false // Keeps the rewritten files around if set.
|
|||||||
// go run ./testdata/main.go ./testdata/test.go
|
// go run ./testdata/main.go ./testdata/test.go
|
||||||
//
|
//
|
||||||
func TestCover(t *testing.T) {
|
func TestCover(t *testing.T) {
|
||||||
|
testenv.NeedsTool(t, "go")
|
||||||
|
|
||||||
// Read in the test file (testTest) and write it, with LINEs specified, to coverInput.
|
// Read in the test file (testTest) and write it, with LINEs specified, to coverInput.
|
||||||
file, err := ioutil.ReadFile(testTest)
|
file, err := ioutil.ReadFile(testTest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -16,6 +16,8 @@ import (
|
|||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"golang.org/x/tools/internal/testenv"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO(adonovan):
|
// TODO(adonovan):
|
||||||
@ -52,6 +54,8 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestFixImports(t *testing.T) {
|
func TestFixImports(t *testing.T) {
|
||||||
|
testenv.NeedsTool(t, "go")
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
stderr = os.Stderr
|
stderr = os.Stderr
|
||||||
*badDomains = "code.google.com"
|
*badDomains = "code.google.com"
|
||||||
@ -239,6 +243,8 @@ import (
|
|||||||
|
|
||||||
// TestDryRun tests that the -n flag suppresses calls to writeFile.
|
// TestDryRun tests that the -n flag suppresses calls to writeFile.
|
||||||
func TestDryRun(t *testing.T) {
|
func TestDryRun(t *testing.T) {
|
||||||
|
testenv.NeedsTool(t, "go")
|
||||||
|
|
||||||
*dryrun = true
|
*dryrun = true
|
||||||
defer func() { *dryrun = false }() // restore
|
defer func() { *dryrun = false }() // restore
|
||||||
stderr = new(bytes.Buffer)
|
stderr = new(bytes.Buffer)
|
||||||
|
@ -21,6 +21,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"golang.org/x/tools/internal/testenv"
|
||||||
)
|
)
|
||||||
|
|
||||||
// buildGodoc builds the godoc executable.
|
// buildGodoc builds the godoc executable.
|
||||||
@ -29,12 +31,15 @@ import (
|
|||||||
// TODO(adonovan): opt: do this at most once, and do the cleanup
|
// TODO(adonovan): opt: do this at most once, and do the cleanup
|
||||||
// exactly once. How though? There's no atexit.
|
// exactly once. How though? There's no atexit.
|
||||||
func buildGodoc(t *testing.T) (bin string, cleanup func()) {
|
func buildGodoc(t *testing.T) (bin string, cleanup func()) {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
if runtime.GOARCH == "arm" {
|
if runtime.GOARCH == "arm" {
|
||||||
t.Skip("skipping test on arm platforms; too slow")
|
t.Skip("skipping test on arm platforms; too slow")
|
||||||
}
|
}
|
||||||
if runtime.GOOS == "android" {
|
if runtime.GOOS == "android" {
|
||||||
t.Skipf("the dependencies are not available on android")
|
t.Skipf("the dependencies are not available on android")
|
||||||
}
|
}
|
||||||
|
testenv.NeedsTool(t, "go")
|
||||||
|
|
||||||
tmp, err := ioutil.TempDir("", "godoc-regtest-")
|
tmp, err := ioutil.TempDir("", "godoc-regtest-")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -14,6 +14,8 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"golang.org/x/tools/internal/testenv"
|
||||||
)
|
)
|
||||||
|
|
||||||
var haveCGO bool
|
var haveCGO bool
|
||||||
@ -32,6 +34,7 @@ func TestGeneratedFiles(t *testing.T) {
|
|||||||
if !haveCGO {
|
if !haveCGO {
|
||||||
t.Skipf("skipping test: no cgo")
|
t.Skipf("skipping test: no cgo")
|
||||||
}
|
}
|
||||||
|
testenv.NeedsTool(t, "go")
|
||||||
|
|
||||||
tmp, bin, cleanup := buildGorename(t)
|
tmp, bin, cleanup := buildGorename(t)
|
||||||
defer cleanup()
|
defer cleanup()
|
||||||
|
@ -48,6 +48,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
guru "golang.org/x/tools/cmd/guru"
|
guru "golang.org/x/tools/cmd/guru"
|
||||||
|
"golang.org/x/tools/internal/testenv"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -296,6 +297,7 @@ func TestGuru(t *testing.T) {
|
|||||||
default:
|
default:
|
||||||
cmd = exec.Command("/usr/bin/diff", "-u", golden, got)
|
cmd = exec.Command("/usr/bin/diff", "-u", golden, got)
|
||||||
}
|
}
|
||||||
|
testenv.NeedsTool(t, cmd.Path)
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
cmd.Stdout = buf
|
cmd.Stdout = buf
|
||||||
cmd.Stderr = os.Stderr
|
cmd.Stderr = os.Stderr
|
||||||
|
@ -19,6 +19,8 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"golang.org/x/tools/internal/testenv"
|
||||||
)
|
)
|
||||||
|
|
||||||
// This file contains a test that compiles and runs each program in testdata
|
// This file contains a test that compiles and runs each program in testdata
|
||||||
@ -151,6 +153,8 @@ func TestConstValueChange(t *testing.T) {
|
|||||||
// buildStringer creates a temporary directory and installs stringer there.
|
// buildStringer creates a temporary directory and installs stringer there.
|
||||||
func buildStringer(t *testing.T) (dir string, stringer string) {
|
func buildStringer(t *testing.T) (dir string, stringer string) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
testenv.NeedsTool(t, "go")
|
||||||
|
|
||||||
dir, err := ioutil.TempDir("", "stringer")
|
dir, err := ioutil.TempDir("", "stringer")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
@ -15,6 +15,8 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"golang.org/x/tools/internal/testenv"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Golden represents a test case.
|
// Golden represents a test case.
|
||||||
@ -398,6 +400,8 @@ func (i Token) String() string {
|
|||||||
`
|
`
|
||||||
|
|
||||||
func TestGolden(t *testing.T) {
|
func TestGolden(t *testing.T) {
|
||||||
|
testenv.NeedsTool(t, "go")
|
||||||
|
|
||||||
dir, err := ioutil.TempDir("", "stringer")
|
dir, err := ioutil.TempDir("", "stringer")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
|
@ -18,6 +18,7 @@ import (
|
|||||||
"golang.org/x/tools/go/analysis"
|
"golang.org/x/tools/go/analysis"
|
||||||
"golang.org/x/tools/go/analysis/internal/checker"
|
"golang.org/x/tools/go/analysis/internal/checker"
|
||||||
"golang.org/x/tools/go/packages"
|
"golang.org/x/tools/go/packages"
|
||||||
|
"golang.org/x/tools/internal/testenv"
|
||||||
)
|
)
|
||||||
|
|
||||||
// WriteFiles is a helper function that creates a temporary directory
|
// WriteFiles is a helper function that creates a temporary directory
|
||||||
@ -98,6 +99,10 @@ type Testing interface {
|
|||||||
// attempted, even if unsuccessful. It is safe for a test to ignore all
|
// attempted, even if unsuccessful. It is safe for a test to ignore all
|
||||||
// the results, but a test may use it to perform additional checks.
|
// the results, but a test may use it to perform additional checks.
|
||||||
func Run(t Testing, dir string, a *analysis.Analyzer, patterns ...string) []*Result {
|
func Run(t Testing, dir string, a *analysis.Analyzer, patterns ...string) []*Result {
|
||||||
|
if t, ok := t.(testenv.Testing); ok {
|
||||||
|
testenv.NeedsGoPackages(t)
|
||||||
|
}
|
||||||
|
|
||||||
pkgs, err := loadPackages(dir, patterns...)
|
pkgs, err := loadPackages(dir, patterns...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("loading %s: %v", patterns, err)
|
t.Errorf("loading %s: %v", patterns, err)
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
|
|
||||||
"golang.org/x/tools/go/analysis/analysistest"
|
"golang.org/x/tools/go/analysis/analysistest"
|
||||||
"golang.org/x/tools/go/analysis/passes/findcall"
|
"golang.org/x/tools/go/analysis/passes/findcall"
|
||||||
|
"golang.org/x/tools/internal/testenv"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -26,6 +27,8 @@ func init() {
|
|||||||
|
|
||||||
// TestTheTest tests the analysistest testing infrastructure.
|
// TestTheTest tests the analysistest testing infrastructure.
|
||||||
func TestTheTest(t *testing.T) {
|
func TestTheTest(t *testing.T) {
|
||||||
|
testenv.NeedsTool(t, "go")
|
||||||
|
|
||||||
// We'll simulate a partly failing test of the findcall analysis,
|
// We'll simulate a partly failing test of the findcall analysis,
|
||||||
// which (by default) reports calls to functions named 'println'.
|
// which (by default) reports calls to functions named 'println'.
|
||||||
findcall.Analyzer.Flags.Set("name", "println")
|
findcall.Analyzer.Flags.Set("name", "println")
|
||||||
|
@ -12,11 +12,14 @@ import (
|
|||||||
"golang.org/x/tools/go/analysis/internal/checker"
|
"golang.org/x/tools/go/analysis/internal/checker"
|
||||||
"golang.org/x/tools/go/analysis/passes/inspect"
|
"golang.org/x/tools/go/analysis/passes/inspect"
|
||||||
"golang.org/x/tools/go/ast/inspector"
|
"golang.org/x/tools/go/ast/inspector"
|
||||||
|
"golang.org/x/tools/internal/testenv"
|
||||||
)
|
)
|
||||||
|
|
||||||
var from, to string
|
var from, to string
|
||||||
|
|
||||||
func TestApplyFixes(t *testing.T) {
|
func TestApplyFixes(t *testing.T) {
|
||||||
|
testenv.NeedsGoPackages(t)
|
||||||
|
|
||||||
from = "bar"
|
from = "bar"
|
||||||
to = "baz"
|
to = "baz"
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ import (
|
|||||||
"golang.org/x/tools/go/analysis/analysistest"
|
"golang.org/x/tools/go/analysis/analysistest"
|
||||||
"golang.org/x/tools/go/analysis/internal/facts"
|
"golang.org/x/tools/go/analysis/internal/facts"
|
||||||
"golang.org/x/tools/go/packages"
|
"golang.org/x/tools/go/packages"
|
||||||
|
"golang.org/x/tools/internal/testenv"
|
||||||
)
|
)
|
||||||
|
|
||||||
type myFact struct {
|
type myFact struct {
|
||||||
@ -88,7 +89,7 @@ func TestEncodeDecode(t *testing.T) {
|
|||||||
}},
|
}},
|
||||||
} {
|
} {
|
||||||
// load package
|
// load package
|
||||||
pkg, err := load(dir, test.path)
|
pkg, err := load(t, dir, test.path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -155,12 +156,13 @@ func find(p *types.Package, expr string) types.Object {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func load(dir string, path string) (*types.Package, error) {
|
func load(t *testing.T, dir string, path string) (*types.Package, error) {
|
||||||
cfg := &packages.Config{
|
cfg := &packages.Config{
|
||||||
Mode: packages.LoadSyntax,
|
Mode: packages.LoadSyntax,
|
||||||
Dir: dir,
|
Dir: dir,
|
||||||
Env: append(os.Environ(), "GOPATH="+dir, "GO111MODULE=off", "GOPROXY=off"),
|
Env: append(os.Environ(), "GOPATH="+dir, "GO111MODULE=off", "GOPROXY=off"),
|
||||||
}
|
}
|
||||||
|
testenv.NeedsGoPackagesEnv(t, cfg.Env)
|
||||||
pkgs, err := packages.Load(cfg, path)
|
pkgs, err := packages.Load(cfg, path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -191,7 +193,7 @@ func TestFactFilter(t *testing.T) {
|
|||||||
}
|
}
|
||||||
defer cleanup()
|
defer cleanup()
|
||||||
|
|
||||||
pkg, err := load(dir, "a")
|
pkg, err := load(t, dir, "a")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import (
|
|||||||
"golang.org/x/tools/go/analysis"
|
"golang.org/x/tools/go/analysis"
|
||||||
"golang.org/x/tools/go/analysis/multichecker"
|
"golang.org/x/tools/go/analysis/multichecker"
|
||||||
"golang.org/x/tools/go/analysis/passes/findcall"
|
"golang.org/x/tools/go/analysis/passes/findcall"
|
||||||
|
"golang.org/x/tools/internal/testenv"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@ -46,6 +47,8 @@ func TestExitCode(t *testing.T) {
|
|||||||
panic("unreachable")
|
panic("unreachable")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testenv.NeedsTool(t, "go")
|
||||||
|
|
||||||
for _, test := range []struct {
|
for _, test := range []struct {
|
||||||
args []string
|
args []string
|
||||||
want int
|
want int
|
||||||
|
@ -19,6 +19,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"golang.org/x/tools/internal/testenv"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@ -52,6 +54,7 @@ func HasGoBuild() bool {
|
|||||||
// and then run them with os.StartProcess or exec.Command.
|
// and then run them with os.StartProcess or exec.Command.
|
||||||
// If not, MustHaveGoBuild calls t.Skip with an explanation.
|
// If not, MustHaveGoBuild calls t.Skip with an explanation.
|
||||||
func MustHaveGoBuild(t *testing.T) {
|
func MustHaveGoBuild(t *testing.T) {
|
||||||
|
testenv.NeedsTool(t, "go")
|
||||||
if !HasGoBuild() {
|
if !HasGoBuild() {
|
||||||
t.Skipf("skipping test: 'go build' not available on %s/%s", runtime.GOOS, runtime.GOARCH)
|
t.Skipf("skipping test: 'go build' not available on %s/%s", runtime.GOOS, runtime.GOARCH)
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ import (
|
|||||||
|
|
||||||
"golang.org/x/tools/go/buildutil"
|
"golang.org/x/tools/go/buildutil"
|
||||||
"golang.org/x/tools/go/loader"
|
"golang.org/x/tools/go/loader"
|
||||||
|
"golang.org/x/tools/internal/testenv"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestStdlib(t *testing.T) {
|
func TestStdlib(t *testing.T) {
|
||||||
@ -33,6 +34,7 @@ func TestStdlib(t *testing.T) {
|
|||||||
if testing.Short() {
|
if testing.Short() {
|
||||||
t.Skip("skipping in short mode; uses tons of memory (https://golang.org/issue/14113)")
|
t.Skip("skipping in short mode; uses tons of memory (https://golang.org/issue/14113)")
|
||||||
}
|
}
|
||||||
|
testenv.NeedsTool(t, "go")
|
||||||
|
|
||||||
runtime.GC()
|
runtime.GC()
|
||||||
t0 := time.Now()
|
t0 := time.Now()
|
||||||
@ -134,6 +136,8 @@ func TestCgoOption(t *testing.T) {
|
|||||||
if !build.Default.CgoEnabled {
|
if !build.Default.CgoEnabled {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
testenv.NeedsTool(t, "go")
|
||||||
|
|
||||||
// Test that we can load cgo-using packages with
|
// Test that we can load cgo-using packages with
|
||||||
// CGO_ENABLED=[01], which causes go/build to select pure
|
// CGO_ENABLED=[01], which causes go/build to select pure
|
||||||
// Go/native implementations, respectively, based on build
|
// Go/native implementations, respectively, based on build
|
||||||
|
@ -24,6 +24,7 @@ import (
|
|||||||
|
|
||||||
"golang.org/x/tools/go/packages"
|
"golang.org/x/tools/go/packages"
|
||||||
"golang.org/x/tools/go/packages/packagestest"
|
"golang.org/x/tools/go/packages/packagestest"
|
||||||
|
"golang.org/x/tools/internal/testenv"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
@ -55,6 +56,8 @@ func TestMain(m *testing.M) {
|
|||||||
|
|
||||||
// The zero-value of Config has LoadFiles mode.
|
// The zero-value of Config has LoadFiles mode.
|
||||||
func TestLoadZeroConfig(t *testing.T) {
|
func TestLoadZeroConfig(t *testing.T) {
|
||||||
|
testenv.NeedsGoPackages(t)
|
||||||
|
|
||||||
initial, err := packages.Load(nil, "hash")
|
initial, err := packages.Load(nil, "hash")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@ -1020,6 +1023,8 @@ func testNewPackagesInOverlay(t *testing.T, exporter packagestest.Exporter) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestAdHocOverlays(t *testing.T) {
|
func TestAdHocOverlays(t *testing.T) {
|
||||||
|
testenv.NeedsTool(t, "go")
|
||||||
|
|
||||||
// This test doesn't use packagestest because we are testing ad-hoc packages,
|
// This test doesn't use packagestest because we are testing ad-hoc packages,
|
||||||
// which are outside of $GOPATH and outside of a module.
|
// which are outside of $GOPATH and outside of a module.
|
||||||
tmp, err := ioutil.TempDir("", "a")
|
tmp, err := ioutil.TempDir("", "a")
|
||||||
@ -1063,6 +1068,8 @@ const A = 1
|
|||||||
// TestOverlayModFileChanges tests the behavior resulting from having files from
|
// TestOverlayModFileChanges tests the behavior resulting from having files from
|
||||||
// multiple modules in overlays.
|
// multiple modules in overlays.
|
||||||
func TestOverlayModFileChanges(t *testing.T) {
|
func TestOverlayModFileChanges(t *testing.T) {
|
||||||
|
testenv.NeedsTool(t, "go")
|
||||||
|
|
||||||
// Create two unrelated modules in a temporary directory.
|
// Create two unrelated modules in a temporary directory.
|
||||||
tmp, err := ioutil.TempDir("", "tmp")
|
tmp, err := ioutil.TempDir("", "tmp")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -12,6 +12,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"golang.org/x/tools/go/packages"
|
"golang.org/x/tools/go/packages"
|
||||||
|
"golang.org/x/tools/internal/testenv"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestLoadImportsC(t *testing.T) {
|
func TestLoadImportsC(t *testing.T) {
|
||||||
@ -28,6 +29,7 @@ func TestLoadImportsC(t *testing.T) {
|
|||||||
// See https://golang.org/issue/27100.
|
// See https://golang.org/issue/27100.
|
||||||
t.Skip(`skipping on plan9; for some reason "net [syscall.test]" is not loaded`)
|
t.Skip(`skipping on plan9; for some reason "net [syscall.test]" is not loaded`)
|
||||||
}
|
}
|
||||||
|
testenv.NeedsGoPackages(t)
|
||||||
|
|
||||||
cfg := &packages.Config{
|
cfg := &packages.Config{
|
||||||
Mode: packages.LoadImports,
|
Mode: packages.LoadImports,
|
||||||
|
@ -25,6 +25,7 @@ import (
|
|||||||
"golang.org/x/tools/go/expect"
|
"golang.org/x/tools/go/expect"
|
||||||
"golang.org/x/tools/go/packages"
|
"golang.org/x/tools/go/packages"
|
||||||
"golang.org/x/tools/internal/span"
|
"golang.org/x/tools/internal/span"
|
||||||
|
"golang.org/x/tools/internal/testenv"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -127,6 +128,10 @@ func BenchmarkAll(b *testing.B, f func(*testing.B, Exporter)) {
|
|||||||
// debugging tests.
|
// debugging tests.
|
||||||
func Export(t testing.TB, exporter Exporter, modules []Module) *Exported {
|
func Export(t testing.TB, exporter Exporter, modules []Module) *Exported {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
if exporter == Modules {
|
||||||
|
testenv.NeedsTool(t, "go")
|
||||||
|
}
|
||||||
|
|
||||||
dirname := strings.Replace(t.Name(), "/", "_", -1)
|
dirname := strings.Replace(t.Name(), "/", "_", -1)
|
||||||
dirname = strings.Replace(dirname, "#", "_", -1) // duplicate subtests get a #NNN suffix.
|
dirname = strings.Replace(dirname, "#", "_", -1) // duplicate subtests get a #NNN suffix.
|
||||||
temp, err := ioutil.TempDir("", dirname)
|
temp, err := ioutil.TempDir("", dirname)
|
||||||
@ -185,6 +190,7 @@ func Export(t testing.TB, exporter Exporter, modules []Module) *Exported {
|
|||||||
if err := exporter.Finalize(exported); err != nil {
|
if err := exporter.Finalize(exported); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
testenv.NeedsGoPackagesEnv(t, exported.Config.Env)
|
||||||
return exported
|
return exported
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"golang.org/x/tools/go/packages"
|
"golang.org/x/tools/go/packages"
|
||||||
|
"golang.org/x/tools/internal/testenv"
|
||||||
)
|
)
|
||||||
|
|
||||||
// This test loads the metadata for the standard library,
|
// This test loads the metadata for the standard library,
|
||||||
@ -23,6 +24,8 @@ func TestStdlibMetadata(t *testing.T) {
|
|||||||
// t.Skipf("incomplete std lib on %s", runtime.GOOS)
|
// t.Skipf("incomplete std lib on %s", runtime.GOOS)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
testenv.NeedsGoPackages(t)
|
||||||
|
|
||||||
runtime.GC()
|
runtime.GC()
|
||||||
t0 := time.Now()
|
t0 := time.Now()
|
||||||
var memstats runtime.MemStats
|
var memstats runtime.MemStats
|
||||||
@ -62,6 +65,8 @@ func TestCgoOption(t *testing.T) {
|
|||||||
t.Skip("skipping in short mode; uses tons of memory (https://golang.org/issue/14113)")
|
t.Skip("skipping in short mode; uses tons of memory (https://golang.org/issue/14113)")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testenv.NeedsGoPackages(t)
|
||||||
|
|
||||||
// TODO(adonovan): see if we can get away without these old
|
// TODO(adonovan): see if we can get away without these old
|
||||||
// go/loader hacks now that we use the go list command.
|
// go/loader hacks now that we use the go list command.
|
||||||
//
|
//
|
||||||
|
@ -17,6 +17,7 @@ import (
|
|||||||
|
|
||||||
"golang.org/x/tools/go/packages"
|
"golang.org/x/tools/go/packages"
|
||||||
"golang.org/x/tools/go/ssa/ssautil"
|
"golang.org/x/tools/go/ssa/ssautil"
|
||||||
|
"golang.org/x/tools/internal/testenv"
|
||||||
)
|
)
|
||||||
|
|
||||||
const hello = `package main
|
const hello = `package main
|
||||||
@ -53,6 +54,8 @@ func TestBuildPackage(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestPackages(t *testing.T) {
|
func TestPackages(t *testing.T) {
|
||||||
|
testenv.NeedsGoPackages(t)
|
||||||
|
|
||||||
cfg := &packages.Config{Mode: packages.LoadSyntax}
|
cfg := &packages.Config{Mode: packages.LoadSyntax}
|
||||||
initial, err := packages.Load(cfg, "bytes")
|
initial, err := packages.Load(cfg, "bytes")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -106,6 +109,8 @@ func TestBuildPackage_MissingImport(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestIssue28106(t *testing.T) {
|
func TestIssue28106(t *testing.T) {
|
||||||
|
testenv.NeedsGoPackages(t)
|
||||||
|
|
||||||
// In go1.10, go/packages loads all packages from source, not
|
// In go1.10, go/packages loads all packages from source, not
|
||||||
// export data, but does not type check function bodies of
|
// export data, but does not type check function bodies of
|
||||||
// imported packages. This test ensures that we do not attempt
|
// imported packages. This test ensures that we do not attempt
|
||||||
|
@ -25,6 +25,7 @@ import (
|
|||||||
"golang.org/x/tools/go/loader"
|
"golang.org/x/tools/go/loader"
|
||||||
"golang.org/x/tools/go/ssa"
|
"golang.org/x/tools/go/ssa"
|
||||||
"golang.org/x/tools/go/ssa/ssautil"
|
"golang.org/x/tools/go/ssa/ssautil"
|
||||||
|
"golang.org/x/tools/internal/testenv"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Skip the set of packages that transitively depend on
|
// Skip the set of packages that transitively depend on
|
||||||
@ -50,6 +51,8 @@ func TestStdlib(t *testing.T) {
|
|||||||
if testing.Short() {
|
if testing.Short() {
|
||||||
t.Skip("skipping in short mode; too slow (https://golang.org/issue/14113)")
|
t.Skip("skipping in short mode; too slow (https://golang.org/issue/14113)")
|
||||||
}
|
}
|
||||||
|
testenv.NeedsTool(t, "go")
|
||||||
|
|
||||||
// Load, parse and type-check the program.
|
// Load, parse and type-check the program.
|
||||||
t0 := time.Now()
|
t0 := time.Now()
|
||||||
alloc0 := bytesAllocated()
|
alloc0 := bytesAllocated()
|
||||||
|
@ -13,6 +13,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"golang.org/x/tools/go/packages"
|
"golang.org/x/tools/go/packages"
|
||||||
|
"golang.org/x/tools/internal/testenv"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestChanges(t *testing.T) {
|
func TestChanges(t *testing.T) {
|
||||||
@ -26,11 +27,11 @@ func TestChanges(t *testing.T) {
|
|||||||
sort.Strings(wanti)
|
sort.Strings(wanti)
|
||||||
sort.Strings(wantc)
|
sort.Strings(wantc)
|
||||||
|
|
||||||
oldpkg, err := load("apidiff/old", dir)
|
oldpkg, err := load(t, "apidiff/old", dir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
newpkg, err := load("apidiff/new", dir)
|
newpkg, err := load(t, "apidiff/new", dir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -115,7 +116,9 @@ func splitIntoPackages(t *testing.T, dir string) (incompatibles, compatibles []s
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func load(importPath, goPath string) (*packages.Package, error) {
|
func load(t *testing.T, importPath, goPath string) (*packages.Package, error) {
|
||||||
|
testenv.NeedsGoPackages(t)
|
||||||
|
|
||||||
cfg := &packages.Config{
|
cfg := &packages.Config{
|
||||||
Mode: packages.LoadTypes,
|
Mode: packages.LoadTypes,
|
||||||
}
|
}
|
||||||
@ -134,7 +137,7 @@ func load(importPath, goPath string) (*packages.Package, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestExportedFields(t *testing.T) {
|
func TestExportedFields(t *testing.T) {
|
||||||
pkg, err := load("golang.org/x/tools/internal/apidiff/testdata/exported_fields", "")
|
pkg, err := load(t, "golang.org/x/tools/internal/apidiff/testdata/exported_fields", "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"golang.org/x/tools/internal/module"
|
"golang.org/x/tools/internal/module"
|
||||||
|
"golang.org/x/tools/internal/testenv"
|
||||||
"golang.org/x/tools/internal/txtar"
|
"golang.org/x/tools/internal/txtar"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -578,6 +579,8 @@ type modTest struct {
|
|||||||
// in testdata/mod, along the lines of TestScript in cmd/go.
|
// in testdata/mod, along the lines of TestScript in cmd/go.
|
||||||
func setup(t *testing.T, main, wd string) *modTest {
|
func setup(t *testing.T, main, wd string) *modTest {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
testenv.NeedsTool(t, "go")
|
||||||
|
|
||||||
proxyOnce.Do(func() {
|
proxyOnce.Do(func() {
|
||||||
var err error
|
var err error
|
||||||
proxyDir, err = ioutil.TempDir("", "proxy-")
|
proxyDir, err = ioutil.TempDir("", "proxy-")
|
||||||
|
108
internal/testenv/testenv.go
Normal file
108
internal/testenv/testenv.go
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
// Copyright 2019 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package testenv contains helper functions for skipping tests
|
||||||
|
// based on which tools are present in the environment.
|
||||||
|
package testenv
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Testing is an abstraction of a *testing.T.
|
||||||
|
type Testing interface {
|
||||||
|
Skipf(format string, args ...interface{})
|
||||||
|
Fatalf(format string, args ...interface{})
|
||||||
|
}
|
||||||
|
|
||||||
|
type helperer interface {
|
||||||
|
Helper()
|
||||||
|
}
|
||||||
|
|
||||||
|
// packageMainIsDevel reports whether the module containing package main
|
||||||
|
// is a development version (if module information is available).
|
||||||
|
//
|
||||||
|
// Builds in GOPATH mode and builds that lack module information are assumed to
|
||||||
|
// be development versions.
|
||||||
|
var packageMainIsDevel = func() bool { return true }
|
||||||
|
|
||||||
|
func allowMissingTool(tool string) bool {
|
||||||
|
if runtime.GOOS == "android" {
|
||||||
|
// Android builds generally run tests on a separate machine from the build,
|
||||||
|
// so don't expect any external tools to be available.
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if tool == "go" && os.Getenv("GO_BUILDER_NAME") == "illumos-amd64-joyent" {
|
||||||
|
// Work around a misconfigured builder (see https://golang.org/issue/33950).
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// If a developer is actively working on this test, we expect them to have all
|
||||||
|
// of its dependencies installed. However, if it's just a dependency of some
|
||||||
|
// other module (for example, being run via 'go test all'), we should be more
|
||||||
|
// tolerant of unusual environments.
|
||||||
|
return !packageMainIsDevel()
|
||||||
|
}
|
||||||
|
|
||||||
|
// NeedsTool skips t if the named tool is not present in the path.
|
||||||
|
func NeedsTool(t Testing, tool string) {
|
||||||
|
_, err := exec.LookPath(tool)
|
||||||
|
if err == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if t, ok := t.(helperer); ok {
|
||||||
|
t.Helper()
|
||||||
|
}
|
||||||
|
if allowMissingTool(tool) {
|
||||||
|
t.Skipf("skipping because %s tool not available: %v", tool, err)
|
||||||
|
} else {
|
||||||
|
t.Fatalf("%s tool not available: %v", tool, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NeedsGoPackages skips t if the go/packages driver (or 'go' tool) implied by
|
||||||
|
// the current process environment is not present in the path.
|
||||||
|
func NeedsGoPackages(t Testing) {
|
||||||
|
if t, ok := t.(helperer); ok {
|
||||||
|
t.Helper()
|
||||||
|
}
|
||||||
|
|
||||||
|
tool := os.Getenv("GOPACKAGESDRIVER")
|
||||||
|
if tool == "" {
|
||||||
|
if _, err := exec.LookPath("gopackagesdriver"); err == nil {
|
||||||
|
tool = "gopackagesdriver"
|
||||||
|
} else {
|
||||||
|
tool = "go"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NeedsTool(t, tool)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NeedsGoPackagesEnv skips t if the go/packages driver (or 'go' tool) implied
|
||||||
|
// by env is not present in the path.
|
||||||
|
func NeedsGoPackagesEnv(t Testing, env []string) {
|
||||||
|
if t, ok := t.(helperer); ok {
|
||||||
|
t.Helper()
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, v := range env {
|
||||||
|
if strings.HasPrefix(v, "GOPACKAGESDRIVER=") {
|
||||||
|
tool := strings.TrimPrefix(v, "GOPACKAGESDRIVER=")
|
||||||
|
if tool == "off" {
|
||||||
|
NeedsTool(t, "go")
|
||||||
|
} else {
|
||||||
|
NeedsTool(t, tool)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NeedsGoPackages(t)
|
||||||
|
}
|
27
internal/testenv/testenv_112.go
Normal file
27
internal/testenv/testenv_112.go
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// Copyright 2019 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build go1.12
|
||||||
|
|
||||||
|
package testenv
|
||||||
|
|
||||||
|
import "runtime/debug"
|
||||||
|
|
||||||
|
func packageMainIsDevelModule() bool {
|
||||||
|
info, ok := debug.ReadBuildInfo()
|
||||||
|
if !ok {
|
||||||
|
// Most test binaries currently lack build info, but this should become more
|
||||||
|
// permissive once https://golang.org/issue/33976 is fixed.
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: info.Main.Version describes the version of the module containing
|
||||||
|
// package main, not the version of “the main module”.
|
||||||
|
// See https://golang.org/issue/33975.
|
||||||
|
return info.Main.Version == "(devel)"
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
packageMainIsDevel = packageMainIsDevelModule
|
||||||
|
}
|
@ -23,6 +23,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"golang.org/x/tools/go/loader"
|
"golang.org/x/tools/go/loader"
|
||||||
|
"golang.org/x/tools/internal/testenv"
|
||||||
"golang.org/x/tools/refactor/eg"
|
"golang.org/x/tools/refactor/eg"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -38,6 +39,8 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func Test(t *testing.T) {
|
func Test(t *testing.T) {
|
||||||
|
testenv.NeedsTool(t, "go")
|
||||||
|
|
||||||
switch runtime.GOOS {
|
switch runtime.GOOS {
|
||||||
case "windows":
|
case "windows":
|
||||||
t.Skipf("skipping test on %q (no /usr/bin/diff)", runtime.GOOS)
|
t.Skipf("skipping test on %q (no /usr/bin/diff)", runtime.GOOS)
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
"go/build"
|
"go/build"
|
||||||
"go/token"
|
"go/token"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
"runtime"
|
"runtime"
|
||||||
@ -17,6 +18,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"golang.org/x/tools/go/buildutil"
|
"golang.org/x/tools/go/buildutil"
|
||||||
|
"golang.org/x/tools/internal/testenv"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO(adonovan): test reported source positions, somehow.
|
// TODO(adonovan): test reported source positions, somehow.
|
||||||
@ -1278,11 +1280,17 @@ func main() {
|
|||||||
|
|
||||||
func TestDiff(t *testing.T) {
|
func TestDiff(t *testing.T) {
|
||||||
switch runtime.GOOS {
|
switch runtime.GOOS {
|
||||||
case "windows", "android":
|
case "windows":
|
||||||
|
if os.Getenv("GO_BUILDER_NAME") != "" {
|
||||||
|
if _, err := exec.LookPath(DiffCmd); err != nil {
|
||||||
t.Skipf("diff tool non-existent for %s on builders", runtime.GOOS)
|
t.Skipf("diff tool non-existent for %s on builders", runtime.GOOS)
|
||||||
|
}
|
||||||
|
}
|
||||||
case "plan9":
|
case "plan9":
|
||||||
t.Skipf("plan9 diff tool doesn't support -u flag")
|
t.Skipf("plan9 diff tool doesn't support -u flag")
|
||||||
}
|
}
|
||||||
|
testenv.NeedsTool(t, DiffCmd)
|
||||||
|
testenv.NeedsTool(t, "go") // to locate golang.org/x/tools/refactor/rename
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
Diff = false
|
Diff = false
|
||||||
|
Loading…
x
Reference in New Issue
Block a user