]> Cypherpunks.ru repositories - gostls13.git/blob - src/cmd/go/internal/load/test.go
[dev.fuzz] all: merge master (c95464f) into dev.fuzz
[gostls13.git] / src / cmd / go / internal / load / test.go
1 // Copyright 2018 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package load
6
7 import (
8         "bytes"
9         "context"
10         "errors"
11         "fmt"
12         "go/ast"
13         "go/build"
14         "go/doc"
15         "go/parser"
16         "go/token"
17         "internal/lazytemplate"
18         "path/filepath"
19         "sort"
20         "strings"
21         "unicode"
22         "unicode/utf8"
23
24         "cmd/go/internal/fsys"
25         "cmd/go/internal/str"
26         "cmd/go/internal/trace"
27 )
28
29 var TestMainDeps = []string{
30         // Dependencies for testmain.
31         "os",
32         "reflect",
33         "testing",
34         "testing/internal/testdeps",
35 }
36
37 type TestCover struct {
38         Mode     string
39         Local    bool
40         Pkgs     []*Package
41         Paths    []string
42         Vars     []coverInfo
43         DeclVars func(*Package, ...string) map[string]*CoverVar
44 }
45
46 // TestPackagesFor is like TestPackagesAndErrors but it returns
47 // an error if the test packages or their dependencies have errors.
48 // Only test packages without errors are returned.
49 func TestPackagesFor(ctx context.Context, opts PackageOpts, p *Package, cover *TestCover) (pmain, ptest, pxtest *Package, err error) {
50         pmain, ptest, pxtest = TestPackagesAndErrors(ctx, opts, p, cover)
51         for _, p1 := range []*Package{ptest, pxtest, pmain} {
52                 if p1 == nil {
53                         // pxtest may be nil
54                         continue
55                 }
56                 if p1.Error != nil {
57                         err = p1.Error
58                         break
59                 }
60                 if len(p1.DepsErrors) > 0 {
61                         perr := p1.DepsErrors[0]
62                         err = perr
63                         break
64                 }
65         }
66         if pmain.Error != nil || len(pmain.DepsErrors) > 0 {
67                 pmain = nil
68         }
69         if ptest.Error != nil || len(ptest.DepsErrors) > 0 {
70                 ptest = nil
71         }
72         if pxtest != nil && (pxtest.Error != nil || len(pxtest.DepsErrors) > 0) {
73                 pxtest = nil
74         }
75         return pmain, ptest, pxtest, err
76 }
77
78 // TestPackagesAndErrors returns three packages:
79 //      - pmain, the package main corresponding to the test binary (running tests in ptest and pxtest).
80 //      - ptest, the package p compiled with added "package p" test files.
81 //      - pxtest, the result of compiling any "package p_test" (external) test files.
82 //
83 // If the package has no "package p_test" test files, pxtest will be nil.
84 // If the non-test compilation of package p can be reused
85 // (for example, if there are no "package p" test files and
86 // package p need not be instrumented for coverage or any other reason),
87 // then the returned ptest == p.
88 //
89 // An error is returned if the testmain source cannot be completely generated
90 // (for example, due to a syntax error in a test file). No error will be
91 // returned for errors loading packages, but the Error or DepsError fields
92 // of the returned packages may be set.
93 //
94 // The caller is expected to have checked that len(p.TestGoFiles)+len(p.XTestGoFiles) > 0,
95 // or else there's no point in any of this.
96 func TestPackagesAndErrors(ctx context.Context, opts PackageOpts, p *Package, cover *TestCover) (pmain, ptest, pxtest *Package) {
97         ctx, span := trace.StartSpan(ctx, "load.TestPackagesAndErrors")
98         defer span.Done()
99
100         pre := newPreload()
101         defer pre.flush()
102         allImports := append([]string{}, p.TestImports...)
103         allImports = append(allImports, p.XTestImports...)
104         pre.preloadImports(ctx, opts, allImports, p.Internal.Build)
105
106         var ptestErr, pxtestErr *PackageError
107         var imports, ximports []*Package
108         var stk ImportStack
109         var testEmbed, xtestEmbed map[string][]string
110         stk.Push(p.ImportPath + " (test)")
111         rawTestImports := str.StringList(p.TestImports)
112         for i, path := range p.TestImports {
113                 p1 := loadImport(ctx, opts, pre, path, p.Dir, p, &stk, p.Internal.Build.TestImportPos[path], ResolveImport)
114                 if str.Contains(p1.Deps, p.ImportPath) || p1.ImportPath == p.ImportPath {
115                         // Same error that loadPackage returns (via reusePackage) in pkg.go.
116                         // Can't change that code, because that code is only for loading the
117                         // non-test copy of a package.
118                         ptestErr = &PackageError{
119                                 ImportStack:   importCycleStack(p1, p.ImportPath),
120                                 Err:           errors.New("import cycle not allowed in test"),
121                                 IsImportCycle: true,
122                         }
123                 }
124                 p.TestImports[i] = p1.ImportPath
125                 imports = append(imports, p1)
126         }
127         var err error
128         p.TestEmbedFiles, testEmbed, err = resolveEmbed(p.Dir, p.TestEmbedPatterns)
129         if err != nil && ptestErr == nil {
130                 ptestErr = &PackageError{
131                         ImportStack: stk.Copy(),
132                         Err:         err,
133                 }
134                 embedErr := err.(*EmbedError)
135                 ptestErr.setPos(p.Internal.Build.TestEmbedPatternPos[embedErr.Pattern])
136         }
137         stk.Pop()
138
139         stk.Push(p.ImportPath + "_test")
140         pxtestNeedsPtest := false
141         rawXTestImports := str.StringList(p.XTestImports)
142         for i, path := range p.XTestImports {
143                 p1 := loadImport(ctx, opts, pre, path, p.Dir, p, &stk, p.Internal.Build.XTestImportPos[path], ResolveImport)
144                 if p1.ImportPath == p.ImportPath {
145                         pxtestNeedsPtest = true
146                 } else {
147                         ximports = append(ximports, p1)
148                 }
149                 p.XTestImports[i] = p1.ImportPath
150         }
151         p.XTestEmbedFiles, xtestEmbed, err = resolveEmbed(p.Dir, p.XTestEmbedPatterns)
152         if err != nil && pxtestErr == nil {
153                 pxtestErr = &PackageError{
154                         ImportStack: stk.Copy(),
155                         Err:         err,
156                 }
157                 embedErr := err.(*EmbedError)
158                 pxtestErr.setPos(p.Internal.Build.XTestEmbedPatternPos[embedErr.Pattern])
159         }
160         stk.Pop()
161
162         // Test package.
163         if len(p.TestGoFiles) > 0 || p.Name == "main" || cover != nil && cover.Local {
164                 ptest = new(Package)
165                 *ptest = *p
166                 ptest.Error = ptestErr
167                 ptest.ForTest = p.ImportPath
168                 ptest.GoFiles = nil
169                 ptest.GoFiles = append(ptest.GoFiles, p.GoFiles...)
170                 ptest.GoFiles = append(ptest.GoFiles, p.TestGoFiles...)
171                 ptest.Target = ""
172                 // Note: The preparation of the vet config requires that common
173                 // indexes in ptest.Imports and ptest.Internal.RawImports
174                 // all line up (but RawImports can be shorter than the others).
175                 // That is, for 0 ≤ i < len(RawImports),
176                 // RawImports[i] is the import string in the program text, and
177                 // Imports[i] is the expanded import string (vendoring applied or relative path expanded away).
178                 // Any implicitly added imports appear in Imports and Internal.Imports
179                 // but not RawImports (because they were not in the source code).
180                 // We insert TestImports, imports, and rawTestImports at the start of
181                 // these lists to preserve the alignment.
182                 // Note that p.Internal.Imports may not be aligned with p.Imports/p.Internal.RawImports,
183                 // but we insert at the beginning there too just for consistency.
184                 ptest.Imports = str.StringList(p.TestImports, p.Imports)
185                 ptest.Internal.Imports = append(imports, p.Internal.Imports...)
186                 ptest.Internal.RawImports = str.StringList(rawTestImports, p.Internal.RawImports)
187                 ptest.Internal.ForceLibrary = true
188                 ptest.Internal.BuildInfo = ""
189                 ptest.Internal.Build = new(build.Package)
190                 *ptest.Internal.Build = *p.Internal.Build
191                 m := map[string][]token.Position{}
192                 for k, v := range p.Internal.Build.ImportPos {
193                         m[k] = append(m[k], v...)
194                 }
195                 for k, v := range p.Internal.Build.TestImportPos {
196                         m[k] = append(m[k], v...)
197                 }
198                 ptest.Internal.Build.ImportPos = m
199                 if testEmbed == nil && len(p.Internal.Embed) > 0 {
200                         testEmbed = map[string][]string{}
201                 }
202                 for k, v := range p.Internal.Embed {
203                         testEmbed[k] = v
204                 }
205                 ptest.Internal.Embed = testEmbed
206                 ptest.EmbedFiles = str.StringList(p.EmbedFiles, p.TestEmbedFiles)
207                 ptest.Internal.OrigImportPath = p.Internal.OrigImportPath
208                 ptest.collectDeps()
209         } else {
210                 ptest = p
211         }
212
213         // External test package.
214         if len(p.XTestGoFiles) > 0 {
215                 pxtest = &Package{
216                         PackagePublic: PackagePublic{
217                                 Name:       p.Name + "_test",
218                                 ImportPath: p.ImportPath + "_test",
219                                 Root:       p.Root,
220                                 Dir:        p.Dir,
221                                 Goroot:     p.Goroot,
222                                 GoFiles:    p.XTestGoFiles,
223                                 Imports:    p.XTestImports,
224                                 ForTest:    p.ImportPath,
225                                 Module:     p.Module,
226                                 Error:      pxtestErr,
227                                 EmbedFiles: p.XTestEmbedFiles,
228                         },
229                         Internal: PackageInternal{
230                                 LocalPrefix: p.Internal.LocalPrefix,
231                                 Build: &build.Package{
232                                         ImportPos: p.Internal.Build.XTestImportPos,
233                                 },
234                                 Imports:    ximports,
235                                 RawImports: rawXTestImports,
236
237                                 Asmflags:       p.Internal.Asmflags,
238                                 Gcflags:        p.Internal.Gcflags,
239                                 Ldflags:        p.Internal.Ldflags,
240                                 Gccgoflags:     p.Internal.Gccgoflags,
241                                 Embed:          xtestEmbed,
242                                 OrigImportPath: p.Internal.OrigImportPath,
243                         },
244                 }
245                 if pxtestNeedsPtest {
246                         pxtest.Internal.Imports = append(pxtest.Internal.Imports, ptest)
247                 }
248                 pxtest.collectDeps()
249         }
250
251         // Build main package.
252         pmain = &Package{
253                 PackagePublic: PackagePublic{
254                         Name:       "main",
255                         Dir:        p.Dir,
256                         GoFiles:    []string{"_testmain.go"},
257                         ImportPath: p.ImportPath + ".test",
258                         Root:       p.Root,
259                         Imports:    str.StringList(TestMainDeps),
260                         Module:     p.Module,
261                 },
262                 Internal: PackageInternal{
263                         Build:          &build.Package{Name: "main"},
264                         BuildInfo:      p.Internal.BuildInfo,
265                         Asmflags:       p.Internal.Asmflags,
266                         Gcflags:        p.Internal.Gcflags,
267                         Ldflags:        p.Internal.Ldflags,
268                         Gccgoflags:     p.Internal.Gccgoflags,
269                         OrigImportPath: p.Internal.OrigImportPath,
270                 },
271         }
272
273         // The generated main also imports testing, regexp, and os.
274         // Also the linker introduces implicit dependencies reported by LinkerDeps.
275         stk.Push("testmain")
276         deps := TestMainDeps // cap==len, so safe for append
277         for _, d := range LinkerDeps(p) {
278                 deps = append(deps, d)
279         }
280         for _, dep := range deps {
281                 if dep == ptest.ImportPath {
282                         pmain.Internal.Imports = append(pmain.Internal.Imports, ptest)
283                 } else {
284                         p1 := loadImport(ctx, opts, pre, dep, "", nil, &stk, nil, 0)
285                         pmain.Internal.Imports = append(pmain.Internal.Imports, p1)
286                 }
287         }
288         stk.Pop()
289
290         if cover != nil && cover.Pkgs != nil {
291                 // Add imports, but avoid duplicates.
292                 seen := map[*Package]bool{p: true, ptest: true}
293                 for _, p1 := range pmain.Internal.Imports {
294                         seen[p1] = true
295                 }
296                 for _, p1 := range cover.Pkgs {
297                         if seen[p1] {
298                                 // Don't add duplicate imports.
299                                 continue
300                         }
301                         seen[p1] = true
302                         pmain.Internal.Imports = append(pmain.Internal.Imports, p1)
303                 }
304         }
305
306         allTestImports := make([]*Package, 0, len(pmain.Internal.Imports)+len(imports)+len(ximports))
307         allTestImports = append(allTestImports, pmain.Internal.Imports...)
308         allTestImports = append(allTestImports, imports...)
309         allTestImports = append(allTestImports, ximports...)
310         setToolFlags(allTestImports...)
311
312         // Do initial scan for metadata needed for writing _testmain.go
313         // Use that metadata to update the list of imports for package main.
314         // The list of imports is used by recompileForTest and by the loop
315         // afterward that gathers t.Cover information.
316         t, err := loadTestFuncs(ptest)
317         if err != nil && pmain.Error == nil {
318                 pmain.setLoadPackageDataError(err, p.ImportPath, &stk, nil)
319         }
320         t.Cover = cover
321         if len(ptest.GoFiles)+len(ptest.CgoFiles) > 0 {
322                 pmain.Internal.Imports = append(pmain.Internal.Imports, ptest)
323                 pmain.Imports = append(pmain.Imports, ptest.ImportPath)
324                 t.ImportTest = true
325         }
326         if pxtest != nil {
327                 pmain.Internal.Imports = append(pmain.Internal.Imports, pxtest)
328                 pmain.Imports = append(pmain.Imports, pxtest.ImportPath)
329                 t.ImportXtest = true
330         }
331         pmain.collectDeps()
332
333         // Sort and dedup pmain.Imports.
334         // Only matters for go list -test output.
335         sort.Strings(pmain.Imports)
336         w := 0
337         for _, path := range pmain.Imports {
338                 if w == 0 || path != pmain.Imports[w-1] {
339                         pmain.Imports[w] = path
340                         w++
341                 }
342         }
343         pmain.Imports = pmain.Imports[:w]
344         pmain.Internal.RawImports = str.StringList(pmain.Imports)
345
346         // Replace pmain's transitive dependencies with test copies, as necessary.
347         recompileForTest(pmain, p, ptest, pxtest)
348
349         // Should we apply coverage analysis locally,
350         // only for this package and only for this test?
351         // Yes, if -cover is on but -coverpkg has not specified
352         // a list of packages for global coverage.
353         if cover != nil && cover.Local {
354                 ptest.Internal.CoverMode = cover.Mode
355                 var coverFiles []string
356                 coverFiles = append(coverFiles, ptest.GoFiles...)
357                 coverFiles = append(coverFiles, ptest.CgoFiles...)
358                 ptest.Internal.CoverVars = cover.DeclVars(ptest, coverFiles...)
359         }
360
361         for _, cp := range pmain.Internal.Imports {
362                 if len(cp.Internal.CoverVars) > 0 {
363                         t.Cover.Vars = append(t.Cover.Vars, coverInfo{cp, cp.Internal.CoverVars})
364                 }
365         }
366
367         data, err := formatTestmain(t)
368         if err != nil && pmain.Error == nil {
369                 pmain.Error = &PackageError{Err: err}
370         }
371         if data != nil {
372                 pmain.Internal.TestmainGo = &data
373         }
374
375         return pmain, ptest, pxtest
376 }
377
378 // importCycleStack returns an import stack from p to the package whose import
379 // path is target.
380 func importCycleStack(p *Package, target string) []string {
381         // importerOf maps each import path to its importer nearest to p.
382         importerOf := map[string]string{p.ImportPath: ""}
383
384         // q is a breadth-first queue of packages to search for target.
385         // Every package added to q has a corresponding entry in pathTo.
386         //
387         // We search breadth-first for two reasons:
388         //
389         //      1. We want to report the shortest cycle.
390         //
391         //      2. If p contains multiple cycles, the first cycle we encounter might not
392         //         contain target. To ensure termination, we have to break all cycles
393         //         other than the first.
394         q := []*Package{p}
395
396         for len(q) > 0 {
397                 p := q[0]
398                 q = q[1:]
399                 if path := p.ImportPath; path == target {
400                         var stk []string
401                         for path != "" {
402                                 stk = append(stk, path)
403                                 path = importerOf[path]
404                         }
405                         return stk
406                 }
407                 for _, dep := range p.Internal.Imports {
408                         if _, ok := importerOf[dep.ImportPath]; !ok {
409                                 importerOf[dep.ImportPath] = p.ImportPath
410                                 q = append(q, dep)
411                         }
412                 }
413         }
414
415         panic("lost path to cycle")
416 }
417
418 // recompileForTest copies and replaces certain packages in pmain's dependency
419 // graph. This is necessary for two reasons. First, if ptest is different than
420 // preal, packages that import the package under test should get ptest instead
421 // of preal. This is particularly important if pxtest depends on functionality
422 // exposed in test sources in ptest. Second, if there is a main package
423 // (other than pmain) anywhere, we need to set p.Internal.ForceLibrary and
424 // clear p.Internal.BuildInfo in the test copy to prevent link conflicts.
425 // This may happen if both -coverpkg and the command line patterns include
426 // multiple main packages.
427 func recompileForTest(pmain, preal, ptest, pxtest *Package) {
428         // The "test copy" of preal is ptest.
429         // For each package that depends on preal, make a "test copy"
430         // that depends on ptest. And so on, up the dependency tree.
431         testCopy := map[*Package]*Package{preal: ptest}
432         for _, p := range PackageList([]*Package{pmain}) {
433                 if p == preal {
434                         continue
435                 }
436                 // Copy on write.
437                 didSplit := p == pmain || p == pxtest
438                 split := func() {
439                         if didSplit {
440                                 return
441                         }
442                         didSplit = true
443                         if testCopy[p] != nil {
444                                 panic("recompileForTest loop")
445                         }
446                         p1 := new(Package)
447                         testCopy[p] = p1
448                         *p1 = *p
449                         p1.ForTest = preal.ImportPath
450                         p1.Internal.Imports = make([]*Package, len(p.Internal.Imports))
451                         copy(p1.Internal.Imports, p.Internal.Imports)
452                         p1.Imports = make([]string, len(p.Imports))
453                         copy(p1.Imports, p.Imports)
454                         p = p1
455                         p.Target = ""
456                         p.Internal.BuildInfo = ""
457                         p.Internal.ForceLibrary = true
458                 }
459
460                 // Update p.Internal.Imports to use test copies.
461                 for i, imp := range p.Internal.Imports {
462                         if p1 := testCopy[imp]; p1 != nil && p1 != imp {
463                                 split()
464                                 p.Internal.Imports[i] = p1
465                         }
466                 }
467
468                 // Force main packages the test imports to be built as libraries.
469                 // Normal imports of main packages are forbidden by the package loader,
470                 // but this can still happen if -coverpkg patterns include main packages:
471                 // covered packages are imported by pmain. Linking multiple packages
472                 // compiled with '-p main' causes duplicate symbol errors.
473                 // See golang.org/issue/30907, golang.org/issue/34114.
474                 if p.Name == "main" && p != pmain && p != ptest {
475                         split()
476                 }
477         }
478 }
479
480 // isTestFunc tells whether fn has the type of a testing function. arg
481 // specifies the parameter type we look for: B, M or T.
482 func isTestFunc(fn *ast.FuncDecl, arg string) bool {
483         if fn.Type.Results != nil && len(fn.Type.Results.List) > 0 ||
484                 fn.Type.Params.List == nil ||
485                 len(fn.Type.Params.List) != 1 ||
486                 len(fn.Type.Params.List[0].Names) > 1 {
487                 return false
488         }
489         ptr, ok := fn.Type.Params.List[0].Type.(*ast.StarExpr)
490         if !ok {
491                 return false
492         }
493         // We can't easily check that the type is *testing.M
494         // because we don't know how testing has been imported,
495         // but at least check that it's *M or *something.M.
496         // Same applies for B and T.
497         if name, ok := ptr.X.(*ast.Ident); ok && name.Name == arg {
498                 return true
499         }
500         if sel, ok := ptr.X.(*ast.SelectorExpr); ok && sel.Sel.Name == arg {
501                 return true
502         }
503         return false
504 }
505
506 // isTest tells whether name looks like a test (or benchmark, according to prefix).
507 // It is a Test (say) if there is a character after Test that is not a lower-case letter.
508 // We don't want TesticularCancer.
509 func isTest(name, prefix string) bool {
510         if !strings.HasPrefix(name, prefix) {
511                 return false
512         }
513         if len(name) == len(prefix) { // "Test" is ok
514                 return true
515         }
516         rune, _ := utf8.DecodeRuneInString(name[len(prefix):])
517         return !unicode.IsLower(rune)
518 }
519
520 type coverInfo struct {
521         Package *Package
522         Vars    map[string]*CoverVar
523 }
524
525 // loadTestFuncs returns the testFuncs describing the tests that will be run.
526 // The returned testFuncs is always non-nil, even if an error occurred while
527 // processing test files.
528 func loadTestFuncs(ptest *Package) (*testFuncs, error) {
529         t := &testFuncs{
530                 Package: ptest,
531         }
532         var err error
533         for _, file := range ptest.TestGoFiles {
534                 if lerr := t.load(filepath.Join(ptest.Dir, file), "_test", &t.ImportTest, &t.NeedTest); lerr != nil && err == nil {
535                         err = lerr
536                 }
537         }
538         for _, file := range ptest.XTestGoFiles {
539                 if lerr := t.load(filepath.Join(ptest.Dir, file), "_xtest", &t.ImportXtest, &t.NeedXtest); lerr != nil && err == nil {
540                         err = lerr
541                 }
542         }
543         return t, err
544 }
545
546 // formatTestmain returns the content of the _testmain.go file for t.
547 func formatTestmain(t *testFuncs) ([]byte, error) {
548         var buf bytes.Buffer
549         if err := testmainTmpl.Execute(&buf, t); err != nil {
550                 return nil, err
551         }
552         return buf.Bytes(), nil
553 }
554
555 type testFuncs struct {
556         Tests       []testFunc
557         Benchmarks  []testFunc
558         FuzzTargets []testFunc
559         Examples    []testFunc
560         TestMain    *testFunc
561         Package     *Package
562         ImportTest  bool
563         NeedTest    bool
564         ImportXtest bool
565         NeedXtest   bool
566         Cover       *TestCover
567 }
568
569 // ImportPath returns the import path of the package being tested, if it is within GOPATH.
570 // This is printed by the testing package when running benchmarks.
571 func (t *testFuncs) ImportPath() string {
572         pkg := t.Package.ImportPath
573         if strings.HasPrefix(pkg, "_/") {
574                 return ""
575         }
576         if pkg == "command-line-arguments" {
577                 return ""
578         }
579         return pkg
580 }
581
582 // Covered returns a string describing which packages are being tested for coverage.
583 // If the covered package is the same as the tested package, it returns the empty string.
584 // Otherwise it is a comma-separated human-readable list of packages beginning with
585 // " in", ready for use in the coverage message.
586 func (t *testFuncs) Covered() string {
587         if t.Cover == nil || t.Cover.Paths == nil {
588                 return ""
589         }
590         return " in " + strings.Join(t.Cover.Paths, ", ")
591 }
592
593 // Tested returns the name of the package being tested.
594 func (t *testFuncs) Tested() string {
595         return t.Package.Name
596 }
597
598 type testFunc struct {
599         Package   string // imported package name (_test or _xtest)
600         Name      string // function name
601         Output    string // output, for examples
602         Unordered bool   // output is allowed to be unordered.
603 }
604
605 var testFileSet = token.NewFileSet()
606
607 func (t *testFuncs) load(filename, pkg string, doImport, seen *bool) error {
608         // Pass in the overlaid source if we have an overlay for this file.
609         src, err := fsys.Open(filename)
610         if err != nil {
611                 return err
612         }
613         defer src.Close()
614         f, err := parser.ParseFile(testFileSet, filename, src, parser.ParseComments)
615         if err != nil {
616                 return err
617         }
618         for _, d := range f.Decls {
619                 n, ok := d.(*ast.FuncDecl)
620                 if !ok {
621                         continue
622                 }
623                 if n.Recv != nil {
624                         continue
625                 }
626                 name := n.Name.String()
627                 switch {
628                 case name == "TestMain":
629                         if isTestFunc(n, "T") {
630                                 t.Tests = append(t.Tests, testFunc{pkg, name, "", false})
631                                 *doImport, *seen = true, true
632                                 continue
633                         }
634                         err := checkTestFunc(n, "M")
635                         if err != nil {
636                                 return err
637                         }
638                         if t.TestMain != nil {
639                                 return errors.New("multiple definitions of TestMain")
640                         }
641                         t.TestMain = &testFunc{pkg, name, "", false}
642                         *doImport, *seen = true, true
643                 case isTest(name, "Test"):
644                         err := checkTestFunc(n, "T")
645                         if err != nil {
646                                 return err
647                         }
648                         t.Tests = append(t.Tests, testFunc{pkg, name, "", false})
649                         *doImport, *seen = true, true
650                 case isTest(name, "Benchmark"):
651                         err := checkTestFunc(n, "B")
652                         if err != nil {
653                                 return err
654                         }
655                         t.Benchmarks = append(t.Benchmarks, testFunc{pkg, name, "", false})
656                         *doImport, *seen = true, true
657                 case isTest(name, "Fuzz"):
658                         err := checkTestFunc(n, "F")
659                         if err != nil {
660                                 return err
661                         }
662                         t.FuzzTargets = append(t.FuzzTargets, testFunc{pkg, name, "", false})
663                         *doImport, *seen = true, true
664                 }
665         }
666         ex := doc.Examples(f)
667         sort.Slice(ex, func(i, j int) bool { return ex[i].Order < ex[j].Order })
668         for _, e := range ex {
669                 *doImport = true // import test file whether executed or not
670                 if e.Output == "" && !e.EmptyOutput {
671                         // Don't run examples with no output.
672                         continue
673                 }
674                 t.Examples = append(t.Examples, testFunc{pkg, "Example" + e.Name, e.Output, e.Unordered})
675                 *seen = true
676         }
677         return nil
678 }
679
680 func checkTestFunc(fn *ast.FuncDecl, arg string) error {
681         if !isTestFunc(fn, arg) {
682                 name := fn.Name.String()
683                 pos := testFileSet.Position(fn.Pos())
684                 return fmt.Errorf("%s: wrong signature for %s, must be: func %s(%s *testing.%s)", pos, name, name, strings.ToLower(arg), arg)
685         }
686         return nil
687 }
688
689 var testmainTmpl = lazytemplate.New("main", `
690 // Code generated by 'go test'. DO NOT EDIT.
691
692 package main
693
694 import (
695         "os"
696 {{if .TestMain}}
697         "reflect"
698 {{end}}
699         "testing"
700         "testing/internal/testdeps"
701
702 {{if .ImportTest}}
703         {{if .NeedTest}}_test{{else}}_{{end}} {{.Package.ImportPath | printf "%q"}}
704 {{end}}
705 {{if .ImportXtest}}
706         {{if .NeedXtest}}_xtest{{else}}_{{end}} {{.Package.ImportPath | printf "%s_test" | printf "%q"}}
707 {{end}}
708 {{if .Cover}}
709 {{range $i, $p := .Cover.Vars}}
710         _cover{{$i}} {{$p.Package.ImportPath | printf "%q"}}
711 {{end}}
712 {{end}}
713 )
714
715 var tests = []testing.InternalTest{
716 {{range .Tests}}
717         {"{{.Name}}", {{.Package}}.{{.Name}}},
718 {{end}}
719 }
720
721 var benchmarks = []testing.InternalBenchmark{
722 {{range .Benchmarks}}
723         {"{{.Name}}", {{.Package}}.{{.Name}}},
724 {{end}}
725 }
726
727 var fuzzTargets = []testing.InternalFuzzTarget{
728 {{range .FuzzTargets}}
729         {"{{.Name}}", {{.Package}}.{{.Name}}},
730 {{end}}
731 }
732
733 var examples = []testing.InternalExample{
734 {{range .Examples}}
735         {"{{.Name}}", {{.Package}}.{{.Name}}, {{.Output | printf "%q"}}, {{.Unordered}}},
736 {{end}}
737 }
738
739 func init() {
740         testdeps.ImportPath = {{.ImportPath | printf "%q"}}
741 }
742
743 {{if .Cover}}
744
745 // Only updated by init functions, so no need for atomicity.
746 var (
747         coverCounters = make(map[string][]uint32)
748         coverBlocks = make(map[string][]testing.CoverBlock)
749 )
750
751 func init() {
752         {{range $i, $p := .Cover.Vars}}
753         {{range $file, $cover := $p.Vars}}
754         coverRegisterFile({{printf "%q" $cover.File}}, _cover{{$i}}.{{$cover.Var}}.Count[:], _cover{{$i}}.{{$cover.Var}}.Pos[:], _cover{{$i}}.{{$cover.Var}}.NumStmt[:])
755         {{end}}
756         {{end}}
757 }
758
759 func coverRegisterFile(fileName string, counter []uint32, pos []uint32, numStmts []uint16) {
760         if 3*len(counter) != len(pos) || len(counter) != len(numStmts) {
761                 panic("coverage: mismatched sizes")
762         }
763         if coverCounters[fileName] != nil {
764                 // Already registered.
765                 return
766         }
767         coverCounters[fileName] = counter
768         block := make([]testing.CoverBlock, len(counter))
769         for i := range counter {
770                 block[i] = testing.CoverBlock{
771                         Line0: pos[3*i+0],
772                         Col0: uint16(pos[3*i+2]),
773                         Line1: pos[3*i+1],
774                         Col1: uint16(pos[3*i+2]>>16),
775                         Stmts: numStmts[i],
776                 }
777         }
778         coverBlocks[fileName] = block
779 }
780 {{end}}
781
782 func main() {
783 {{if .Cover}}
784         testing.RegisterCover(testing.Cover{
785                 Mode: {{printf "%q" .Cover.Mode}},
786                 Counters: coverCounters,
787                 Blocks: coverBlocks,
788                 CoveredPackages: {{printf "%q" .Covered}},
789         })
790 {{end}}
791         m := testing.MainStart(testdeps.TestDeps{}, tests, benchmarks, fuzzTargets, examples)
792 {{with .TestMain}}
793         {{.Package}}.{{.Name}}(m)
794         os.Exit(int(reflect.ValueOf(m).Elem().FieldByName("exitCode").Int()))
795 {{else}}
796         os.Exit(m.Run())
797 {{end}}
798 }
799
800 `)