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