GoPLS Viewer

Home|gopls/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
5package 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
11import (
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
30func 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    progerr := 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 := 205numPkgs < want {
64        t.Errorf("Loaded only %d packages, want at least %d"numPkgswant)
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{ pkgfn 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.pkgtest.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.Filebool {
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
121func 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        pkgnamegenericFile 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{falsetrue} {
159            conf := loader.Config{Build: &ctxt}
160            conf.Import(test.pkg)
161            progerr := 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.pkgtest.name)
174                continue
175            }
176            posn := prog.Fset.Position(obj.Pos())
177            t.Logf("%s: %s (CgoEnabled=%t)"posnobjctxt.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                    objgotFile)
185            } else if !ctxt.CgoEnabled && !filesMatch {
186                t.Errorf("CGO_ENABLED=0: %s found in %s, want %s",
187                    objgotFiletest.genericFile)
188            }
189
190            // Load the file and check the object is declared at the right place.
191            berr := ioutil.ReadFile(posn.Filename)
192            if err != nil {
193                t.Errorf("can't read %s: %s"posn.Filenameerr)
194                continue
195            }
196            line := string(bytes.Split(b, []byte("\n"))[posn.Line-1])
197            ident := line[posn.Column-1:]
198            if !strings.HasPrefix(identtest.name) {
199                t.Errorf("%s: %s not declared here (looking at %q)"posnobjident)
200            }
201        }
202    }
203}
204
MembersX
TestStdlib.t0
TestStdlib.want
TestCgoOption.RangeStmt_4362.BlockStmt.ctxt
TestCgoOption.RangeStmt_4362.BlockStmt.RangeStmt_4549.BlockStmt.err
TestCgoOption.RangeStmt_4362.BlockStmt.RangeStmt_4549.BlockStmt.obj
ioutil
TestStdlib.RangeStmt_1147.path
TestStdlib.t1
TestStdlib.BlockStmt.RangeStmt_1568.BlockStmt.scope
TestStdlib.conf
TestCgoOption.RangeStmt_4362.BlockStmt.RangeStmt_4549.BlockStmt.conf
TestStdlib.err
TestStdlib.BlockStmt.RangeStmt_1568.pkg
TestStdlib.lineCount
TestCgoOption
TestCgoOption.RangeStmt_4362.BlockStmt.RangeStmt_4549.BlockStmt.prog
TestCgoOption.RangeStmt_4362.BlockStmt.RangeStmt_4549.BlockStmt.b
TestStdlib.alloc
TestCgoOption.RangeStmt_4362.BlockStmt.RangeStmt_4549.BlockStmt.gotFile
TestCgoOption.RangeStmt_4362.BlockStmt.RangeStmt_4549.BlockStmt.line
TestStdlib.RangeStmt_2423.test
TestStdlib.t
TestStdlib.prog
TestCgoOption.RangeStmt_4362.BlockStmt.RangeStmt_4549.BlockStmt.posn
TestStdlib
TestStdlib.numPkgs
TestStdlib.BlockStmt.RangeStmt_1568.BlockStmt.qualifier
TestCgoOption.t
TestStdlib.ctxt
TestStdlib.memstats
TestStdlib.BlockStmt.RangeStmt_1568.BlockStmt.RangeStmt_1712.name
TestCgoOption.RangeStmt_4362.test
bytes
Members
X