@@ -39,44 +39,74 @@ type TestCover struct {
3939 DeclVars func (* Package , ... string ) map [string ]* CoverVar
4040}
4141
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).
4377// - ptest, the package p compiled with added "package p" test files.
4478// - 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).
4679//
4780// If the package has no "package p_test" test files, pxtest will be nil.
4881// If the non-test compilation of package p can be reused
4982// (for example, if there are no "package p" test files and
5083// package p need not be instrumented for coverage or any other reason),
5184// then the returned ptest == p.
5285//
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+ //
5391// The caller is expected to have checked that len(p.TestGoFiles)+len(p.XTestGoFiles) > 0,
5492// 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
5695 var imports , ximports []* Package
5796 var stk ImportStack
5897 stk .Push (p .ImportPath + " (test)" )
5998 rawTestImports := str .StringList (p .TestImports )
6099 for i , path := range p .TestImports {
61100 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- }
70101 if str .Contains (p1 .Deps , p .ImportPath ) || p1 .ImportPath == p .ImportPath {
71102 // Same error that loadPackage returns (via reusePackage) in pkg.go.
72103 // Can't change that code, because that code is only for loading the
73104 // non-test copy of a package.
74- err : = & PackageError {
105+ ptestErr = & PackageError {
75106 ImportStack : testImportStack (stk [0 ], p1 , p .ImportPath ),
76107 Err : "import cycle not allowed in test" ,
77108 IsImportCycle : true ,
78109 }
79- return nil , nil , nil , err
80110 }
81111 p .TestImports [i ] = p1 .ImportPath
82112 imports = append (imports , p1 )
@@ -87,14 +117,6 @@ func TestPackagesFor(p *Package, cover *TestCover) (pmain, ptest, pxtest *Packag
87117 rawXTestImports := str .StringList (p .XTestImports )
88118 for i , path := range p .XTestImports {
89119 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- }
98120 if p1 .ImportPath == p .ImportPath {
99121 pxtestNeedsPtest = true
100122 } else {
@@ -108,6 +130,7 @@ func TestPackagesFor(p *Package, cover *TestCover) (pmain, ptest, pxtest *Packag
108130 if len (p .TestGoFiles ) > 0 || p .Name == "main" || cover != nil && cover .Local {
109131 ptest = new (Package )
110132 * ptest = * p
133+ ptest .Error = ptestErr
111134 ptest .ForTest = p .ImportPath
112135 ptest .GoFiles = nil
113136 ptest .GoFiles = append (ptest .GoFiles , p .GoFiles ... )
@@ -140,6 +163,7 @@ func TestPackagesFor(p *Package, cover *TestCover) (pmain, ptest, pxtest *Packag
140163 m [k ] = append (m [k ], v ... )
141164 }
142165 ptest .Internal .Build .ImportPos = m
166+ ptest .collectDeps ()
143167 } else {
144168 ptest = p
145169 }
@@ -155,6 +179,7 @@ func TestPackagesFor(p *Package, cover *TestCover) (pmain, ptest, pxtest *Packag
155179 GoFiles : p .XTestGoFiles ,
156180 Imports : p .XTestImports ,
157181 ForTest : p .ImportPath ,
182+ Error : pxtestErr ,
158183 },
159184 Internal : PackageInternal {
160185 LocalPrefix : p .Internal .LocalPrefix ,
@@ -173,6 +198,7 @@ func TestPackagesFor(p *Package, cover *TestCover) (pmain, ptest, pxtest *Packag
173198 if pxtestNeedsPtest {
174199 pxtest .Internal .Imports = append (pxtest .Internal .Imports , ptest )
175200 }
201+ pxtest .collectDeps ()
176202 }
177203
178204 // Build main package.
@@ -207,9 +233,6 @@ func TestPackagesFor(p *Package, cover *TestCover) (pmain, ptest, pxtest *Packag
207233 pmain .Internal .Imports = append (pmain .Internal .Imports , ptest )
208234 } else {
209235 p1 := LoadImport (dep , "" , nil , & stk , nil , 0 )
210- if p1 .Error != nil {
211- return nil , nil , nil , p1 .Error
212- }
213236 pmain .Internal .Imports = append (pmain .Internal .Imports , p1 )
214237 }
215238 }
@@ -240,8 +263,8 @@ func TestPackagesFor(p *Package, cover *TestCover) (pmain, ptest, pxtest *Packag
240263 // The list of imports is used by recompileForTest and by the loop
241264 // afterward that gathers t.Cover information.
242265 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 ()}
245268 }
246269 t .Cover = cover
247270 if len (ptest .GoFiles )+ len (ptest .CgoFiles ) > 0 {
@@ -254,6 +277,7 @@ func TestPackagesFor(p *Package, cover *TestCover) (pmain, ptest, pxtest *Packag
254277 pmain .Imports = append (pmain .Imports , pxtest .ImportPath )
255278 t .ImportXtest = true
256279 }
280+ pmain .collectDeps ()
257281
258282 // Sort and dedup pmain.Imports.
259283 // Only matters for go list -test output.
@@ -299,12 +323,14 @@ func TestPackagesFor(p *Package, cover *TestCover) (pmain, ptest, pxtest *Packag
299323 }
300324
301325 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
304331 }
305- pmain .Internal .TestmainGo = & data
306332
307- return pmain , ptest , pxtest , nil
333+ return pmain , ptest , pxtest
308334}
309335
310336func testImportStack (top string , p * Package , target string ) []string {
@@ -420,21 +446,24 @@ type coverInfo struct {
420446}
421447
422448// 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.
423451func loadTestFuncs (ptest * Package ) (* testFuncs , error ) {
424452 t := & testFuncs {
425453 Package : ptest ,
426454 }
455+ var err error
427456 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
430459 }
431460 }
432461 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
435464 }
436465 }
437- return t , nil
466+ return t , err
438467}
439468
440469// formatTestmain returns the content of the _testmain.go file for t.
0 commit comments