1
0
mirror of https://github.com/golang/go synced 2024-11-05 17:06:13 -07:00

cmd/vet: build the binary only once in the test

Recent changes caused vet to build the binary for each Test function.
This is wasteful and will become only more so as more tests are added.
Use testing.Main to build only once.

Verified that compilation errors still appear if the binary cannot be
built.

Before:
	real	0m11.169s
	user	0m18.328s
	sys	0m2.152s

After:
	real	0m5.132s
	user	0m9.404s
	sys	0m1.168s

Of course if the compiler were fast we might not notice, but vet is
a big program and growing bigger all the time, as are the tests.

Change-Id: I209a8fdcace94bc5cec946f5dd365d7191f44c02
Reviewed-on: https://go-review.googlesource.com/14822
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
Rob Pike 2015-09-21 11:06:43 -07:00
parent c07ec392ac
commit ebd96933c1

View File

@ -10,6 +10,8 @@ package main_test
import ( import (
"bytes" "bytes"
"flag"
"fmt"
"os" "os"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
@ -22,20 +24,47 @@ const (
binary = "testvet.exe" binary = "testvet.exe"
) )
func CanRun(t *testing.T) bool { // We implement TestMain so remove the test binary when all is done.
// Plan 9 and Windows systems can't be guaranteed to have Perl and so can't run errchk. func TestMain(m *testing.M) {
flag.Parse()
result := m.Run()
os.Remove(binary)
os.Exit(result)
}
func CanRun() bool {
switch runtime.GOOS { switch runtime.GOOS {
case "plan9", "windows": case "plan9", "windows":
t.Skip("skipping test; no Perl on %q", runtime.GOOS) // No Perl installed, can't run errcheck.
return false
case "nacl":
// Minimal and problematic file system.
return false return false
} }
return true return true
} }
var (
built = false // We have built the binary.
failed = false // We have failed to build the binary, don't try again.
)
func Build(t *testing.T) { func Build(t *testing.T) {
// go build if built {
return
}
if !CanRun() || failed {
t.Skip("cannot run on this environment")
return
}
cmd := exec.Command("go", "build", "-o", binary) cmd := exec.Command("go", "build", "-o", binary)
run(cmd, t) output, err := cmd.CombinedOutput()
if err != nil {
failed = true
fmt.Fprintf(os.Stderr, "%s\n", output)
t.Fatal(err)
}
built = true
} }
func Vet(t *testing.T, files []string) { func Vet(t *testing.T, files []string) {
@ -58,11 +87,7 @@ func Vet(t *testing.T, files []string) {
// //
func TestVet(t *testing.T) { func TestVet(t *testing.T) {
if !CanRun(t) {
t.Skip("cannot run on this environment")
}
Build(t) Build(t)
defer os.Remove(binary)
// errchk ./testvet // errchk ./testvet
gos, err := filepath.Glob(filepath.Join(dataDir, "*.go")) gos, err := filepath.Glob(filepath.Join(dataDir, "*.go"))
@ -78,23 +103,13 @@ func TestVet(t *testing.T) {
} }
func TestDivergentPackagesExamples(t *testing.T) { func TestDivergentPackagesExamples(t *testing.T) {
if !CanRun(t) {
t.Skip("cannot run on this environment")
}
Build(t) Build(t)
defer os.Remove(binary)
// errchk ./testvet // errchk ./testvet
Vet(t, []string{"testdata/divergent/buf.go", "testdata/divergent/buf_test.go"}) Vet(t, []string{"testdata/divergent/buf.go", "testdata/divergent/buf_test.go"})
} }
func TestIncompleteExamples(t *testing.T) { func TestIncompleteExamples(t *testing.T) {
if !CanRun(t) {
t.Skip("cannot run on this environment")
}
Build(t) Build(t)
defer os.Remove(binary)
// errchk ./testvet // errchk ./testvet
Vet(t, []string{"testdata/incomplete/examples_test.go"}) Vet(t, []string{"testdata/incomplete/examples_test.go"})
} }
@ -115,18 +130,13 @@ func run(c *exec.Cmd, t *testing.T) bool {
// TestTags verifies that the -tags argument controls which files to check. // TestTags verifies that the -tags argument controls which files to check.
func TestTags(t *testing.T) { func TestTags(t *testing.T) {
// go build Build(t)
cmd := exec.Command("go", "build", "-o", binary)
run(cmd, t)
defer os.Remove(binary)
args := []string{ args := []string{
"-tags=testtag", "-tags=testtag",
"-v", // We're going to look at the files it examines. "-v", // We're going to look at the files it examines.
"testdata/tagtest", "testdata/tagtest",
} }
cmd = exec.Command("./"+binary, args...) cmd := exec.Command("./"+binary, args...)
output, err := cmd.CombinedOutput() output, err := cmd.CombinedOutput()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)