GoPLS Viewer

Home|gopls/go/loader/loader_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// No testdata on Android.
6
7//go:build !android
8// +build !android
9
10package loader_test
11
12import (
13    "fmt"
14    "go/build"
15    "go/constant"
16    "go/types"
17    "os"
18    "path/filepath"
19    "reflect"
20    "runtime"
21    "sort"
22    "strings"
23    "sync"
24    "testing"
25
26    "golang.org/x/tools/go/buildutil"
27    "golang.org/x/tools/go/loader"
28    "golang.org/x/tools/internal/testenv"
29)
30
31func TestMain(m *testing.M) {
32    testenv.ExitIfSmallMachine()
33    os.Exit(m.Run())
34}
35
36// TestFromArgs checks that conf.FromArgs populates conf correctly.
37// It does no I/O.
38func TestFromArgs(t *testing.T) {
39    type result struct {
40        Err        string
41        Rest       []string
42        ImportPkgs map[string]bool
43        CreatePkgs []loader.PkgSpec
44    }
45    for _test := range []struct {
46        args  []string
47        tests bool
48        want  result
49    }{
50        // Mix of existing and non-existent packages.
51        {
52            args: []string{"nosuchpkg""errors"},
53            wantresult{
54                ImportPkgs: map[string]bool{"errors"false"nosuchpkg"false},
55            },
56        },
57        // Same, with -test flag.
58        {
59            args:  []string{"nosuchpkg""errors"},
60            teststrue,
61            wantresult{
62                ImportPkgs: map[string]bool{"errors"true"nosuchpkg"true},
63            },
64        },
65        // Surplus arguments.
66        {
67            args: []string{"fmt""errors""--""surplus"},
68            wantresult{
69                Rest:       []string{"surplus"},
70                ImportPkgs: map[string]bool{"errors"false"fmt"false},
71            },
72        },
73        // Ad hoc package specified as *.go files.
74        {
75            args: []string{"foo.go""bar.go"},
76            wantresult{CreatePkgs: []loader.PkgSpec{{
77                Filenames: []string{"foo.go""bar.go"},
78            }}},
79        },
80        // Mixture of *.go and import paths.
81        {
82            args: []string{"foo.go""fmt"},
83            wantresult{
84                Err"named files must be .go files: fmt",
85            },
86        },
87    } {
88        var conf loader.Config
89        resterr := conf.FromArgs(test.argstest.tests)
90        got := result{
91            Rest:       rest,
92            ImportPkgsconf.ImportPkgs,
93            CreatePkgsconf.CreatePkgs,
94        }
95        if err != nil {
96            got.Err = err.Error()
97        }
98        if !reflect.DeepEqual(gottest.want) {
99            t.Errorf("FromArgs(%q) = %+v, want %+v"test.argsgottest.want)
100        }
101    }
102}
103
104func TestLoad_NoInitialPackages(t *testing.T) {
105    var conf loader.Config
106
107    const wantErr = "no initial packages were loaded"
108
109    progerr := conf.Load()
110    if err == nil {
111        t.Errorf("Load succeeded unexpectedly, want %q"wantErr)
112    } else if err.Error() != wantErr {
113        t.Errorf("Load failed with wrong error %q, want %q"errwantErr)
114    }
115    if prog != nil {
116        t.Errorf("Load unexpectedly returned a Program")
117    }
118}
119
120func TestLoad_MissingInitialPackage(t *testing.T) {
121    var conf loader.Config
122    conf.Import("nosuchpkg")
123    conf.Import("errors")
124
125    const wantErr = "couldn't load packages due to errors: nosuchpkg"
126
127    progerr := conf.Load()
128    if err == nil {
129        t.Errorf("Load succeeded unexpectedly, want %q"wantErr)
130    } else if err.Error() != wantErr {
131        t.Errorf("Load failed with wrong error %q, want %q"errwantErr)
132    }
133    if prog != nil {
134        t.Errorf("Load unexpectedly returned a Program")
135    }
136}
137
138func TestLoad_MissingInitialPackage_AllowErrors(t *testing.T) {
139    if runtime.Compiler == "gccgo" {
140        t.Skip("gccgo has no standard library test files")
141    }
142
143    var conf loader.Config
144    conf.AllowErrors = true
145    conf.Import("nosuchpkg")
146    conf.ImportWithTests("errors")
147
148    progerr := conf.Load()
149    if err != nil {
150        t.Errorf("Load failed unexpectedly: %v"err)
151    }
152    if prog == nil {
153        t.Fatalf("Load returned a nil Program")
154    }
155    if gotwant := created(prog), "errors_test"got != want {
156        t.Errorf("Created = %s, want %s"gotwant)
157    }
158    if gotwant := imported(prog), "errors"got != want {
159        t.Errorf("Imported = %s, want %s"gotwant)
160    }
161}
162
163func TestCreateUnnamedPackage(t *testing.T) {
164    var conf loader.Config
165    conf.CreateFromFilenames("")
166    progerr := conf.Load()
167    if err != nil {
168        t.Fatalf("Load failed: %v"err)
169    }
170    if gotwant := fmt.Sprint(prog.InitialPackages()), "[(unnamed)]"got != want {
171        t.Errorf("InitialPackages = %s, want %s"gotwant)
172    }
173}
174
175func TestLoad_MissingFileInCreatedPackage(t *testing.T) {
176    var conf loader.Config
177    conf.CreateFromFilenames("""missing.go")
178
179    const wantErr = "couldn't load packages due to errors: (unnamed)"
180
181    progerr := conf.Load()
182    if prog != nil {
183        t.Errorf("Load unexpectedly returned a Program")
184    }
185    if err == nil {
186        t.Fatalf("Load succeeded unexpectedly, want %q"wantErr)
187    }
188    if err.Error() != wantErr {
189        t.Fatalf("Load failed with wrong error %q, want %q"errwantErr)
190    }
191}
192
193func TestLoad_MissingFileInCreatedPackage_AllowErrors(t *testing.T) {
194    conf := loader.Config{AllowErrorstrue}
195    conf.CreateFromFilenames("""missing.go")
196
197    progerr := conf.Load()
198    if err != nil {
199        t.Errorf("Load failed: %v"err)
200    }
201    if gotwant := fmt.Sprint(prog.InitialPackages()), "[(unnamed)]"got != want {
202        t.Fatalf("InitialPackages = %s, want %s"gotwant)
203    }
204}
205
206func TestLoad_ParseError(t *testing.T) {
207    var conf loader.Config
208    conf.CreateFromFilenames("badpkg""testdata/badpkgdecl.go")
209
210    const wantErr = "couldn't load packages due to errors: badpkg"
211
212    progerr := conf.Load()
213    if prog != nil {
214        t.Errorf("Load unexpectedly returned a Program")
215    }
216    if err == nil {
217        t.Fatalf("Load succeeded unexpectedly, want %q"wantErr)
218    }
219    if err.Error() != wantErr {
220        t.Fatalf("Load failed with wrong error %q, want %q"errwantErr)
221    }
222}
223
224func TestLoad_ParseError_AllowErrors(t *testing.T) {
225    var conf loader.Config
226    conf.AllowErrors = true
227    conf.CreateFromFilenames("badpkg""testdata/badpkgdecl.go")
228
229    progerr := conf.Load()
230    if err != nil {
231        t.Errorf("Load failed unexpectedly: %v"err)
232    }
233    if prog == nil {
234        t.Fatalf("Load returned a nil Program")
235    }
236    if gotwant := created(prog), "badpkg"got != want {
237        t.Errorf("Created = %s, want %s"gotwant)
238    }
239
240    badpkg := prog.Created[0]
241    if len(badpkg.Files) != 1 {
242        t.Errorf("badpkg has %d files, want 1"len(badpkg.Files))
243    }
244    wantErr := filepath.Join("testdata""badpkgdecl.go") + ":1:34: expected 'package', found 'EOF'"
245    if !hasError(badpkg.ErrorswantErr) {
246        t.Errorf("badpkg.Errors = %v, want %s"badpkg.ErrorswantErr)
247    }
248}
249
250func TestLoad_FromSource_Success(t *testing.T) {
251    var conf loader.Config
252    conf.CreateFromFilenames("P""testdata/a.go""testdata/b.go")
253
254    progerr := conf.Load()
255    if err != nil {
256        t.Errorf("Load failed unexpectedly: %v"err)
257    }
258    if prog == nil {
259        t.Fatalf("Load returned a nil Program")
260    }
261    if gotwant := created(prog), "P"got != want {
262        t.Errorf("Created = %s, want %s"gotwant)
263    }
264}
265
266func TestLoad_FromImports_Success(t *testing.T) {
267    if runtime.Compiler == "gccgo" {
268        t.Skip("gccgo has no standard library test files")
269    }
270
271    var conf loader.Config
272    conf.ImportWithTests("fmt")
273    conf.ImportWithTests("errors")
274
275    progerr := conf.Load()
276    if err != nil {
277        t.Errorf("Load failed unexpectedly: %v"err)
278    }
279    if prog == nil {
280        t.Fatalf("Load returned a nil Program")
281    }
282    if gotwant := created(prog), "errors_test fmt_test"got != want {
283        t.Errorf("Created = %q, want %s"gotwant)
284    }
285    if gotwant := imported(prog), "errors fmt"got != want {
286        t.Errorf("Imported = %s, want %s"gotwant)
287    }
288    // Check set of transitive packages.
289    // There are >30 and the set may grow over time, so only check a few.
290    want := map[string]bool{
291        "strings"true,
292        "time":    true,
293        "runtime"true,
294        "testing"true,
295        "unicode"true,
296    }
297    for _path := range all(prog) {
298        delete(wantpath)
299    }
300    if len(want) > 0 {
301        t.Errorf("AllPackages is missing these keys: %q"keys(want))
302    }
303}
304
305func TestLoad_MissingIndirectImport(t *testing.T) {
306    pkgs := map[string]string{
307        "a"`package a; import _ "b"`,
308        "b"`package b; import _ "c"`,
309    }
310    conf := loader.Config{BuildfakeContext(pkgs)}
311    conf.Import("a")
312
313    const wantErr = "couldn't load packages due to errors: b"
314
315    progerr := conf.Load()
316    if err == nil {
317        t.Errorf("Load succeeded unexpectedly, want %q"wantErr)
318    } else if err.Error() != wantErr {
319        t.Errorf("Load failed with wrong error %q, want %q"errwantErr)
320    }
321    if prog != nil {
322        t.Errorf("Load unexpectedly returned a Program")
323    }
324}
325
326func TestLoad_BadDependency_AllowErrors(t *testing.T) {
327    for _test := range []struct {
328        descr    string
329        pkgs     map[string]string
330        wantPkgs string
331    }{
332
333        {
334            descr"missing dependency",
335            pkgs: map[string]string{
336                "a"`package a; import _ "b"`,
337                "b"`package b; import _ "c"`,
338            },
339            wantPkgs"a b",
340        },
341        {
342            descr"bad package decl in dependency",
343            pkgs: map[string]string{
344                "a"`package a; import _ "b"`,
345                "b"`package b; import _ "c"`,
346                "c"`package`,
347            },
348            wantPkgs"a b",
349        },
350        {
351            descr"parse error in dependency",
352            pkgs: map[string]string{
353                "a"`package a; import _ "b"`,
354                "b"`package b; import _ "c"`,
355                "c"`package c; var x = `,
356            },
357            wantPkgs"a b c",
358        },
359    } {
360        conf := loader.Config{
361            AllowErrorstrue,
362            Build:       fakeContext(test.pkgs),
363        }
364        conf.Import("a")
365
366        progerr := conf.Load()
367        if err != nil {
368            t.Errorf("%s: Load failed unexpectedly: %v"test.descrerr)
369        }
370        if prog == nil {
371            t.Fatalf("%s: Load returned a nil Program"test.descr)
372        }
373
374        if gotwant := imported(prog), "a"got != want {
375            t.Errorf("%s: Imported = %s, want %s"test.descrgotwant)
376        }
377        if got := all(prog); strings.Join(got" ") != test.wantPkgs {
378            t.Errorf("%s: AllPackages = %s, want %s"test.descrgottest.wantPkgs)
379        }
380    }
381}
382
383func TestCwd(t *testing.T) {
384    ctxt := fakeContext(map[string]string{"one/two/three"`package three`})
385    for _test := range []struct {
386        cwdargwant string
387    }{
388        {cwd"/go/src/one"arg"./two/three"want"one/two/three"},
389        {cwd"/go/src/one"arg"../one/two/three"want"one/two/three"},
390        {cwd"/go/src/one"arg"one/two/three"want"one/two/three"},
391        {cwd"/go/src/one/two/three"arg"."want"one/two/three"},
392        {cwd"/go/src/one"arg"two/three"want""},
393    } {
394        conf := loader.Config{
395            Cwd:   test.cwd,
396            Buildctxt,
397        }
398        conf.Import(test.arg)
399
400        var got string
401        progerr := conf.Load()
402        if prog != nil {
403            got = imported(prog)
404        }
405        if got != test.want {
406            t.Errorf("Load(%s) from %s: Imported = %s, want %s",
407                test.argtest.cwdgottest.want)
408            if err != nil {
409                t.Errorf("Load failed: %v"err)
410            }
411        }
412    }
413}
414
415func TestLoad_vendor(t *testing.T) {
416    pkgs := map[string]string{
417        "a":          `package a; import _ "x"`,
418        "a/vendor":   ``// mkdir a/vendor
419        "a/vendor/x"`package xa`,
420        "b":          `package b; import _ "x"`,
421        "b/vendor":   ``// mkdir b/vendor
422        "b/vendor/x"`package xb`,
423        "c":          `package c; import _ "x"`,
424        "x":          `package xc`,
425    }
426    conf := loader.Config{BuildfakeContext(pkgs)}
427    conf.Import("a")
428    conf.Import("b")
429    conf.Import("c")
430
431    progerr := conf.Load()
432    if err != nil {
433        t.Fatal(err)
434    }
435
436    // Check that a, b, and c see different versions of x.
437    for _r := range "abc" {
438        name := string(r)
439        got := prog.Package(name).Pkg.Imports()[0]
440        want := "x" + name
441        if got.Name() != want {
442            t.Errorf("package %s import %q = %s, want %s",
443                name"x"got.Name(), want)
444        }
445    }
446}
447
448func TestVendorCwd(t *testing.T) {
449    // Test the interaction of cwd and vendor directories.
450    ctxt := fakeContext(map[string]string{
451        "net":          ``// mkdir net
452        "net/http":     `package http; import _ "hpack"`,
453        "vendor":       ``// mkdir vendor
454        "vendor/hpack"`package vendorhpack`,
455        "hpack":        `package hpack`,
456    })
457    for itest := range []struct {
458        cwdargwant string
459    }{
460        {cwd"/go/src/net"arg"http"}, // not found
461        {cwd"/go/src/net"arg"./http"want"net/http vendor/hpack"},
462        {cwd"/go/src/net"arg"hpack"want"vendor/hpack"},
463        {cwd"/go/src/vendor"arg"hpack"want"vendor/hpack"},
464        {cwd"/go/src/vendor"arg"./hpack"want"vendor/hpack"},
465    } {
466        conf := loader.Config{
467            Cwd:   test.cwd,
468            Buildctxt,
469        }
470        conf.Import(test.arg)
471
472        var got string
473        progerr := conf.Load()
474        if prog != nil {
475            got = strings.Join(all(prog), " ")
476        }
477        if got != test.want {
478            t.Errorf("#%d: Load(%s) from %s: got %s, want %s",
479                itest.argtest.cwdgottest.want)
480            if err != nil {
481                t.Errorf("Load failed: %v"err)
482            }
483        }
484    }
485}
486
487func TestVendorCwdIssue16580(t *testing.T) {
488    // Regression test for Go issue 16580.
489    // Import decls in "created" packages were vendor-resolved
490    // w.r.t. cwd, not the parent directory of the package's files.
491    ctxt := fakeContext(map[string]string{
492        "a":          ``// mkdir a
493        "a/vendor":   ``// mkdir a/vendor
494        "a/vendor/b"`package b; const X = true`,
495        "b":          `package b; const X = false`,
496    })
497    for _test := range []struct {
498        filenamecwd string
499        want          bool // expected value of b.X; depends on filename, not on cwd
500    }{
501        {filename"c.go"cwd"/go/src"wantfalse},
502        {filename"c.go"cwd"/go/src/a"wantfalse},
503        {filename"c.go"cwd"/go/src/a/b"wantfalse},
504        {filename"c.go"cwd"/go/src/a/vendor/b"wantfalse},
505
506        {filename"/go/src/a/c.go"cwd"/go/src"wanttrue},
507        {filename"/go/src/a/c.go"cwd"/go/src/a"wanttrue},
508        {filename"/go/src/a/c.go"cwd"/go/src/a/b"wanttrue},
509        {filename"/go/src/a/c.go"cwd"/go/src/a/vendor/b"wanttrue},
510
511        {filename"/go/src/c/c.go"cwd"/go/src"wantfalse},
512        {filename"/go/src/c/c.go"cwd"/go/src/a"wantfalse},
513        {filename"/go/src/c/c.go"cwd"/go/src/a/b"wantfalse},
514        {filename"/go/src/c/c.go"cwd"/go/src/a/vendor/b"wantfalse},
515    } {
516        conf := loader.Config{
517            Cwd:   test.cwd,
518            Buildctxt,
519        }
520        ferr := conf.ParseFile(test.filename`package dummy; import "b"; const X = b.X`)
521        if err != nil {
522            t.Fatal(f)
523        }
524        conf.CreateFromFiles("dummy"f)
525
526        progerr := conf.Load()
527        if err != nil {
528            t.Errorf("%+v: Load failed: %v"testerr)
529            continue
530        }
531
532        x := constant.BoolVal(prog.Created[0].Pkg.Scope().Lookup("X").(*types.Const).Val())
533        if x != test.want {
534            t.Errorf("%+v: b.X = %t"testx)
535        }
536    }
537
538    // TODO(adonovan): also test imports within XTestGoFiles.
539}
540
541// TODO(adonovan): more Load tests:
542//
543// failures:
544// - to parse package decl of *_test.go files
545// - to parse package decl of external *_test.go files
546// - to parse whole of *_test.go files
547// - to parse whole of external *_test.go files
548// - to open a *.go file during import scanning
549// - to import from binary
550
551// features:
552// - InitialPackages
553// - PackageCreated hook
554// - TypeCheckFuncBodies hook
555
556func TestTransitivelyErrorFreeFlag(t *testing.T) {
557    // Create an minimal custom build.Context
558    // that fakes the following packages:
559    //
560    // a --> b --> c!   c has an error
561    //   \              d and e are transitively error-free.
562    //    e --> d
563    //
564    // Each package [a-e] consists of one file, x.go.
565    pkgs := map[string]string{
566        "a"`package a; import (_ "b"; _ "e")`,
567        "b"`package b; import _ "c"`,
568        "c"`package c; func f() { _ = int(false) }`// type error within function body
569        "d"`package d;`,
570        "e"`package e; import _ "d"`,
571    }
572    conf := loader.Config{
573        AllowErrorstrue,
574        Build:       fakeContext(pkgs),
575    }
576    conf.Import("a")
577
578    progerr := conf.Load()
579    if err != nil {
580        t.Errorf("Load failed: %s"err)
581    }
582    if prog == nil {
583        t.Fatalf("Load returned nil *Program")
584    }
585
586    for pkginfo := range prog.AllPackages {
587        var wantErrwantTEF bool
588        switch pkg.Path() {
589        case "a""b":
590        case "c":
591            wantErr = true
592        case "d""e":
593            wantTEF = true
594        default:
595            t.Errorf("unexpected package: %q"pkg.Path())
596            continue
597        }
598
599        if (info.Errors != nil) != wantErr {
600            if wantErr {
601                t.Errorf("Package %q.Error = nil, want error"pkg.Path())
602            } else {
603                t.Errorf("Package %q has unexpected Errors: %v",
604                    pkg.Path(), info.Errors)
605            }
606        }
607
608        if info.TransitivelyErrorFree != wantTEF {
609            t.Errorf("Package %q.TransitivelyErrorFree=%t, want %t",
610                pkg.Path(), info.TransitivelyErrorFreewantTEF)
611        }
612    }
613}
614
615// Test that syntax (scan/parse), type, and loader errors are recorded
616// (in PackageInfo.Errors) and reported (via Config.TypeChecker.Error).
617func TestErrorReporting(t *testing.T) {
618    pkgs := map[string]string{
619        "a"`package a; import (_ "b"; _ "c"); var x int = false`,
620        "b"`package b; 'syntax error!`,
621    }
622    conf := loader.Config{
623        AllowErrorstrue,
624        Build:       fakeContext(pkgs),
625    }
626    var mu sync.Mutex
627    var allErrors []error
628    conf.TypeChecker.Error = func(err error) {
629        mu.Lock()
630        allErrors = append(allErrorserr)
631        mu.Unlock()
632    }
633    conf.Import("a")
634
635    progerr := conf.Load()
636    if err != nil {
637        t.Errorf("Load failed: %s"err)
638    }
639    if prog == nil {
640        t.Fatalf("Load returned nil *Program")
641    }
642
643    // TODO(adonovan): test keys of ImportMap.
644
645    // Check errors recorded in each PackageInfo.
646    for pkginfo := range prog.AllPackages {
647        switch pkg.Path() {
648        case "a":
649            // The match below is unfortunately vague, because in go1.16 the error
650            // message in go/types changed from "cannot convert ..." to "cannot use
651            // ... as ... in assignment".
652            if !hasError(info.Errors"cannot") {
653                t.Errorf("a.Errors = %v, want bool assignment (type) error"info.Errors)
654            }
655            if !hasError(info.Errors"could not import c") {
656                t.Errorf("a.Errors = %v, want import (loader) error"info.Errors)
657            }
658        case "b":
659            if !hasError(info.Errors"rune literal not terminated") {
660                t.Errorf("b.Errors = %v, want unterminated literal (syntax) error"info.Errors)
661            }
662        }
663    }
664
665    // Check errors reported via error handler.
666    if !hasError(allErrors"cannot") ||
667        !hasError(allErrors"rune literal not terminated") ||
668        !hasError(allErrors"could not import c") {
669        t.Errorf("allErrors = %v, want syntax, type and loader errors"allErrors)
670    }
671}
672
673func TestCycles(t *testing.T) {
674    for _test := range []struct {
675        descr   string
676        ctxt    *build.Context
677        wantErr string
678    }{
679        {
680            "self-cycle",
681            fakeContext(map[string]string{
682                "main":      `package main; import _ "selfcycle"`,
683                "selfcycle"`package selfcycle; import _ "selfcycle"`,
684            }),
685            `import cycle: selfcycle -> selfcycle`,
686        },
687        {
688            "three-package cycle",
689            fakeContext(map[string]string{
690                "main"`package main; import _ "a"`,
691                "a":    `package a; import _ "b"`,
692                "b":    `package b; import _ "c"`,
693                "c":    `package c; import _ "a"`,
694            }),
695            `import cycle: c -> a -> b -> c`,
696        },
697        {
698            "self-cycle in dependency of test file",
699            buildutil.FakeContext(map[string]map[string]string{
700                "main": {
701                    "main.go":      `package main`,
702                    "main_test.go"`package main; import _ "a"`,
703                },
704                "a": {
705                    "a.go"`package a; import _ "a"`,
706                },
707            }),
708            `import cycle: a -> a`,
709        },
710        // TODO(adonovan): fix: these fail
711        // {
712        //     "two-package cycle in dependency of test file",
713        //     buildutil.FakeContext(map[string]map[string]string{
714        //         "main": {
715        //             "main.go":      `package main`,
716        //             "main_test.go": `package main; import _ "a"`,
717        //         },
718        //         "a": {
719        //             "a.go": `package a; import _ "main"`,
720        //         },
721        //     }),
722        //     `import cycle: main -> a -> main`,
723        // },
724        // {
725        //     "self-cycle in augmented package",
726        //     buildutil.FakeContext(map[string]map[string]string{
727        //         "main": {
728        //             "main.go":      `package main`,
729        //             "main_test.go": `package main; import _ "main"`,
730        //         },
731        //     }),
732        //     `import cycle: main -> main`,
733        // },
734    } {
735        conf := loader.Config{
736            AllowErrorstrue,
737            Build:       test.ctxt,
738        }
739        var mu sync.Mutex
740        var allErrors []error
741        conf.TypeChecker.Error = func(err error) {
742            mu.Lock()
743            allErrors = append(allErrorserr)
744            mu.Unlock()
745        }
746        conf.ImportWithTests("main")
747
748        progerr := conf.Load()
749        if err != nil {
750            t.Errorf("%s: Load failed: %s"test.descrerr)
751        }
752        if prog == nil {
753            t.Fatalf("%s: Load returned nil *Program"test.descr)
754        }
755
756        if !hasError(allErrorstest.wantErr) {
757            t.Errorf("%s: Load() errors = %q, want %q",
758                test.descrallErrorstest.wantErr)
759        }
760    }
761
762    // TODO(adonovan):
763    // - Test that in a legal test cycle, none of the symbols
764    //   defined by augmentation are visible via import.
765}
766
767// ---- utilities ----
768
769// Simplifying wrapper around buildutil.FakeContext for single-file packages.
770func fakeContext(pkgs map[string]string) *build.Context {
771    pkgs2 := make(map[string]map[string]string)
772    for pathcontent := range pkgs {
773        pkgs2[path] = map[string]string{"x.go"content}
774    }
775    return buildutil.FakeContext(pkgs2)
776}
777
778func hasError(errors []errorsubstr stringbool {
779    for _err := range errors {
780        if strings.Contains(err.Error(), substr) {
781            return true
782        }
783    }
784    return false
785}
786
787func keys(m map[string]bool) (keys []string) {
788    for key := range m {
789        keys = append(keyskey)
790    }
791    sort.Strings(keys)
792    return
793}
794
795// Returns all loaded packages.
796func all(prog *loader.Program) []string {
797    var pkgs []string
798    for _info := range prog.AllPackages {
799        pkgs = append(pkgsinfo.Pkg.Path())
800    }
801    sort.Strings(pkgs)
802    return pkgs
803}
804
805// Returns initially imported packages, as a string.
806func imported(prog *loader.Programstring {
807    var pkgs []string
808    for _info := range prog.Imported {
809        pkgs = append(pkgsinfo.Pkg.Path())
810    }
811    sort.Strings(pkgs)
812    return strings.Join(pkgs" ")
813}
814
815// Returns initially created packages, as a string.
816func created(prog *loader.Programstring {
817    var pkgs []string
818    for _info := range prog.Created {
819        pkgs = append(pkgsinfo.Pkg.Path())
820    }
821    return strings.Join(pkgs" ")
822}
823
824// Load package "io" twice in parallel.
825// When run with -race, this is a regression test for Go issue 20718, in
826// which the global "unsafe" package was modified concurrently.
827func TestLoad1(t *testing.T) { loadIO(t) }
828func TestLoad2(t *testing.T) { loadIO(t) }
829
830func loadIO(t *testing.T) {
831    t.Parallel()
832    conf := &loader.Config{ImportPkgs: map[string]bool{"io"false}}
833    if _err := conf.Load(); err != nil {
834        t.Fatal(err)
835    }
836}
837
838func TestCgoCwdIssue46877(t *testing.T) {
839    var conf loader.Config
840    conf.Import("golang.org/x/tools/go/loader/testdata/issue46877")
841    if _err := conf.Load(); err != nil {
842        t.Errorf("Load failed: %v"err)
843    }
844}
845
MembersX
TestCwd.RangeStmt_9537.BlockStmt.prog
TestVendorCwd
TestVendorCwdIssue16580.ctxt
TestVendorCwdIssue16580.RangeStmt_12630.test
loader
TestMain.m
TestLoad_FromSource_Success.want
TestLoad_MissingIndirectImport.wantErr
loadIO.err
TestVendorCwdIssue16580.RangeStmt_12630.BlockStmt.conf
TestErrorReporting.pkgs
TestErrorReporting.prog
all.prog
TestLoad_BadDependency_AllowErrors.RangeStmt_8170.BlockStmt.err
TestCwd.t
fakeContext.RangeStmt_20221.path
TestLoad_MissingInitialPackage.prog
TestLoad_MissingInitialPackage_AllowErrors
TestCreateUnnamedPackage.conf
TestLoad_BadDependency_AllowErrors.RangeStmt_8170.BlockStmt.conf
TestLoad_ParseError.err
TestLoad_ParseError_AllowErrors
TestCwd.RangeStmt_9537.BlockStmt.err
TestTransitivelyErrorFreeFlag.RangeStmt_15262.BlockStmt.wantTEF
runtime
TestFromArgs.result.Rest
TestLoad_MissingFileInCreatedPackage_AllowErrors.got
TestLoad_MissingFileInCreatedPackage_AllowErrors.want
TestCycles.RangeStmt_17693.test
imported.RangeStmt_20975.info
keys.m
TestLoad_MissingFileInCreatedPackage.t
TestLoad_MissingFileInCreatedPackage.wantErr
TestLoad_MissingIndirectImport.pkgs
TestVendorCwd.ctxt
TestCgoCwdIssue46877.conf
TestFromArgs.RangeStmt_827.BlockStmt.rest
TestLoad_NoInitialPackages.prog
TestLoad_MissingFileInCreatedPackage_AllowErrors.prog
TestTransitivelyErrorFreeFlag.pkgs
TestCgoCwdIssue46877.t
TestFromArgs.t
TestLoad_BadDependency_AllowErrors.RangeStmt_8170.test
TestVendorCwdIssue16580.RangeStmt_12630.BlockStmt.x
keys
TestTransitivelyErrorFreeFlag.RangeStmt_15262.BlockStmt.wantErr
TestCycles.RangeStmt_17693.BlockStmt.mu
fakeContext.RangeStmt_20221.content
TestErrorReporting
TestCycles.RangeStmt_17693.BlockStmt.err
fakeContext
created.prog
TestLoad_NoInitialPackages.conf
TestLoad_MissingInitialPackage_AllowErrors.prog
TestLoad_MissingFileInCreatedPackage_AllowErrors
TestLoad_MissingFileInCreatedPackage_AllowErrors.conf
created.RangeStmt_21225.info
hasError.RangeStmt_20402.err
created
testenv
TestLoad_NoInitialPackages.t
TestLoad_MissingIndirectImport
TestLoad_vendor.RangeStmt_10887.r
TestCwd
TestVendorCwdIssue16580
loadIO
loadIO.conf
TestLoad_MissingIndirectImport.conf
TestLoad_BadDependency_AllowErrors.RangeStmt_8170.BlockStmt.got
TestVendorCwdIssue16580.RangeStmt_12630.BlockStmt.prog
TestErrorReporting.allErrors
TestLoad_FromSource_Success.conf
TestLoad_FromImports_Success.t
TestLoad_FromImports_Success.conf
TestLoad_FromImports_Success.RangeStmt_7401.path
TestLoad_MissingIndirectImport.err
TestLoad_vendor.RangeStmt_10887.BlockStmt.name
fakeContext.pkgs
reflect
TestFromArgs.result.CreatePkgs
TestLoad_MissingInitialPackage_AllowErrors.got
TestCreateUnnamedPackage.got
fakeContext.pkgs2
TestCgoCwdIssue46877._
TestLoad_MissingInitialPackage_AllowErrors.want
TestLoad_ParseError.wantErr
TestLoad_FromImports_Success.err
TestTransitivelyErrorFreeFlag.err
TestLoad_BadDependency_AllowErrors.RangeStmt_8170.BlockStmt.want
TestCwd.ctxt
TestLoad_ParseError.prog
TestLoad_vendor
TestErrorReporting.conf
hasError.substr
buildutil
TestFromArgs
TestFromArgs.RangeStmt_827.test
TestLoad_MissingFileInCreatedPackage.conf
TestCwd.RangeStmt_9537.BlockStmt.got
TestVendorCwd.RangeStmt_11455.BlockStmt.prog
TestLoad1.t
TestFromArgs.result
TestLoad_NoInitialPackages.wantErr
TestLoad_MissingInitialPackage_AllowErrors.conf
TestLoad_MissingIndirectImport.prog
TestLoad2
TestLoad_MissingInitialPackage
TestLoad_vendor.err
TestVendorCwdIssue16580.RangeStmt_12630.BlockStmt.f
created.pkgs
hasError.errors
TestLoad_ParseError_AllowErrors.err
TestLoad_BadDependency_AllowErrors.t
TestVendorCwd.RangeStmt_11455.test
TestTransitivelyErrorFreeFlag.conf
TestCycles
all.pkgs
TestLoad_NoInitialPackages
TestLoad_ParseError.conf
TestLoad_MissingIndirectImport.t
TestLoad_vendor.pkgs
TestLoad_vendor.conf
TestCreateUnnamedPackage.prog
TestLoad_MissingFileInCreatedPackage_AllowErrors.t
TestLoad_ParseError_AllowErrors.got
TestLoad_FromImports_Success.got
TestLoad_MissingInitialPackage.err
TestLoad_MissingFileInCreatedPackage.err
TestLoad_BadDependency_AllowErrors.RangeStmt_8170.BlockStmt.prog
TestLoad_vendor.t
TestLoad_FromImports_Success.prog
TestVendorCwd.RangeStmt_11455.BlockStmt.err
TestErrorReporting.mu
TestCycles.RangeStmt_17693.BlockStmt.allErrors
TestFromArgs.RangeStmt_827.BlockStmt.conf
TestLoad_MissingInitialPackage_AllowErrors.err
TestLoad_FromSource_Success
TestLoad_FromSource_Success.err
TestVendorCwd.RangeStmt_11455.i
TestErrorReporting.RangeStmt_16707.pkg
keys.keys
keys.RangeStmt_20563.key
TestFromArgs.RangeStmt_827.BlockStmt.err
TestLoad_NoInitialPackages.err
TestLoad_ParseError_AllowErrors.prog
TestLoad_FromSource_Success.prog
imported.pkgs
TestLoad_FromImports_Success
TestLoad_FromImports_Success.want
TestCwd.RangeStmt_9537.test
TestVendorCwd.RangeStmt_11455.BlockStmt.got
TestLoad_MissingInitialPackage.wantErr
TestCreateUnnamedPackage
TestLoad_ParseError_AllowErrors.t
TestLoad_ParseError_AllowErrors.conf
TestLoad2.t
TestVendorCwdIssue16580.RangeStmt_12630.BlockStmt.err
TestTransitivelyErrorFreeFlag.t
TestCycles.t
TestCycles.RangeStmt_17693.BlockStmt.prog
TestTransitivelyErrorFreeFlag
TestTransitivelyErrorFreeFlag.RangeStmt_15262.info
imported.prog
TestCgoCwdIssue46877
testing
TestLoad_MissingInitialPackage.t
TestLoad_FromSource_Success.got
TestLoad_BadDependency_AllowErrors
TestCgoCwdIssue46877.err
TestLoad_ParseError_AllowErrors.want
TestVendorCwd.RangeStmt_11455.BlockStmt.conf
TestLoad_MissingInitialPackage.conf
TestLoad_MissingFileInCreatedPackage
TestLoad_MissingFileInCreatedPackage.prog
TestLoad_MissingFileInCreatedPackage_AllowErrors.err
TestLoad_MissingInitialPackage_AllowErrors.t
TestVendorCwdIssue16580.t
loadIO.t
constant
TestCreateUnnamedPackage.err
TestLoad_vendor.prog
imported
TestTransitivelyErrorFreeFlag.RangeStmt_15262.pkg
TestErrorReporting.RangeStmt_16707.info
TestCycles.RangeStmt_17693.BlockStmt.conf
hasError
TestMain
TestFromArgs.result.ImportPkgs
TestLoad_ParseError.t
TestCwd.RangeStmt_9537.BlockStmt.conf
loadIO._
TestFromArgs.result.Err
TestFromArgs.RangeStmt_827.BlockStmt.got
TestLoad_FromSource_Success.t
all.RangeStmt_20739.info
TestCreateUnnamedPackage.want
TestLoad_ParseError
TestErrorReporting.t
TestLoad1
all
TestCreateUnnamedPackage.t
TestVendorCwd.t
TestTransitivelyErrorFreeFlag.prog
TestErrorReporting.err
Members
X