Skip to content

Commit ebd9693

Browse files
committed
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 <[email protected]>
1 parent c07ec39 commit ebd9693

File tree

1 file changed

+36
-26
lines changed

1 file changed

+36
-26
lines changed

src/cmd/vet/vet_test.go

+36-26
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ package main_test
1010

1111
import (
1212
"bytes"
13+
"flag"
14+
"fmt"
1315
"os"
1416
"os/exec"
1517
"path/filepath"
@@ -22,20 +24,47 @@ const (
2224
binary = "testvet.exe"
2325
)
2426

25-
func CanRun(t *testing.T) bool {
26-
// Plan 9 and Windows systems can't be guaranteed to have Perl and so can't run errchk.
27+
// We implement TestMain so remove the test binary when all is done.
28+
func TestMain(m *testing.M) {
29+
flag.Parse()
30+
result := m.Run()
31+
os.Remove(binary)
32+
os.Exit(result)
33+
}
34+
35+
func CanRun() bool {
2736
switch runtime.GOOS {
2837
case "plan9", "windows":
29-
t.Skip("skipping test; no Perl on %q", runtime.GOOS)
38+
// No Perl installed, can't run errcheck.
39+
return false
40+
case "nacl":
41+
// Minimal and problematic file system.
3042
return false
3143
}
3244
return true
3345
}
3446

47+
var (
48+
built = false // We have built the binary.
49+
failed = false // We have failed to build the binary, don't try again.
50+
)
51+
3552
func Build(t *testing.T) {
36-
// go build
53+
if built {
54+
return
55+
}
56+
if !CanRun() || failed {
57+
t.Skip("cannot run on this environment")
58+
return
59+
}
3760
cmd := exec.Command("go", "build", "-o", binary)
38-
run(cmd, t)
61+
output, err := cmd.CombinedOutput()
62+
if err != nil {
63+
failed = true
64+
fmt.Fprintf(os.Stderr, "%s\n", output)
65+
t.Fatal(err)
66+
}
67+
built = true
3968
}
4069

4170
func Vet(t *testing.T, files []string) {
@@ -58,11 +87,7 @@ func Vet(t *testing.T, files []string) {
5887
//
5988

6089
func TestVet(t *testing.T) {
61-
if !CanRun(t) {
62-
t.Skip("cannot run on this environment")
63-
}
6490
Build(t)
65-
defer os.Remove(binary)
6691

6792
// errchk ./testvet
6893
gos, err := filepath.Glob(filepath.Join(dataDir, "*.go"))
@@ -78,23 +103,13 @@ func TestVet(t *testing.T) {
78103
}
79104

80105
func TestDivergentPackagesExamples(t *testing.T) {
81-
if !CanRun(t) {
82-
t.Skip("cannot run on this environment")
83-
}
84106
Build(t)
85-
defer os.Remove(binary)
86-
87107
// errchk ./testvet
88108
Vet(t, []string{"testdata/divergent/buf.go", "testdata/divergent/buf_test.go"})
89109
}
90110

91111
func TestIncompleteExamples(t *testing.T) {
92-
if !CanRun(t) {
93-
t.Skip("cannot run on this environment")
94-
}
95112
Build(t)
96-
defer os.Remove(binary)
97-
98113
// errchk ./testvet
99114
Vet(t, []string{"testdata/incomplete/examples_test.go"})
100115
}
@@ -115,18 +130,13 @@ func run(c *exec.Cmd, t *testing.T) bool {
115130

116131
// TestTags verifies that the -tags argument controls which files to check.
117132
func TestTags(t *testing.T) {
118-
// go build
119-
cmd := exec.Command("go", "build", "-o", binary)
120-
run(cmd, t)
121-
122-
defer os.Remove(binary)
123-
133+
Build(t)
124134
args := []string{
125135
"-tags=testtag",
126136
"-v", // We're going to look at the files it examines.
127137
"testdata/tagtest",
128138
}
129-
cmd = exec.Command("./"+binary, args...)
139+
cmd := exec.Command("./"+binary, args...)
130140
output, err := cmd.CombinedOutput()
131141
if err != nil {
132142
t.Fatal(err)

0 commit comments

Comments
 (0)