@@ -13,6 +13,7 @@ import (
13
13
"os/exec"
14
14
"path/filepath"
15
15
"runtime"
16
+ "sync"
16
17
"testing"
17
18
)
18
19
@@ -40,19 +41,22 @@ func MustHavePerl(t *testing.T) {
40
41
}
41
42
42
43
var (
43
- built = false // We have built the binary.
44
- failed = false // We have failed to build the binary, don't try again.
44
+ buildMu sync.Mutex // guards following
45
+ built = false // We have built the binary.
46
+ failed = false // We have failed to build the binary, don't try again.
45
47
)
46
48
47
49
func Build (t * testing.T ) {
48
- testenv . MustHaveGoBuild ( t )
49
- MustHavePerl ( t )
50
+ buildMu . Lock ( )
51
+ defer buildMu . Unlock ( )
50
52
if built {
51
53
return
52
54
}
53
55
if failed {
54
56
t .Skip ("cannot run on this environment" )
55
57
}
58
+ testenv .MustHaveGoBuild (t )
59
+ MustHavePerl (t )
56
60
cmd := exec .Command (testenv .GoToolPath (t ), "build" , "-o" , binary )
57
61
output , err := cmd .CombinedOutput ()
58
62
if err != nil {
@@ -83,69 +87,122 @@ func Vet(t *testing.T, files []string) {
83
87
// rm testvet
84
88
//
85
89
90
+ // TestVet tests self-contained files in testdata/*.go.
91
+ //
92
+ // If a file contains assembly or has inter-dependencies, it should be
93
+ // in its own test, like TestVetAsm, TestDivergentPackagesExamples,
94
+ // etc below.
86
95
func TestVet (t * testing.T ) {
87
96
Build (t )
97
+ t .Parallel ()
88
98
89
99
// errchk ./testvet
90
100
gos , err := filepath .Glob (filepath .Join (dataDir , "*.go" ))
91
101
if err != nil {
92
102
t .Fatal (err )
93
103
}
94
- asms , err := filepath .Glob (filepath .Join (dataDir , "*.s" ))
95
- if err != nil {
96
- t .Fatal (err )
104
+ wide := runtime .GOMAXPROCS (0 )
105
+ if wide > len (gos ) {
106
+ wide = len (gos )
107
+ }
108
+ batch := make ([][]string , wide )
109
+ for i , file := range gos {
110
+ batch [i % wide ] = append (batch [i % wide ], file )
111
+ }
112
+ for i , files := range batch {
113
+ files := files
114
+ t .Run (fmt .Sprint (i ), func (t * testing.T ) {
115
+ t .Parallel ()
116
+ t .Logf ("files: %q" , files )
117
+ Vet (t , files )
118
+ })
97
119
}
98
- files := append (gos , asms ... )
99
- Vet (t , files )
100
120
}
101
121
102
- func TestDivergentPackagesExamples (t * testing.T ) {
122
+ func TestVetAsm (t * testing.T ) {
103
123
Build (t )
124
+
125
+ asmDir := filepath .Join (dataDir , "asm" )
126
+ gos , err := filepath .Glob (filepath .Join (asmDir , "*.go" ))
127
+ if err != nil {
128
+ t .Fatal (err )
129
+ }
130
+ asms , err := filepath .Glob (filepath .Join (asmDir , "*.s" ))
131
+ if err != nil {
132
+ t .Fatal (err )
133
+ }
134
+
135
+ t .Parallel ()
104
136
// errchk ./testvet
105
- Vet (t , [] string { "testdata/divergent" } )
137
+ Vet (t , append ( gos , asms ... ) )
106
138
}
107
139
108
- func TestIncompleteExamples (t * testing.T ) {
140
+ func TestVetDirs (t * testing.T ) {
141
+ t .Parallel ()
109
142
Build (t )
110
- // errchk ./testvet
111
- Vet (t , []string {"testdata/incomplete/examples_test.go" })
143
+ for _ , dir := range []string {
144
+ "testingpkg" ,
145
+ "divergent" ,
146
+ "buildtag" ,
147
+ "incomplete" , // incomplete examples
148
+ } {
149
+ dir := dir
150
+ t .Run (dir , func (t * testing.T ) {
151
+ t .Parallel ()
152
+ gos , err := filepath .Glob (filepath .Join ("testdata" , dir , "*.go" ))
153
+ if err != nil {
154
+ t .Fatal (err )
155
+ }
156
+ Vet (t , gos )
157
+ })
158
+ }
112
159
}
113
160
114
161
func run (c * exec.Cmd , t * testing.T ) bool {
115
162
output , err := c .CombinedOutput ()
116
- os .Stderr .Write (output )
117
163
if err != nil {
164
+ t .Logf ("vet output:\n %s" , output )
118
165
t .Fatal (err )
119
166
}
120
167
// Errchk delights by not returning non-zero status if it finds errors, so we look at the output.
121
168
// It prints "BUG" if there is a failure.
122
169
if ! c .ProcessState .Success () {
170
+ t .Logf ("vet output:\n %s" , output )
123
171
return false
124
172
}
125
- return ! bytes .Contains (output , []byte ("BUG" ))
173
+ ok := ! bytes .Contains (output , []byte ("BUG" ))
174
+ if ! ok {
175
+ t .Logf ("vet output:\n %s" , output )
176
+ }
177
+ return ok
126
178
}
127
179
128
180
// TestTags verifies that the -tags argument controls which files to check.
129
181
func TestTags (t * testing.T ) {
182
+ t .Parallel ()
130
183
Build (t )
131
184
for _ , tag := range []string {"testtag" , "x testtag y" , "x,testtag,y" } {
132
- t .Logf ("-tags=%s" , tag )
133
- args := []string {
134
- "-tags=" + tag ,
135
- "-v" , // We're going to look at the files it examines.
136
- "testdata/tagtest" ,
137
- }
138
- cmd := exec .Command ("./" + binary , args ... )
139
- output , err := cmd .CombinedOutput ()
140
- if err != nil {
141
- t .Fatal (err )
142
- }
143
- // file1 has testtag and file2 has !testtag.
144
- if ! bytes .Contains (output , []byte (filepath .Join ("tagtest" , "file1.go" ))) {
145
- t .Error ("file1 was excluded, should be included" )
146
- }
147
- if bytes .Contains (output , []byte (filepath .Join ("tagtest" , "file2.go" ))) {
148
- t .Error ("file2 was included, should be excluded" )
149
- }
185
+ tag := tag
186
+ t .Run (tag , func (t * testing.T ) {
187
+ t .Parallel ()
188
+ t .Logf ("-tags=%s" , tag )
189
+ args := []string {
190
+ "-tags=" + tag ,
191
+ "-v" , // We're going to look at the files it examines.
192
+ "testdata/tagtest" ,
193
+ }
194
+ cmd := exec .Command ("./" + binary , args ... )
195
+ output , err := cmd .CombinedOutput ()
196
+ if err != nil {
197
+ t .Fatal (err )
198
+ }
199
+ // file1 has testtag and file2 has !testtag.
200
+ if ! bytes .Contains (output , []byte (filepath .Join ("tagtest" , "file1.go" ))) {
201
+ t .Error ("file1 was excluded, should be included" )
202
+ }
203
+ if bytes .Contains (output , []byte (filepath .Join ("tagtest" , "file2.go" ))) {
204
+ t .Error ("file2 was included, should be excluded" )
205
+ }
206
+ })
150
207
}
151
208
}
0 commit comments