Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.0.0-20201105173854-bc9fc8d8c4bc / go / loader / stdlib_test.go
1 // Copyright 2013 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 loader_test
6
7 // This file enumerates all packages beneath $GOROOT, loads them, plus
8 // their external tests if any, runs the type checker on them, and
9 // prints some summary information.
10
11 import (
12         "bytes"
13         "fmt"
14         "go/ast"
15         "go/build"
16         "go/token"
17         "go/types"
18         "io/ioutil"
19         "path/filepath"
20         "runtime"
21         "strings"
22         "testing"
23         "time"
24
25         "golang.org/x/tools/go/buildutil"
26         "golang.org/x/tools/go/loader"
27         "golang.org/x/tools/internal/testenv"
28 )
29
30 func TestStdlib(t *testing.T) {
31         if runtime.GOOS == "android" {
32                 t.Skipf("incomplete std lib on %s", runtime.GOOS)
33         }
34         if testing.Short() {
35                 t.Skip("skipping in short mode; uses tons of memory (https://golang.org/issue/14113)")
36         }
37         testenv.NeedsTool(t, "go")
38
39         runtime.GC()
40         t0 := time.Now()
41         var memstats runtime.MemStats
42         runtime.ReadMemStats(&memstats)
43         alloc := memstats.Alloc
44
45         // Load, parse and type-check the program.
46         ctxt := build.Default // copy
47         ctxt.GOPATH = ""      // disable GOPATH
48         conf := loader.Config{Build: &ctxt}
49         for _, path := range buildutil.AllPackages(conf.Build) {
50                 conf.ImportWithTests(path)
51         }
52
53         prog, err := conf.Load()
54         if err != nil {
55                 t.Fatalf("Load failed: %v", err)
56         }
57
58         t1 := time.Now()
59         runtime.GC()
60         runtime.ReadMemStats(&memstats)
61
62         numPkgs := len(prog.AllPackages)
63         if want := 205; numPkgs < want {
64                 t.Errorf("Loaded only %d packages, want at least %d", numPkgs, want)
65         }
66
67         // Dump package members.
68         if false {
69                 for pkg := range prog.AllPackages {
70                         fmt.Printf("Package %s:\n", pkg.Path())
71                         scope := pkg.Scope()
72                         qualifier := types.RelativeTo(pkg)
73                         for _, name := range scope.Names() {
74                                 if ast.IsExported(name) {
75                                         fmt.Printf("\t%s\n", types.ObjectString(scope.Lookup(name), qualifier))
76                                 }
77                         }
78                         fmt.Println()
79                 }
80         }
81
82         // Check that Test functions for regexp and compress/bzip2 are
83         // simultaneously present. The apparent cycle formed when augmenting
84         // these packages by their tests (together with io/ioutil's test, which is now
85         // an xtest) was the original motivation or reporting golang.org/issue/7114.
86         //
87         // compress/bzip2.TestBitReader in bzip2_test.go    imports io/ioutil
88         // io/ioutil.TestTempFile       in tempfile_test.go imports regexp (no longer exists)
89         // regexp.TestRE2Search         in exec_test.go     imports compress/bzip2
90         for _, test := range []struct{ pkg, fn string }{
91                 {"regexp", "TestRE2Search"},
92                 {"compress/bzip2", "TestBitReader"},
93         } {
94                 info := prog.Imported[test.pkg]
95                 if info == nil {
96                         t.Errorf("failed to load package %q", test.pkg)
97                         continue
98                 }
99                 obj, _ := info.Pkg.Scope().Lookup(test.fn).(*types.Func)
100                 if obj == nil {
101                         t.Errorf("package %q has no func %q", test.pkg, test.fn)
102                         continue
103                 }
104         }
105
106         // Dump some statistics.
107
108         // determine line count
109         var lineCount int
110         prog.Fset.Iterate(func(f *token.File) bool {
111                 lineCount += f.LineCount()
112                 return true
113         })
114
115         t.Log("GOMAXPROCS:           ", runtime.GOMAXPROCS(0))
116         t.Log("#Source lines:        ", lineCount)
117         t.Log("Load/parse/typecheck: ", t1.Sub(t0))
118         t.Log("#MB:                  ", int64(memstats.Alloc-alloc)/1000000)
119 }
120
121 func TestCgoOption(t *testing.T) {
122         if testing.Short() {
123                 t.Skip("skipping in short mode; uses tons of memory (https://golang.org/issue/14113)")
124         }
125         switch runtime.GOOS {
126         // On these systems, the net and os/user packages don't use cgo
127         // or the std library is incomplete (Android).
128         case "android", "plan9", "solaris", "windows":
129                 t.Skipf("no cgo or incomplete std lib on %s", runtime.GOOS)
130         }
131         // In nocgo builds (e.g. linux-amd64-nocgo),
132         // there is no "runtime/cgo" package,
133         // so cgo-generated Go files will have a failing import.
134         if !build.Default.CgoEnabled {
135                 return
136         }
137         testenv.NeedsTool(t, "go")
138
139         // Test that we can load cgo-using packages with
140         // CGO_ENABLED=[01], which causes go/build to select pure
141         // Go/native implementations, respectively, based on build
142         // tags.
143         //
144         // Each entry specifies a package-level object and the generic
145         // file expected to define it when cgo is disabled.
146         // When cgo is enabled, the exact file is not specified (since
147         // it varies by platform), but must differ from the generic one.
148         //
149         // The test also loads the actual file to verify that the
150         // object is indeed defined at that location.
151         for _, test := range []struct {
152                 pkg, name, genericFile string
153         }{
154                 {"net", "cgoLookupHost", "cgo_stub.go"},
155                 {"os/user", "current", "lookup_stubs.go"},
156         } {
157                 ctxt := build.Default
158                 for _, ctxt.CgoEnabled = range []bool{false, true} {
159                         conf := loader.Config{Build: &ctxt}
160                         conf.Import(test.pkg)
161                         prog, err := conf.Load()
162                         if err != nil {
163                                 t.Errorf("Load failed: %v", err)
164                                 continue
165                         }
166                         info := prog.Imported[test.pkg]
167                         if info == nil {
168                                 t.Errorf("package %s not found", test.pkg)
169                                 continue
170                         }
171                         obj := info.Pkg.Scope().Lookup(test.name)
172                         if obj == nil {
173                                 t.Errorf("no object %s.%s", test.pkg, test.name)
174                                 continue
175                         }
176                         posn := prog.Fset.Position(obj.Pos())
177                         t.Logf("%s: %s (CgoEnabled=%t)", posn, obj, ctxt.CgoEnabled)
178
179                         gotFile := filepath.Base(posn.Filename)
180                         filesMatch := gotFile == test.genericFile
181
182                         if ctxt.CgoEnabled && filesMatch {
183                                 t.Errorf("CGO_ENABLED=1: %s found in %s, want native file",
184                                         obj, gotFile)
185                         } else if !ctxt.CgoEnabled && !filesMatch {
186                                 t.Errorf("CGO_ENABLED=0: %s found in %s, want %s",
187                                         obj, gotFile, test.genericFile)
188                         }
189
190                         // Load the file and check the object is declared at the right place.
191                         b, err := ioutil.ReadFile(posn.Filename)
192                         if err != nil {
193                                 t.Errorf("can't read %s: %s", posn.Filename, err)
194                                 continue
195                         }
196                         line := string(bytes.Split(b, []byte("\n"))[posn.Line-1])
197                         ident := line[posn.Column-1:]
198                         if !strings.HasPrefix(ident, test.name) {
199                                 t.Errorf("%s: %s not declared here (looking at %q)", posn, obj, ident)
200                         }
201                 }
202         }
203 }