@@ -39,44 +39,74 @@ type TestCover struct {
39
39
DeclVars func (* Package , ... string ) map [string ]* CoverVar
40
40
}
41
41
42
- // TestPackagesFor returns three packages:
42
+ // TestPackagesFor is like TestPackagesAndErrors but it returns
43
+ // an error if the test packages or their dependencies have errors.
44
+ // Only test packages without errors are returned.
45
+ func TestPackagesFor (p * Package , cover * TestCover ) (pmain , ptest , pxtest * Package , err error ) {
46
+ pmain , ptest , pxtest = TestPackagesAndErrors (p , cover )
47
+ for _ , p1 := range []* Package {ptest , pxtest , pmain } {
48
+ if p1 == nil {
49
+ // pxtest may be nil
50
+ continue
51
+ }
52
+ if p1 .Error != nil {
53
+ err = p1 .Error
54
+ break
55
+ }
56
+ if len (p1 .DepsErrors ) > 0 {
57
+ perr := p1 .DepsErrors [0 ]
58
+ perr .Pos = "" // show full import stack
59
+ err = perr
60
+ break
61
+ }
62
+ }
63
+ if pmain .Error != nil || len (pmain .DepsErrors ) > 0 {
64
+ pmain = nil
65
+ }
66
+ if ptest .Error != nil || len (ptest .DepsErrors ) > 0 {
67
+ ptest = nil
68
+ }
69
+ if pxtest != nil && (pxtest .Error != nil || len (pxtest .DepsErrors ) > 0 ) {
70
+ pxtest = nil
71
+ }
72
+ return pmain , ptest , pxtest , err
73
+ }
74
+
75
+ // TestPackagesAndErrors returns three packages:
76
+ // - pmain, the package main corresponding to the test binary (running tests in ptest and pxtest).
43
77
// - ptest, the package p compiled with added "package p" test files.
44
78
// - pxtest, the result of compiling any "package p_test" (external) test files.
45
- // - pmain, the package main corresponding to the test binary (running tests in ptest and pxtest).
46
79
//
47
80
// If the package has no "package p_test" test files, pxtest will be nil.
48
81
// If the non-test compilation of package p can be reused
49
82
// (for example, if there are no "package p" test files and
50
83
// package p need not be instrumented for coverage or any other reason),
51
84
// then the returned ptest == p.
52
85
//
86
+ // An error is returned if the testmain source cannot be completely generated
87
+ // (for example, due to a syntax error in a test file). No error will be
88
+ // returned for errors loading packages, but the Error or DepsError fields
89
+ // of the returned packages may be set.
90
+ //
53
91
// The caller is expected to have checked that len(p.TestGoFiles)+len(p.XTestGoFiles) > 0,
54
92
// or else there's no point in any of this.
55
- func TestPackagesFor (p * Package , cover * TestCover ) (pmain , ptest , pxtest * Package , err error ) {
93
+ func TestPackagesAndErrors (p * Package , cover * TestCover ) (pmain , ptest , pxtest * Package ) {
94
+ var ptestErr , pxtestErr * PackageError
56
95
var imports , ximports []* Package
57
96
var stk ImportStack
58
97
stk .Push (p .ImportPath + " (test)" )
59
98
rawTestImports := str .StringList (p .TestImports )
60
99
for i , path := range p .TestImports {
61
100
p1 := LoadImport (path , p .Dir , p , & stk , p .Internal .Build .TestImportPos [path ], ResolveImport )
62
- if p1 .Error != nil {
63
- return nil , nil , nil , p1 .Error
64
- }
65
- if len (p1 .DepsErrors ) > 0 {
66
- err := p1 .DepsErrors [0 ]
67
- err .Pos = "" // show full import stack
68
- return nil , nil , nil , err
69
- }
70
101
if str .Contains (p1 .Deps , p .ImportPath ) || p1 .ImportPath == p .ImportPath {
71
102
// Same error that loadPackage returns (via reusePackage) in pkg.go.
72
103
// Can't change that code, because that code is only for loading the
73
104
// non-test copy of a package.
74
- err : = & PackageError {
105
+ ptestErr = & PackageError {
75
106
ImportStack : testImportStack (stk [0 ], p1 , p .ImportPath ),
76
107
Err : "import cycle not allowed in test" ,
77
108
IsImportCycle : true ,
78
109
}
79
- return nil , nil , nil , err
80
110
}
81
111
p .TestImports [i ] = p1 .ImportPath
82
112
imports = append (imports , p1 )
@@ -87,14 +117,6 @@ func TestPackagesFor(p *Package, cover *TestCover) (pmain, ptest, pxtest *Packag
87
117
rawXTestImports := str .StringList (p .XTestImports )
88
118
for i , path := range p .XTestImports {
89
119
p1 := LoadImport (path , p .Dir , p , & stk , p .Internal .Build .XTestImportPos [path ], ResolveImport )
90
- if p1 .Error != nil {
91
- return nil , nil , nil , p1 .Error
92
- }
93
- if len (p1 .DepsErrors ) > 0 {
94
- err := p1 .DepsErrors [0 ]
95
- err .Pos = "" // show full import stack
96
- return nil , nil , nil , err
97
- }
98
120
if p1 .ImportPath == p .ImportPath {
99
121
pxtestNeedsPtest = true
100
122
} else {
@@ -108,6 +130,7 @@ func TestPackagesFor(p *Package, cover *TestCover) (pmain, ptest, pxtest *Packag
108
130
if len (p .TestGoFiles ) > 0 || p .Name == "main" || cover != nil && cover .Local {
109
131
ptest = new (Package )
110
132
* ptest = * p
133
+ ptest .Error = ptestErr
111
134
ptest .ForTest = p .ImportPath
112
135
ptest .GoFiles = nil
113
136
ptest .GoFiles = append (ptest .GoFiles , p .GoFiles ... )
@@ -140,6 +163,7 @@ func TestPackagesFor(p *Package, cover *TestCover) (pmain, ptest, pxtest *Packag
140
163
m [k ] = append (m [k ], v ... )
141
164
}
142
165
ptest .Internal .Build .ImportPos = m
166
+ ptest .collectDeps ()
143
167
} else {
144
168
ptest = p
145
169
}
@@ -155,6 +179,7 @@ func TestPackagesFor(p *Package, cover *TestCover) (pmain, ptest, pxtest *Packag
155
179
GoFiles : p .XTestGoFiles ,
156
180
Imports : p .XTestImports ,
157
181
ForTest : p .ImportPath ,
182
+ Error : pxtestErr ,
158
183
},
159
184
Internal : PackageInternal {
160
185
LocalPrefix : p .Internal .LocalPrefix ,
@@ -173,6 +198,7 @@ func TestPackagesFor(p *Package, cover *TestCover) (pmain, ptest, pxtest *Packag
173
198
if pxtestNeedsPtest {
174
199
pxtest .Internal .Imports = append (pxtest .Internal .Imports , ptest )
175
200
}
201
+ pxtest .collectDeps ()
176
202
}
177
203
178
204
// Build main package.
@@ -207,9 +233,6 @@ func TestPackagesFor(p *Package, cover *TestCover) (pmain, ptest, pxtest *Packag
207
233
pmain .Internal .Imports = append (pmain .Internal .Imports , ptest )
208
234
} else {
209
235
p1 := LoadImport (dep , "" , nil , & stk , nil , 0 )
210
- if p1 .Error != nil {
211
- return nil , nil , nil , p1 .Error
212
- }
213
236
pmain .Internal .Imports = append (pmain .Internal .Imports , p1 )
214
237
}
215
238
}
@@ -240,8 +263,8 @@ func TestPackagesFor(p *Package, cover *TestCover) (pmain, ptest, pxtest *Packag
240
263
// The list of imports is used by recompileForTest and by the loop
241
264
// afterward that gathers t.Cover information.
242
265
t , err := loadTestFuncs (ptest )
243
- if err != nil {
244
- return nil , nil , nil , err
266
+ if err != nil && pmain . Error == nil {
267
+ pmain . Error = & PackageError { Err : err . Error ()}
245
268
}
246
269
t .Cover = cover
247
270
if len (ptest .GoFiles )+ len (ptest .CgoFiles ) > 0 {
@@ -254,6 +277,7 @@ func TestPackagesFor(p *Package, cover *TestCover) (pmain, ptest, pxtest *Packag
254
277
pmain .Imports = append (pmain .Imports , pxtest .ImportPath )
255
278
t .ImportXtest = true
256
279
}
280
+ pmain .collectDeps ()
257
281
258
282
// Sort and dedup pmain.Imports.
259
283
// Only matters for go list -test output.
@@ -299,12 +323,14 @@ func TestPackagesFor(p *Package, cover *TestCover) (pmain, ptest, pxtest *Packag
299
323
}
300
324
301
325
data , err := formatTestmain (t )
302
- if err != nil {
303
- return nil , nil , nil , err
326
+ if err != nil && pmain .Error == nil {
327
+ pmain .Error = & PackageError {Err : err .Error ()}
328
+ }
329
+ if data != nil {
330
+ pmain .Internal .TestmainGo = & data
304
331
}
305
- pmain .Internal .TestmainGo = & data
306
332
307
- return pmain , ptest , pxtest , nil
333
+ return pmain , ptest , pxtest
308
334
}
309
335
310
336
func testImportStack (top string , p * Package , target string ) []string {
@@ -420,21 +446,24 @@ type coverInfo struct {
420
446
}
421
447
422
448
// loadTestFuncs returns the testFuncs describing the tests that will be run.
449
+ // The returned testFuncs is always non-nil, even if an error occurred while
450
+ // processing test files.
423
451
func loadTestFuncs (ptest * Package ) (* testFuncs , error ) {
424
452
t := & testFuncs {
425
453
Package : ptest ,
426
454
}
455
+ var err error
427
456
for _ , file := range ptest .TestGoFiles {
428
- if err := t .load (filepath .Join (ptest .Dir , file ), "_test" , & t .ImportTest , & t .NeedTest ); err ! = nil {
429
- return nil , err
457
+ if lerr := t .load (filepath .Join (ptest .Dir , file ), "_test" , & t .ImportTest , & t .NeedTest ); lerr != nil && err = = nil {
458
+ err = lerr
430
459
}
431
460
}
432
461
for _ , file := range ptest .XTestGoFiles {
433
- if err := t .load (filepath .Join (ptest .Dir , file ), "_xtest" , & t .ImportXtest , & t .NeedXtest ); err ! = nil {
434
- return nil , err
462
+ if lerr := t .load (filepath .Join (ptest .Dir , file ), "_xtest" , & t .ImportXtest , & t .NeedXtest ); lerr != nil && err = = nil {
463
+ err = lerr
435
464
}
436
465
}
437
- return t , nil
466
+ return t , err
438
467
}
439
468
440
469
// formatTestmain returns the content of the _testmain.go file for t.
0 commit comments