Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.0.0-20201028153306-37f0764111ff / go / packages / packages_test.go
diff --git a/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201028153306-37f0764111ff/go/packages/packages_test.go b/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201028153306-37f0764111ff/go/packages/packages_test.go
new file mode 100644 (file)
index 0000000..a5351ab
--- /dev/null
@@ -0,0 +1,2764 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package packages_test
+
+import (
+       "bytes"
+       "context"
+       "encoding/json"
+       "flag"
+       "fmt"
+       "go/ast"
+       constantpkg "go/constant"
+       "go/parser"
+       "go/token"
+       "go/types"
+       "io/ioutil"
+       "os"
+       "os/exec"
+       "path/filepath"
+       "reflect"
+       "runtime"
+       "sort"
+       "strings"
+       "testing"
+       "time"
+
+       "golang.org/x/tools/go/packages"
+       "golang.org/x/tools/go/packages/packagestest"
+       "golang.org/x/tools/internal/packagesinternal"
+       "golang.org/x/tools/internal/testenv"
+)
+
+// testCtx is canceled when the test binary is about to time out.
+//
+// If https://golang.org/issue/28135 is accepted, uses of this variable in test
+// functions should be replaced by t.Context().
+var testCtx = context.Background()
+
+func TestMain(m *testing.M) {
+       testenv.ExitIfSmallMachine()
+
+       timeoutFlag := flag.Lookup("test.timeout")
+       if timeoutFlag != nil {
+               if d := timeoutFlag.Value.(flag.Getter).Get().(time.Duration); d != 0 {
+                       aBitShorter := d * 95 / 100
+                       var cancel context.CancelFunc
+                       testCtx, cancel = context.WithTimeout(testCtx, aBitShorter)
+                       defer cancel()
+               }
+       }
+
+       os.Exit(m.Run())
+}
+
+// TODO(adonovan): more test cases to write:
+//
+// - When the tests fail, make them print a 'cd & load' command
+//   that will allow the maintainer to interact with the failing scenario.
+// - errors in go-list metadata
+// - a foo.test package that cannot be built for some reason (e.g.
+//   import error) will result in a JSON blob with no name and a
+//   nonexistent testmain file in GoFiles. Test that we handle this
+//   gracefully.
+// - test more Flags.
+//
+// LoadSyntax & LoadAllSyntax modes:
+//   - Fset may be user-supplied or not.
+//   - Packages.Info is correctly set.
+//   - typechecker configuration is honored
+//   - import cycles are gracefully handled in type checker.
+//   - test typechecking of generated test main and cgo.
+
+// The zero-value of Config has LoadFiles mode.
+func TestLoadZeroConfig(t *testing.T) {
+       testenv.NeedsGoPackages(t)
+
+       initial, err := packages.Load(nil, "hash")
+       if err != nil {
+               t.Fatal(err)
+       }
+       if len(initial) != 1 {
+               t.Fatalf("got %s, want [hash]", initial)
+       }
+       hash := initial[0]
+       // Even though the hash package has imports,
+       // they are not reported.
+       got := fmt.Sprintf("iamashamedtousethedisabledqueryname=%s srcs=%v imports=%v", hash.Name, srcs(hash), hash.Imports)
+       want := "iamashamedtousethedisabledqueryname=hash srcs=[hash.go] imports=map[]"
+       if got != want {
+               t.Fatalf("got %s, want %s", got, want)
+       }
+}
+
+func TestLoadImportsGraph(t *testing.T) { packagestest.TestAll(t, testLoadImportsGraph) }
+func testLoadImportsGraph(t *testing.T, exporter packagestest.Exporter) {
+       exported := packagestest.Export(t, exporter, []packagestest.Module{{
+               Name: "golang.org/fake",
+               Files: map[string]interface{}{
+                       "a/a.go":             `package a; const A = 1`,
+                       "b/b.go":             `package b; import ("golang.org/fake/a"; _ "container/list"); var B = a.A`,
+                       "c/c.go":             `package c; import (_ "golang.org/fake/b"; _ "unsafe")`,
+                       "c/c2.go":            "// +build ignore\n\n" + `package c; import _ "fmt"`,
+                       "subdir/d/d.go":      `package d`,
+                       "subdir/d/d_test.go": `package d; import _ "math/bits"`,
+                       "subdir/d/x_test.go": `package d_test; import _ "golang.org/fake/subdir/d"`, // TODO(adonovan): test bad import here
+                       "subdir/e/d.go":      `package e`,
+                       "e/e.go":             `package main; import _ "golang.org/fake/b"`,
+                       "e/e2.go":            `package main; import _ "golang.org/fake/c"`,
+                       "f/f.go":             `package f`,
+               }}})
+       defer exported.Cleanup()
+       exported.Config.Mode = packages.LoadImports
+       initial, err := packages.Load(exported.Config, "golang.org/fake/c", "golang.org/fake/subdir/d", "golang.org/fake/e")
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       // Check graph topology.
+       graph, _ := importGraph(initial)
+       wantGraph := `
+  container/list
+  golang.org/fake/a
+  golang.org/fake/b
+* golang.org/fake/c
+* golang.org/fake/e
+* golang.org/fake/subdir/d
+* golang.org/fake/subdir/d [golang.org/fake/subdir/d.test]
+* golang.org/fake/subdir/d.test
+* golang.org/fake/subdir/d_test [golang.org/fake/subdir/d.test]
+  math/bits
+  unsafe
+  golang.org/fake/b -> container/list
+  golang.org/fake/b -> golang.org/fake/a
+  golang.org/fake/c -> golang.org/fake/b
+  golang.org/fake/c -> unsafe
+  golang.org/fake/e -> golang.org/fake/b
+  golang.org/fake/e -> golang.org/fake/c
+  golang.org/fake/subdir/d [golang.org/fake/subdir/d.test] -> math/bits
+  golang.org/fake/subdir/d.test -> golang.org/fake/subdir/d [golang.org/fake/subdir/d.test]
+  golang.org/fake/subdir/d.test -> golang.org/fake/subdir/d_test [golang.org/fake/subdir/d.test]
+  golang.org/fake/subdir/d_test [golang.org/fake/subdir/d.test] -> golang.org/fake/subdir/d [golang.org/fake/subdir/d.test]
+`[1:]
+
+       if graph != wantGraph {
+               t.Errorf("wrong import graph: got <<%s>>, want <<%s>>", graph, wantGraph)
+       }
+
+       exported.Config.Tests = true
+       initial, err = packages.Load(exported.Config, "golang.org/fake/c", "golang.org/fake/subdir/d", "golang.org/fake/e")
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       // Check graph topology.
+       graph, all := importGraph(initial)
+       wantGraph = `
+  container/list
+  golang.org/fake/a
+  golang.org/fake/b
+* golang.org/fake/c
+* golang.org/fake/e
+* golang.org/fake/subdir/d
+* golang.org/fake/subdir/d [golang.org/fake/subdir/d.test]
+* golang.org/fake/subdir/d.test
+* golang.org/fake/subdir/d_test [golang.org/fake/subdir/d.test]
+  math/bits
+  unsafe
+  golang.org/fake/b -> container/list
+  golang.org/fake/b -> golang.org/fake/a
+  golang.org/fake/c -> golang.org/fake/b
+  golang.org/fake/c -> unsafe
+  golang.org/fake/e -> golang.org/fake/b
+  golang.org/fake/e -> golang.org/fake/c
+  golang.org/fake/subdir/d [golang.org/fake/subdir/d.test] -> math/bits
+  golang.org/fake/subdir/d.test -> golang.org/fake/subdir/d [golang.org/fake/subdir/d.test]
+  golang.org/fake/subdir/d.test -> golang.org/fake/subdir/d_test [golang.org/fake/subdir/d.test]
+  golang.org/fake/subdir/d_test [golang.org/fake/subdir/d.test] -> golang.org/fake/subdir/d [golang.org/fake/subdir/d.test]
+`[1:]
+
+       if graph != wantGraph {
+               t.Errorf("wrong import graph: got <<%s>>, want <<%s>>", graph, wantGraph)
+       }
+
+       // Check node information: kind, name, srcs.
+       for _, test := range []struct {
+               id          string
+               wantName    string
+               wantKind    string
+               wantSrcs    string
+               wantIgnored string
+       }{
+               {"golang.org/fake/a", "a", "package", "a.go", ""},
+               {"golang.org/fake/b", "b", "package", "b.go", ""},
+               {"golang.org/fake/c", "c", "package", "c.go", "c2.go"}, // c2.go is ignored
+               {"golang.org/fake/e", "main", "command", "e.go e2.go", ""},
+               {"container/list", "list", "package", "list.go", ""},
+               {"golang.org/fake/subdir/d", "d", "package", "d.go", ""},
+               {"golang.org/fake/subdir/d.test", "main", "command", "0.go", ""},
+               {"unsafe", "unsafe", "package", "", ""},
+       } {
+               p, ok := all[test.id]
+               if !ok {
+                       t.Errorf("no package %s", test.id)
+                       continue
+               }
+               if p.Name != test.wantName {
+                       t.Errorf("%s.Name = %q, want %q", test.id, p.Name, test.wantName)
+               }
+
+               // kind
+               var kind string
+               if p.Name == "main" {
+                       kind += "command"
+               } else {
+                       kind += "package"
+               }
+               if kind != test.wantKind {
+                       t.Errorf("%s.Kind = %q, want %q", test.id, kind, test.wantKind)
+               }
+
+               if srcs := strings.Join(srcs(p), " "); srcs != test.wantSrcs {
+                       t.Errorf("%s.Srcs = [%s], want [%s]", test.id, srcs, test.wantSrcs)
+               }
+               if ignored := strings.Join(cleanPaths(p.IgnoredFiles), " "); ignored != test.wantIgnored {
+                       t.Errorf("%s.Srcs = [%s], want [%s]", test.id, ignored, test.wantIgnored)
+               }
+       }
+
+       // Test an ad-hoc package, analogous to "go run hello.go".
+       if initial, err := packages.Load(exported.Config, exported.File("golang.org/fake", "c/c.go")); len(initial) == 0 {
+               t.Errorf("failed to obtain metadata for ad-hoc package: %s", err)
+       } else {
+               got := fmt.Sprintf("%s %s", initial[0].ID, srcs(initial[0]))
+               if want := "command-line-arguments [c.go]"; got != want {
+                       t.Errorf("oops: got %s, want %s", got, want)
+               }
+       }
+
+       // Wildcards
+       // See StdlibTest for effective test of "std" wildcard.
+       // TODO(adonovan): test "all" returns everything in the current module.
+       {
+               // "..." (subdirectory)
+               initial, err = packages.Load(exported.Config, "golang.org/fake/subdir/...")
+               if err != nil {
+                       t.Fatal(err)
+               }
+               graph, _ = importGraph(initial)
+               wantGraph = `
+* golang.org/fake/subdir/d
+* golang.org/fake/subdir/d [golang.org/fake/subdir/d.test]
+* golang.org/fake/subdir/d.test
+* golang.org/fake/subdir/d_test [golang.org/fake/subdir/d.test]
+* golang.org/fake/subdir/e
+  math/bits
+  golang.org/fake/subdir/d [golang.org/fake/subdir/d.test] -> math/bits
+  golang.org/fake/subdir/d.test -> golang.org/fake/subdir/d [golang.org/fake/subdir/d.test]
+  golang.org/fake/subdir/d.test -> golang.org/fake/subdir/d_test [golang.org/fake/subdir/d.test]
+  golang.org/fake/subdir/d_test [golang.org/fake/subdir/d.test] -> golang.org/fake/subdir/d [golang.org/fake/subdir/d.test]
+`[1:]
+
+               if graph != wantGraph {
+                       t.Errorf("wrong import graph: got <<%s>>, want <<%s>>", graph, wantGraph)
+               }
+       }
+}
+
+func TestLoadImportsTestVariants(t *testing.T) { packagestest.TestAll(t, testLoadImportsTestVariants) }
+func testLoadImportsTestVariants(t *testing.T, exporter packagestest.Exporter) {
+       exported := packagestest.Export(t, exporter, []packagestest.Module{{
+               Name: "golang.org/fake",
+               Files: map[string]interface{}{
+                       "a/a.go":       `package a; import _ "golang.org/fake/b"`,
+                       "b/b.go":       `package b`,
+                       "b/b_test.go":  `package b`,
+                       "b/bx_test.go": `package b_test; import _ "golang.org/fake/a"`,
+               }}})
+       defer exported.Cleanup()
+       exported.Config.Mode = packages.LoadImports
+       exported.Config.Tests = true
+
+       initial, err := packages.Load(exported.Config, "golang.org/fake/a", "golang.org/fake/b")
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       // Check graph topology.
+       graph, _ := importGraph(initial)
+       wantGraph := `
+* golang.org/fake/a
+  golang.org/fake/a [golang.org/fake/b.test]
+* golang.org/fake/b
+* golang.org/fake/b [golang.org/fake/b.test]
+* golang.org/fake/b.test
+* golang.org/fake/b_test [golang.org/fake/b.test]
+  golang.org/fake/a -> golang.org/fake/b
+  golang.org/fake/a [golang.org/fake/b.test] -> golang.org/fake/b [golang.org/fake/b.test]
+  golang.org/fake/b.test -> golang.org/fake/b [golang.org/fake/b.test]
+  golang.org/fake/b.test -> golang.org/fake/b_test [golang.org/fake/b.test]
+  golang.org/fake/b_test [golang.org/fake/b.test] -> golang.org/fake/a [golang.org/fake/b.test]
+`[1:]
+
+       if graph != wantGraph {
+               t.Errorf("wrong import graph: got <<%s>>, want <<%s>>", graph, wantGraph)
+       }
+}
+
+func TestLoadAbsolutePath(t *testing.T) {
+       exported := packagestest.Export(t, packagestest.GOPATH, []packagestest.Module{{
+               Name: "golang.org/gopatha",
+               Files: map[string]interface{}{
+                       "a/a.go": `package a`,
+               }}, {
+               Name: "golang.org/gopathb",
+               Files: map[string]interface{}{
+                       "b/b.go": `package b`,
+               }}})
+       defer exported.Cleanup()
+
+       initial, err := packages.Load(exported.Config, filepath.Dir(exported.File("golang.org/gopatha", "a/a.go")), filepath.Dir(exported.File("golang.org/gopathb", "b/b.go")))
+       if err != nil {
+               t.Fatalf("failed to load imports: %v", err)
+       }
+
+       got := []string{}
+       for _, p := range initial {
+               got = append(got, p.ID)
+       }
+       sort.Strings(got)
+       want := []string{"golang.org/gopatha/a", "golang.org/gopathb/b"}
+       if !reflect.DeepEqual(got, want) {
+               t.Fatalf("initial packages loaded: got [%s], want [%s]", got, want)
+       }
+}
+
+func TestVendorImports(t *testing.T) {
+       exported := packagestest.Export(t, packagestest.GOPATH, []packagestest.Module{{
+               Name: "golang.org/fake",
+               Files: map[string]interface{}{
+                       "a/a.go":          `package a; import _ "b"; import _ "golang.org/fake/c";`,
+                       "a/vendor/b/b.go": `package b; import _ "golang.org/fake/c"`,
+                       "c/c.go":          `package c; import _ "b"`,
+                       "c/vendor/b/b.go": `package b`,
+               }}})
+       defer exported.Cleanup()
+       exported.Config.Mode = packages.LoadImports
+       initial, err := packages.Load(exported.Config, "golang.org/fake/a", "golang.org/fake/c")
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       graph, all := importGraph(initial)
+       wantGraph := `
+* golang.org/fake/a
+  golang.org/fake/a/vendor/b
+* golang.org/fake/c
+  golang.org/fake/c/vendor/b
+  golang.org/fake/a -> golang.org/fake/a/vendor/b
+  golang.org/fake/a -> golang.org/fake/c
+  golang.org/fake/a/vendor/b -> golang.org/fake/c
+  golang.org/fake/c -> golang.org/fake/c/vendor/b
+`[1:]
+       if graph != wantGraph {
+               t.Errorf("wrong import graph: got <<%s>>, want <<%s>>", graph, wantGraph)
+       }
+
+       for _, test := range []struct {
+               pattern     string
+               wantImports string
+       }{
+               {"golang.org/fake/a", "b:golang.org/fake/a/vendor/b golang.org/fake/c:golang.org/fake/c"},
+               {"golang.org/fake/c", "b:golang.org/fake/c/vendor/b"},
+               {"golang.org/fake/a/vendor/b", "golang.org/fake/c:golang.org/fake/c"},
+               {"golang.org/fake/c/vendor/b", ""},
+       } {
+               // Test the import paths.
+               pkg := all[test.pattern]
+               if imports := strings.Join(imports(pkg), " "); imports != test.wantImports {
+                       t.Errorf("package %q: got %s, want %s", test.pattern, imports, test.wantImports)
+               }
+       }
+}
+
+func imports(p *packages.Package) []string {
+       if p == nil {
+               return nil
+       }
+       keys := make([]string, 0, len(p.Imports))
+       for k, v := range p.Imports {
+               keys = append(keys, fmt.Sprintf("%s:%s", k, v.ID))
+       }
+       sort.Strings(keys)
+       return keys
+}
+
+func TestConfigDir(t *testing.T) { packagestest.TestAll(t, testConfigDir) }
+func testConfigDir(t *testing.T, exporter packagestest.Exporter) {
+       exported := packagestest.Export(t, exporter, []packagestest.Module{{
+               Name: "golang.org/fake",
+               Files: map[string]interface{}{
+                       "a/a.go":   `package a; const Name = "a" `,
+                       "a/b/b.go": `package b; const Name = "a/b"`,
+                       "b/b.go":   `package b; const Name = "b"`,
+               }}})
+       defer exported.Cleanup()
+       aDir := filepath.Dir(exported.File("golang.org/fake", "a/a.go"))
+       bDir := filepath.Dir(exported.File("golang.org/fake", "b/b.go"))
+       baseDir := filepath.Dir(aDir)
+
+       for _, test := range []struct {
+               dir     string
+               pattern string
+               want    string // value of Name constant
+               fails   bool
+       }{
+               {dir: bDir, pattern: "golang.org/fake/a", want: `"a"`},
+               {dir: bDir, pattern: "golang.org/fake/b", want: `"b"`},
+               {dir: bDir, pattern: "./a", fails: true},
+               {dir: bDir, pattern: "./b", fails: true},
+               {dir: baseDir, pattern: "golang.org/fake/a", want: `"a"`},
+               {dir: baseDir, pattern: "golang.org/fake/b", want: `"b"`},
+               {dir: baseDir, pattern: "./a", want: `"a"`},
+               {dir: baseDir, pattern: "./b", want: `"b"`},
+               {dir: aDir, pattern: "golang.org/fake/a", want: `"a"`},
+               {dir: aDir, pattern: "golang.org/fake/b", want: `"b"`},
+               {dir: aDir, pattern: "./a", fails: true},
+               {dir: aDir, pattern: "./b", want: `"a/b"`},
+       } {
+               exported.Config.Mode = packages.LoadSyntax // Use LoadSyntax to ensure that files can be opened.
+               exported.Config.Dir = test.dir
+               initial, err := packages.Load(exported.Config, test.pattern)
+               var got string
+               fails := false
+               if err != nil {
+                       fails = true
+               } else if len(initial) > 0 {
+                       if len(initial[0].Errors) > 0 {
+                               fails = true
+                       } else if c := constant(initial[0], "Name"); c != nil {
+                               got = c.Val().String()
+                       }
+               }
+               if got != test.want {
+                       t.Errorf("dir %q, pattern %q: got %s, want %s",
+                               test.dir, test.pattern, got, test.want)
+               }
+               if fails != test.fails {
+                       // TODO: remove when go#28023 is fixed
+                       if test.fails && strings.HasPrefix(test.pattern, "./") && exporter == packagestest.Modules {
+                               // Currently go list in module mode does not handle missing directories correctly.
+                               continue
+                       }
+                       t.Errorf("dir %q, pattern %q: error %v, want %v",
+                               test.dir, test.pattern, fails, test.fails)
+               }
+       }
+}
+
+func TestConfigFlags(t *testing.T) { packagestest.TestAll(t, testConfigFlags) }
+func testConfigFlags(t *testing.T, exporter packagestest.Exporter) {
+       // Test satisfying +build line tags, with -tags flag.
+       exported := packagestest.Export(t, exporter, []packagestest.Module{{
+               Name: "golang.org/fake",
+               Files: map[string]interface{}{
+                       // package a
+                       "a/a.go": `package a; import _ "golang.org/fake/a/b"`,
+                       "a/b.go": `// +build tag
+
+package a`,
+                       "a/c.go": `// +build tag tag2
+
+package a`,
+                       "a/d.go": `// +build tag,tag2
+
+package a`,
+                       // package a/b
+                       "a/b/a.go": `package b`,
+                       "a/b/b.go": `// +build tag
+
+package b`,
+               }}})
+       defer exported.Cleanup()
+
+       for _, test := range []struct {
+               pattern        string
+               tags           []string
+               wantSrcs       string
+               wantImportSrcs string
+       }{
+               {`golang.org/fake/a`, []string{}, "a.go", "a.go"},
+               {`golang.org/fake/a`, []string{`-tags=tag`}, "a.go b.go c.go", "a.go b.go"},
+               {`golang.org/fake/a`, []string{`-tags=tag2`}, "a.go c.go", "a.go"},
+               {`golang.org/fake/a`, []string{`-tags=tag tag2`}, "a.go b.go c.go d.go", "a.go b.go"},
+       } {
+               exported.Config.Mode = packages.LoadImports
+               exported.Config.BuildFlags = test.tags
+
+               initial, err := packages.Load(exported.Config, test.pattern)
+               if err != nil {
+                       t.Error(err)
+                       continue
+               }
+               if len(initial) != 1 {
+                       t.Errorf("test tags %v: pattern %s, expected 1 package, got %d packages.", test.tags, test.pattern, len(initial))
+                       continue
+               }
+               pkg := initial[0]
+               if srcs := strings.Join(srcs(pkg), " "); srcs != test.wantSrcs {
+                       t.Errorf("test tags %v: srcs of package %s = [%s], want [%s]", test.tags, test.pattern, srcs, test.wantSrcs)
+               }
+               for path, ipkg := range pkg.Imports {
+                       if srcs := strings.Join(srcs(ipkg), " "); srcs != test.wantImportSrcs {
+                               t.Errorf("build tags %v: srcs of imported package %s = [%s], want [%s]", test.tags, path, srcs, test.wantImportSrcs)
+                       }
+               }
+
+       }
+}
+
+func TestLoadTypes(t *testing.T) { packagestest.TestAll(t, testLoadTypes) }
+func testLoadTypes(t *testing.T, exporter packagestest.Exporter) {
+       // In LoadTypes and LoadSyntax modes, the compiler will
+       // fail to generate an export data file for c, because it has
+       // a type error.  The loader should fall back loading a and c
+       // from source, but use the export data for b.
+
+       exported := packagestest.Export(t, exporter, []packagestest.Module{{
+               Name: "golang.org/fake",
+               Files: map[string]interface{}{
+                       "a/a.go": `package a; import "golang.org/fake/b"; import "golang.org/fake/c"; const A = "a" + b.B + c.C`,
+                       "b/b.go": `package b; const B = "b"`,
+                       "c/c.go": `package c; const C = "c" + 1`,
+               }}})
+       defer exported.Cleanup()
+
+       exported.Config.Mode = packages.LoadTypes
+       initial, err := packages.Load(exported.Config, "golang.org/fake/a")
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       graph, all := importGraph(initial)
+       wantGraph := `
+* golang.org/fake/a
+  golang.org/fake/b
+  golang.org/fake/c
+  golang.org/fake/a -> golang.org/fake/b
+  golang.org/fake/a -> golang.org/fake/c
+`[1:]
+       if graph != wantGraph {
+               t.Errorf("wrong import graph: got <<%s>>, want <<%s>>", graph, wantGraph)
+       }
+
+       for _, id := range []string{
+               "golang.org/fake/a",
+               "golang.org/fake/b",
+               "golang.org/fake/c",
+       } {
+               p := all[id]
+               if p == nil {
+                       t.Errorf("missing package: %s", id)
+                       continue
+               }
+               if p.Types == nil {
+                       t.Errorf("missing types.Package for %s", p)
+                       continue
+               } else if !p.Types.Complete() {
+                       t.Errorf("incomplete types.Package for %s", p)
+               } else if p.TypesSizes == nil {
+                       t.Errorf("TypesSizes is not filled in for %s", p)
+               }
+
+       }
+}
+
+// TestLoadTypesBits is equivalent to TestLoadTypes except that it only requests
+// the types using the NeedTypes bit.
+func TestLoadTypesBits(t *testing.T) { packagestest.TestAll(t, testLoadTypesBits) }
+func testLoadTypesBits(t *testing.T, exporter packagestest.Exporter) {
+       exported := packagestest.Export(t, exporter, []packagestest.Module{{
+               Name: "golang.org/fake",
+               Files: map[string]interface{}{
+                       "a/a.go": `package a; import "golang.org/fake/b"; const A = "a" + b.B`,
+                       "b/b.go": `package b; import "golang.org/fake/c"; const B = "b" + c.C`,
+                       "c/c.go": `package c; import "golang.org/fake/d"; const C = "c" + d.D`,
+                       "d/d.go": `package d; import "golang.org/fake/e"; const D = "d" + e.E`,
+                       "e/e.go": `package e; import "golang.org/fake/f"; const E = "e" + f.F`,
+                       "f/f.go": `package f; const F = "f"`,
+               }}})
+       defer exported.Cleanup()
+
+       exported.Config.Mode = packages.NeedTypes | packages.NeedImports
+       initial, err := packages.Load(exported.Config, "golang.org/fake/a", "golang.org/fake/c")
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       graph, all := importGraph(initial)
+       wantGraph := `
+* golang.org/fake/a
+  golang.org/fake/b
+* golang.org/fake/c
+  golang.org/fake/d
+  golang.org/fake/e
+  golang.org/fake/f
+  golang.org/fake/a -> golang.org/fake/b
+  golang.org/fake/b -> golang.org/fake/c
+  golang.org/fake/c -> golang.org/fake/d
+  golang.org/fake/d -> golang.org/fake/e
+  golang.org/fake/e -> golang.org/fake/f
+`[1:]
+       if graph != wantGraph {
+               t.Errorf("wrong import graph: got <<%s>>, want <<%s>>", graph, wantGraph)
+       }
+
+       for _, test := range []struct {
+               id string
+       }{
+               {"golang.org/fake/a"},
+               {"golang.org/fake/b"},
+               {"golang.org/fake/c"},
+               {"golang.org/fake/d"},
+               {"golang.org/fake/e"},
+               {"golang.org/fake/f"},
+       } {
+               p := all[test.id]
+               if p == nil {
+                       t.Errorf("missing package: %s", test.id)
+                       continue
+               }
+               if p.Types == nil {
+                       t.Errorf("missing types.Package for %s", p)
+                       continue
+               }
+               // We don't request the syntax, so we shouldn't get it.
+               if p.Syntax != nil {
+                       t.Errorf("Syntax unexpectedly provided for %s", p)
+               }
+               if p.Errors != nil {
+                       t.Errorf("errors in package: %s: %s", p, p.Errors)
+               }
+       }
+
+       // Check value of constant.
+       aA := constant(all["golang.org/fake/a"], "A")
+       if aA == nil {
+               t.Fatalf("a.A: got nil")
+       }
+       if got, want := fmt.Sprintf("%v %v", aA, aA.Val()), `const golang.org/fake/a.A untyped string "abcdef"`; got != want {
+               t.Errorf("a.A: got %s, want %s", got, want)
+       }
+}
+
+func TestLoadSyntaxOK(t *testing.T) { packagestest.TestAll(t, testLoadSyntaxOK) }
+func testLoadSyntaxOK(t *testing.T, exporter packagestest.Exporter) {
+       exported := packagestest.Export(t, exporter, []packagestest.Module{{
+               Name: "golang.org/fake",
+               Files: map[string]interface{}{
+                       "a/a.go": `package a; import "golang.org/fake/b"; const A = "a" + b.B`,
+                       "b/b.go": `package b; import "golang.org/fake/c"; const B = "b" + c.C`,
+                       "c/c.go": `package c; import "golang.org/fake/d"; const C = "c" + d.D`,
+                       "d/d.go": `package d; import "golang.org/fake/e"; const D = "d" + e.E`,
+                       "e/e.go": `package e; import "golang.org/fake/f"; const E = "e" + f.F`,
+                       "f/f.go": `package f; const F = "f"`,
+               }}})
+       defer exported.Cleanup()
+
+       exported.Config.Mode = packages.LoadSyntax
+       initial, err := packages.Load(exported.Config, "golang.org/fake/a", "golang.org/fake/c")
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       graph, all := importGraph(initial)
+       wantGraph := `
+* golang.org/fake/a
+  golang.org/fake/b
+* golang.org/fake/c
+  golang.org/fake/d
+  golang.org/fake/e
+  golang.org/fake/f
+  golang.org/fake/a -> golang.org/fake/b
+  golang.org/fake/b -> golang.org/fake/c
+  golang.org/fake/c -> golang.org/fake/d
+  golang.org/fake/d -> golang.org/fake/e
+  golang.org/fake/e -> golang.org/fake/f
+`[1:]
+       if graph != wantGraph {
+               t.Errorf("wrong import graph: got <<%s>>, want <<%s>>", graph, wantGraph)
+       }
+
+       for _, test := range []struct {
+               id           string
+               wantSyntax   bool
+               wantComplete bool
+       }{
+               {"golang.org/fake/a", true, true},   // source package
+               {"golang.org/fake/b", true, true},   // source package because depends on initial package
+               {"golang.org/fake/c", true, true},   // source package
+               {"golang.org/fake/d", false, true},  // export data package
+               {"golang.org/fake/e", false, false}, // export data package
+               {"golang.org/fake/f", false, false}, // export data package
+       } {
+               // TODO(matloob): LoadSyntax and LoadAllSyntax are now equivalent, wantSyntax and wantComplete
+               // are true for all packages in the transitive dependency set. Add test cases on the individual
+               // Need* fields to check the equivalents on the new API.
+               p := all[test.id]
+               if p == nil {
+                       t.Errorf("missing package: %s", test.id)
+                       continue
+               }
+               if p.Types == nil {
+                       t.Errorf("missing types.Package for %s", p)
+                       continue
+               } else if p.Types.Complete() != test.wantComplete {
+                       if test.wantComplete {
+                               t.Errorf("incomplete types.Package for %s", p)
+                       } else {
+                               t.Errorf("unexpected complete types.Package for %s", p)
+                       }
+               }
+               if (p.Syntax != nil) != test.wantSyntax {
+                       if test.wantSyntax {
+                               t.Errorf("missing ast.Files for %s", p)
+                       } else {
+                               t.Errorf("unexpected ast.Files for for %s", p)
+                       }
+               }
+               if p.Errors != nil {
+                       t.Errorf("errors in package: %s: %s", p, p.Errors)
+               }
+       }
+
+       // Check value of constant.
+       aA := constant(all["golang.org/fake/a"], "A")
+       if aA == nil {
+               t.Fatalf("a.A: got nil")
+       }
+       if got, want := fmt.Sprintf("%v %v", aA, aA.Val()), `const golang.org/fake/a.A untyped string "abcdef"`; got != want {
+               t.Errorf("a.A: got %s, want %s", got, want)
+       }
+}
+
+func TestLoadDiamondTypes(t *testing.T) { packagestest.TestAll(t, testLoadDiamondTypes) }
+func testLoadDiamondTypes(t *testing.T, exporter packagestest.Exporter) {
+       // We make a diamond dependency and check the type d.D is the same through both paths
+       exported := packagestest.Export(t, exporter, []packagestest.Module{{
+               Name: "golang.org/fake",
+               Files: map[string]interface{}{
+                       "a/a.go": `package a; import ("golang.org/fake/b"; "golang.org/fake/c"); var _ = b.B == c.C`,
+                       "b/b.go": `package b; import "golang.org/fake/d"; var B d.D`,
+                       "c/c.go": `package c; import "golang.org/fake/d"; var C d.D`,
+                       "d/d.go": `package d; type D int`,
+               }}})
+       defer exported.Cleanup()
+
+       exported.Config.Mode = packages.LoadSyntax
+       initial, err := packages.Load(exported.Config, "golang.org/fake/a")
+       if err != nil {
+               t.Fatal(err)
+       }
+       packages.Visit(initial, nil, func(pkg *packages.Package) {
+               for _, err := range pkg.Errors {
+                       t.Errorf("package %s: %v", pkg.ID, err)
+               }
+       })
+
+       graph, _ := importGraph(initial)
+       wantGraph := `
+* golang.org/fake/a
+  golang.org/fake/b
+  golang.org/fake/c
+  golang.org/fake/d
+  golang.org/fake/a -> golang.org/fake/b
+  golang.org/fake/a -> golang.org/fake/c
+  golang.org/fake/b -> golang.org/fake/d
+  golang.org/fake/c -> golang.org/fake/d
+`[1:]
+       if graph != wantGraph {
+               t.Errorf("wrong import graph: got <<%s>>, want <<%s>>", graph, wantGraph)
+       }
+}
+
+func TestLoadSyntaxError(t *testing.T) { packagestest.TestAll(t, testLoadSyntaxError) }
+func testLoadSyntaxError(t *testing.T, exporter packagestest.Exporter) {
+       // A type error in a lower-level package (e) prevents go list
+       // from producing export data for all packages that depend on it
+       // [a-e]. Only f should be loaded from export data, and the rest
+       // should be IllTyped.
+       exported := packagestest.Export(t, exporter, []packagestest.Module{{
+               Name: "golang.org/fake",
+               Files: map[string]interface{}{
+                       "a/a.go": `package a; import "golang.org/fake/b"; const A = "a" + b.B`,
+                       "b/b.go": `package b; import "golang.org/fake/c"; const B = "b" + c.C`,
+                       "c/c.go": `package c; import "golang.org/fake/d"; const C = "c" + d.D`,
+                       "d/d.go": `package d; import "golang.org/fake/e"; const D = "d" + e.E`,
+                       "e/e.go": `package e; import "golang.org/fake/f"; const E = "e" + f.F + 1`, // type error
+                       "f/f.go": `package f; const F = "f"`,
+               }}})
+       defer exported.Cleanup()
+
+       exported.Config.Mode = packages.LoadSyntax
+       initial, err := packages.Load(exported.Config, "golang.org/fake/a", "golang.org/fake/c")
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       all := make(map[string]*packages.Package)
+       packages.Visit(initial, nil, func(p *packages.Package) {
+               all[p.ID] = p
+       })
+
+       for _, test := range []struct {
+               id           string
+               wantSyntax   bool
+               wantIllTyped bool
+       }{
+               {"golang.org/fake/a", true, true},
+               {"golang.org/fake/b", true, true},
+               {"golang.org/fake/c", true, true},
+               {"golang.org/fake/d", true, true},
+               {"golang.org/fake/e", true, true},
+               {"golang.org/fake/f", false, false},
+       } {
+               p := all[test.id]
+               if p == nil {
+                       t.Errorf("missing package: %s", test.id)
+                       continue
+               }
+               if p.Types == nil {
+                       t.Errorf("missing types.Package for %s", p)
+                       continue
+               } else if !p.Types.Complete() {
+                       t.Errorf("incomplete types.Package for %s", p)
+               }
+               if (p.Syntax != nil) != test.wantSyntax {
+                       if test.wantSyntax {
+                               t.Errorf("missing ast.Files for %s", test.id)
+                       } else {
+                               t.Errorf("unexpected ast.Files for for %s", test.id)
+                       }
+               }
+               if p.IllTyped != test.wantIllTyped {
+                       t.Errorf("IllTyped was %t for %s", p.IllTyped, test.id)
+               }
+       }
+
+       // Check value of constant.
+       aA := constant(all["golang.org/fake/a"], "A")
+       if aA == nil {
+               t.Fatalf("a.A: got nil")
+       }
+       if got, want := aA.String(), `const golang.org/fake/a.A invalid type`; got != want {
+               t.Errorf("a.A: got %s, want %s", got, want)
+       }
+}
+
+// This function tests use of the ParseFile hook to modify
+// the AST after parsing.
+func TestParseFileModifyAST(t *testing.T) { packagestest.TestAll(t, testParseFileModifyAST) }
+func testParseFileModifyAST(t *testing.T, exporter packagestest.Exporter) {
+       exported := packagestest.Export(t, exporter, []packagestest.Module{{
+               Name: "golang.org/fake",
+               Files: map[string]interface{}{
+                       "a/a.go": `package a; const A = "a" `,
+               }}})
+       defer exported.Cleanup()
+
+       exported.Config.Mode = packages.LoadAllSyntax
+       exported.Config.ParseFile = func(fset *token.FileSet, filename string, src []byte) (*ast.File, error) {
+               const mode = parser.AllErrors | parser.ParseComments
+               f, err := parser.ParseFile(fset, filename, src, mode)
+               // modify AST to change `const A = "a"` to `const A = "b"`
+               spec := f.Decls[0].(*ast.GenDecl).Specs[0].(*ast.ValueSpec)
+               spec.Values[0].(*ast.BasicLit).Value = `"b"`
+               return f, err
+       }
+       initial, err := packages.Load(exported.Config, "golang.org/fake/a")
+       if err != nil {
+               t.Error(err)
+       }
+
+       // Check value of a.A has been set to "b"
+       a := initial[0]
+       got := constant(a, "A").Val().String()
+       if got != `"b"` {
+               t.Errorf("a.A: got %s, want %s", got, `"b"`)
+       }
+}
+
+func TestAdHocPackagesBadImport(t *testing.T) {
+       // This test doesn't use packagestest because we are testing ad-hoc packages,
+       // which are outside of $GOPATH and outside of a module.
+       tmp, err := ioutil.TempDir("", "a")
+       if err != nil {
+               t.Fatal(err)
+       }
+       defer os.RemoveAll(tmp)
+
+       filename := filepath.Join(tmp, "a.go")
+       content := []byte(`package a
+import _ "badimport"
+const A = 1
+`)
+       if err := ioutil.WriteFile(filename, content, 0775); err != nil {
+               t.Fatal(err)
+       }
+
+       // Make sure that the user's value of GO111MODULE does not affect test results.
+       for _, go111module := range []string{"off", "auto", "on"} {
+               config := &packages.Config{
+                       Env:  append(os.Environ(), "GOPACKAGESDRIVER=off", fmt.Sprintf("GO111MODULE=%s", go111module)),
+                       Dir:  tmp,
+                       Mode: packages.LoadAllSyntax,
+                       Logf: t.Logf,
+               }
+               initial, err := packages.Load(config, fmt.Sprintf("file=%s", filename))
+               if err != nil {
+                       t.Error(err)
+               }
+               if len(initial) == 0 {
+                       t.Fatalf("no packages for %s with GO111MODULE=%s", filename, go111module)
+               }
+               // Check value of a.A.
+               a := initial[0]
+               // There's an error because there's a bad import.
+               aA := constant(a, "A")
+               if aA == nil {
+                       t.Errorf("a.A: got nil")
+                       return
+               }
+               got := aA.Val().String()
+               if want := "1"; got != want {
+                       t.Errorf("a.A: got %s, want %s", got, want)
+               }
+       }
+}
+
+func TestLoadAllSyntaxImportErrors(t *testing.T) {
+       packagestest.TestAll(t, testLoadAllSyntaxImportErrors)
+}
+func testLoadAllSyntaxImportErrors(t *testing.T, exporter packagestest.Exporter) {
+       // TODO(matloob): Remove this once go list -e -compiled is fixed.
+       // See https://golang.org/issue/26755
+       t.Skip("go list -compiled -e fails with non-zero exit status for empty packages")
+
+       exported := packagestest.Export(t, exporter, []packagestest.Module{{
+               Name: "golang.org/fake",
+               Files: map[string]interface{}{
+                       "unicycle/unicycle.go": `package unicycle; import _ "unicycle"`,
+                       "bicycle1/bicycle1.go": `package bicycle1; import _ "bicycle2"`,
+                       "bicycle2/bicycle2.go": `package bicycle2; import _ "bicycle1"`,
+                       "bad/bad.go":           `not a package declaration`,
+                       "empty/README.txt":     `not a go file`,
+                       "root/root.go": `package root
+import (
+       _ "bicycle1"
+       _ "unicycle"
+       _ "nonesuch"
+       _ "empty"
+       _ "bad"
+)`,
+               }}})
+       defer exported.Cleanup()
+
+       exported.Config.Mode = packages.LoadAllSyntax
+       initial, err := packages.Load(exported.Config, "root")
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       // Cycle-forming edges are removed from the graph:
+       //      bicycle2 -> bicycle1
+       //      unicycle -> unicycle
+       graph, all := importGraph(initial)
+       wantGraph := `
+  bicycle1
+  bicycle2
+* root
+  unicycle
+  bicycle1 -> bicycle2
+  root -> bicycle1
+  root -> unicycle
+`[1:]
+       if graph != wantGraph {
+               t.Errorf("wrong import graph: got <<%s>>, want <<%s>>", graph, wantGraph)
+       }
+       for _, test := range []struct {
+               id       string
+               wantErrs []string
+       }{
+               {"bicycle1", nil},
+               {"bicycle2", []string{
+                       "could not import bicycle1 (import cycle: [root bicycle1 bicycle2])",
+               }},
+               {"unicycle", []string{
+                       "could not import unicycle (import cycle: [root unicycle])",
+               }},
+               {"root", []string{
+                       `could not import bad (missing package: "bad")`,
+                       `could not import empty (missing package: "empty")`,
+                       `could not import nonesuch (missing package: "nonesuch")`,
+               }},
+       } {
+               p := all[test.id]
+               if p == nil {
+                       t.Errorf("missing package: %s", test.id)
+                       continue
+               }
+               if p.Types == nil {
+                       t.Errorf("missing types.Package for %s", test.id)
+               }
+               if p.Syntax == nil {
+                       t.Errorf("missing ast.Files for %s", test.id)
+               }
+               if !p.IllTyped {
+                       t.Errorf("IllTyped was false for %s", test.id)
+               }
+               if errs := errorMessages(p.Errors); !reflect.DeepEqual(errs, test.wantErrs) {
+                       t.Errorf("in package %s, got errors %s, want %s", p, errs, test.wantErrs)
+               }
+       }
+}
+
+func TestAbsoluteFilenames(t *testing.T) { packagestest.TestAll(t, testAbsoluteFilenames) }
+func testAbsoluteFilenames(t *testing.T, exporter packagestest.Exporter) {
+       exported := packagestest.Export(t, exporter, []packagestest.Module{{
+               Name: "golang.org/fake",
+               Files: map[string]interface{}{
+                       "a/a.go":          `package a; const A = 1`,
+                       "b/b.go":          `package b; import ("golang.org/fake/a"; _ "errors"); var B = a.A`,
+                       "b/vendor/a/a.go": `package a; const A = 1`,
+                       "c/c.go":          `package c; import (_ "golang.org/fake/b"; _ "unsafe")`,
+                       "c/c2.go":         "// +build ignore\n\n" + `package c; import _ "fmt"`,
+                       "subdir/d/d.go":   `package d`,
+                       "subdir/e/d.go":   `package e`,
+                       "e/e.go":          `package main; import _ "golang.org/fake/b"`,
+                       "e/e2.go":         `package main; import _ "golang.org/fake/c"`,
+                       "f/f.go":          `package f`,
+                       "f/f.s":           ``,
+               }}})
+       defer exported.Cleanup()
+       exported.Config.Dir = filepath.Dir(filepath.Dir(exported.File("golang.org/fake", "a/a.go")))
+
+       checkFile := func(filename string) {
+               if !filepath.IsAbs(filename) {
+                       t.Errorf("filename is not absolute: %s", filename)
+               }
+               if _, err := os.Stat(filename); err != nil {
+                       t.Errorf("stat error, %s: %v", filename, err)
+               }
+       }
+
+       for _, test := range []struct {
+               pattern string
+               want    string
+       }{
+               // Import paths
+               {"golang.org/fake/a", "a.go"},
+               {"golang.org/fake/b/vendor/a", "a.go"},
+               {"golang.org/fake/b", "b.go"},
+               {"golang.org/fake/c", "c.go"},
+               {"golang.org/fake/subdir/d", "d.go"},
+               {"golang.org/fake/subdir/e", "d.go"},
+               {"golang.org/fake/e", "e.go e2.go"},
+               {"golang.org/fake/f", "f.go f.s"},
+               // Relative paths
+               {"./a", "a.go"},
+               {"./b/vendor/a", "a.go"},
+               {"./b", "b.go"},
+               {"./c", "c.go"},
+               {"./subdir/d", "d.go"},
+               {"./subdir/e", "d.go"},
+               {"./e", "e.go e2.go"},
+               {"./f", "f.go f.s"},
+       } {
+               exported.Config.Mode = packages.LoadFiles
+               pkgs, err := packages.Load(exported.Config, test.pattern)
+               if err != nil {
+                       t.Errorf("pattern %s: %v", test.pattern, err)
+                       continue
+               }
+
+               if got := strings.Join(srcs(pkgs[0]), " "); got != test.want {
+                       t.Errorf("in package %s, got %s, want %s", test.pattern, got, test.want)
+               }
+
+               // Test that files in all packages exist and are absolute paths.
+               _, all := importGraph(pkgs)
+               for _, pkg := range all {
+                       for _, filename := range pkg.GoFiles {
+                               checkFile(filename)
+                       }
+                       for _, filename := range pkg.OtherFiles {
+                               checkFile(filename)
+                       }
+                       for _, filename := range pkg.IgnoredFiles {
+                               checkFile(filename)
+                       }
+               }
+       }
+}
+
+func TestContains(t *testing.T) { packagestest.TestAll(t, testContains) }
+func testContains(t *testing.T, exporter packagestest.Exporter) {
+       exported := packagestest.Export(t, exporter, []packagestest.Module{{
+               Name: "golang.org/fake",
+               Files: map[string]interface{}{
+                       "a/a.go": `package a; import "golang.org/fake/b"`,
+                       "b/b.go": `package b; import "golang.org/fake/c"`,
+                       "c/c.go": `package c`,
+               }}})
+       defer exported.Cleanup()
+       bFile := exported.File("golang.org/fake", "b/b.go")
+       exported.Config.Mode = packages.LoadImports
+       initial, err := packages.Load(exported.Config, "file="+bFile)
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       graph, _ := importGraph(initial)
+       wantGraph := `
+* golang.org/fake/b
+  golang.org/fake/c
+  golang.org/fake/b -> golang.org/fake/c
+`[1:]
+       if graph != wantGraph {
+               t.Errorf("wrong import graph: got <<%s>>, want <<%s>>", graph, wantGraph)
+       }
+}
+
+// This test ensures that the effective GOARCH variable in the
+// application determines the Sizes function used by the type checker.
+// This behavior is a stop-gap until we make the build system's query
+// tool report the correct sizes function for the actual configuration.
+func TestSizes(t *testing.T) { packagestest.TestAll(t, testSizes) }
+func testSizes(t *testing.T, exporter packagestest.Exporter) {
+       // Only run this test on operating systems that have both an amd64 and 386 port.
+       switch runtime.GOOS {
+       case "linux", "windows", "freebsd", "openbsd", "netbsd", "android":
+       default:
+               t.Skipf("skipping test on %s", runtime.GOOS)
+       }
+
+       exported := packagestest.Export(t, exporter, []packagestest.Module{{
+               Name: "golang.org/fake",
+               Files: map[string]interface{}{
+                       "a/a.go": `package a; import "unsafe"; const WordSize = 8*unsafe.Sizeof(int(0))`,
+               }}})
+       defer exported.Cleanup()
+
+       exported.Config.Mode = packages.LoadSyntax
+       savedEnv := exported.Config.Env
+       for arch, wantWordSize := range map[string]int64{"386": 32, "amd64": 64} {
+               exported.Config.Env = append(savedEnv, "GOARCH="+arch)
+               initial, err := packages.Load(exported.Config, "golang.org/fake/a")
+               if err != nil {
+                       t.Fatal(err)
+               }
+               if packages.PrintErrors(initial) > 0 {
+                       t.Fatal("there were errors")
+               }
+               gotWordSize, _ := constantpkg.Int64Val(constant(initial[0], "WordSize").Val())
+               if gotWordSize != wantWordSize {
+                       t.Errorf("for GOARCH=%s, got word size %d, want %d", arch, gotWordSize, wantWordSize)
+               }
+       }
+}
+
+// TestContainsFallbackSticks ensures that when there are both contains and non-contains queries
+// the decision whether to fallback to the pre-1.11 go list sticks across both sets of calls to
+// go list.
+func TestContainsFallbackSticks(t *testing.T) { packagestest.TestAll(t, testContainsFallbackSticks) }
+func testContainsFallbackSticks(t *testing.T, exporter packagestest.Exporter) {
+       exported := packagestest.Export(t, exporter, []packagestest.Module{{
+               Name: "golang.org/fake",
+               Files: map[string]interface{}{
+                       "a/a.go": `package a; import "golang.org/fake/b"`,
+                       "b/b.go": `package b; import "golang.org/fake/c"`,
+                       "c/c.go": `package c`,
+               }}})
+       defer exported.Cleanup()
+
+       exported.Config.Mode = packages.LoadImports
+       bFile := exported.File("golang.org/fake", "b/b.go")
+       initial, err := packages.Load(exported.Config, "golang.org/fake/a", "file="+bFile)
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       graph, _ := importGraph(initial)
+       wantGraph := `
+* golang.org/fake/a
+* golang.org/fake/b
+  golang.org/fake/c
+  golang.org/fake/a -> golang.org/fake/b
+  golang.org/fake/b -> golang.org/fake/c
+`[1:]
+       if graph != wantGraph {
+               t.Errorf("wrong import graph: got <<%s>>, want <<%s>>", graph, wantGraph)
+       }
+}
+
+// Test that Load with no patterns is equivalent to loading "." via the golist
+// driver.
+func TestNoPatterns(t *testing.T) { packagestest.TestAll(t, testNoPatterns) }
+func testNoPatterns(t *testing.T, exporter packagestest.Exporter) {
+       exported := packagestest.Export(t, exporter, []packagestest.Module{{
+               Name: "golang.org/fake",
+               Files: map[string]interface{}{
+                       "a/a.go":   `package a;`,
+                       "a/b/b.go": `package b;`,
+               }}})
+       defer exported.Cleanup()
+
+       aDir := filepath.Dir(exported.File("golang.org/fake", "a/a.go"))
+       exported.Config.Dir = aDir
+
+       initial, err := packages.Load(exported.Config)
+       if err != nil {
+               t.Fatal(err)
+       }
+       if len(initial) != 1 || initial[0].Name != "a" {
+               t.Fatalf(`Load() = %v, wanted just the package in the current directory`, initial)
+       }
+}
+
+func TestJSON(t *testing.T) { packagestest.TestAll(t, testJSON) }
+func testJSON(t *testing.T, exporter packagestest.Exporter) {
+       //TODO: add in some errors
+       exported := packagestest.Export(t, exporter, []packagestest.Module{{
+               Name: "golang.org/fake",
+               Files: map[string]interface{}{
+                       "a/a.go": `package a; const A = 1`,
+                       "b/b.go": `package b; import "golang.org/fake/a"; var B = a.A`,
+                       "c/c.go": `package c; import "golang.org/fake/b" ; var C = b.B`,
+                       "d/d.go": `package d; import "golang.org/fake/b" ; var D = b.B`,
+               }}})
+       defer exported.Cleanup()
+
+       exported.Config.Mode = packages.LoadImports
+       initial, err := packages.Load(exported.Config, "golang.org/fake/c", "golang.org/fake/d")
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       // Visit and print all packages.
+       buf := &bytes.Buffer{}
+       enc := json.NewEncoder(buf)
+       enc.SetIndent("", "\t")
+       packages.Visit(initial, nil, func(pkg *packages.Package) {
+               // trim the source lists for stable results
+               pkg.GoFiles = cleanPaths(pkg.GoFiles)
+               pkg.CompiledGoFiles = cleanPaths(pkg.CompiledGoFiles)
+               pkg.OtherFiles = cleanPaths(pkg.OtherFiles)
+               pkg.IgnoredFiles = cleanPaths(pkg.IgnoredFiles)
+               if err := enc.Encode(pkg); err != nil {
+                       t.Fatal(err)
+               }
+       })
+
+       wantJSON := `
+{
+       "ID": "golang.org/fake/a",
+       "Name": "a",
+       "PkgPath": "golang.org/fake/a",
+       "GoFiles": [
+               "a.go"
+       ],
+       "CompiledGoFiles": [
+               "a.go"
+       ]
+}
+{
+       "ID": "golang.org/fake/b",
+       "Name": "b",
+       "PkgPath": "golang.org/fake/b",
+       "GoFiles": [
+               "b.go"
+       ],
+       "CompiledGoFiles": [
+               "b.go"
+       ],
+       "Imports": {
+               "golang.org/fake/a": "golang.org/fake/a"
+       }
+}
+{
+       "ID": "golang.org/fake/c",
+       "Name": "c",
+       "PkgPath": "golang.org/fake/c",
+       "GoFiles": [
+               "c.go"
+       ],
+       "CompiledGoFiles": [
+               "c.go"
+       ],
+       "Imports": {
+               "golang.org/fake/b": "golang.org/fake/b"
+       }
+}
+{
+       "ID": "golang.org/fake/d",
+       "Name": "d",
+       "PkgPath": "golang.org/fake/d",
+       "GoFiles": [
+               "d.go"
+       ],
+       "CompiledGoFiles": [
+               "d.go"
+       ],
+       "Imports": {
+               "golang.org/fake/b": "golang.org/fake/b"
+       }
+}
+`[1:]
+
+       if buf.String() != wantJSON {
+               t.Errorf("wrong JSON: got <<%s>>, want <<%s>>", buf.String(), wantJSON)
+       }
+       // now decode it again
+       var decoded []*packages.Package
+       dec := json.NewDecoder(buf)
+       for dec.More() {
+               p := new(packages.Package)
+               if err := dec.Decode(p); err != nil {
+                       t.Fatal(err)
+               }
+               decoded = append(decoded, p)
+       }
+       if len(decoded) != 4 {
+               t.Fatalf("got %d packages, want 4", len(decoded))
+       }
+       for i, want := range []*packages.Package{{
+               ID:   "golang.org/fake/a",
+               Name: "a",
+       }, {
+               ID:   "golang.org/fake/b",
+               Name: "b",
+               Imports: map[string]*packages.Package{
+                       "golang.org/fake/a": {ID: "golang.org/fake/a"},
+               },
+       }, {
+               ID:   "golang.org/fake/c",
+               Name: "c",
+               Imports: map[string]*packages.Package{
+                       "golang.org/fake/b": {ID: "golang.org/fake/b"},
+               },
+       }, {
+               ID:   "golang.org/fake/d",
+               Name: "d",
+               Imports: map[string]*packages.Package{
+                       "golang.org/fake/b": {ID: "golang.org/fake/b"},
+               },
+       }} {
+               got := decoded[i]
+               if got.ID != want.ID {
+                       t.Errorf("Package %d has ID %q want %q", i, got.ID, want.ID)
+               }
+               if got.Name != want.Name {
+                       t.Errorf("Package %q has Name %q want %q", got.ID, got.Name, want.Name)
+               }
+               if len(got.Imports) != len(want.Imports) {
+                       t.Errorf("Package %q has %d imports want %d", got.ID, len(got.Imports), len(want.Imports))
+                       continue
+               }
+               for path, ipkg := range got.Imports {
+                       if want.Imports[path] == nil {
+                               t.Errorf("Package %q has unexpected import %q", got.ID, path)
+                               continue
+                       }
+                       if want.Imports[path].ID != ipkg.ID {
+                               t.Errorf("Package %q import %q is %q want %q", got.ID, path, ipkg.ID, want.Imports[path].ID)
+                       }
+               }
+       }
+}
+
+func TestRejectInvalidQueries(t *testing.T) {
+       queries := []string{"key=", "key=value"}
+       cfg := &packages.Config{
+               Mode: packages.LoadImports,
+               Env:  append(os.Environ(), "GO111MODULE=off", "GOPACKAGESDRIVER=off"),
+       }
+       for _, q := range queries {
+               if _, err := packages.Load(cfg, q); err == nil {
+                       t.Errorf("packages.Load(%q) succeeded. Expected \"invalid query type\" error", q)
+               } else if !strings.Contains(err.Error(), "invalid query type") {
+                       t.Errorf("packages.Load(%q): got error %v, want \"invalid query type\" error", q, err)
+               }
+       }
+}
+
+func TestPatternPassthrough(t *testing.T) { packagestest.TestAll(t, testPatternPassthrough) }
+func testPatternPassthrough(t *testing.T, exporter packagestest.Exporter) {
+       exported := packagestest.Export(t, exporter, []packagestest.Module{{
+               Name: "golang.org/fake",
+               Files: map[string]interface{}{
+                       "a/a.go": `package a;`,
+               }}})
+       defer exported.Cleanup()
+
+       initial, err := packages.Load(exported.Config, "pattern=a")
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       graph, _ := importGraph(initial)
+       wantGraph := `
+* a
+`[1:]
+       if graph != wantGraph {
+               t.Errorf("wrong import graph: got <<%s>>, want <<%s>>", graph, wantGraph)
+       }
+
+}
+
+func TestConfigDefaultEnv(t *testing.T) { packagestest.TestAll(t, testConfigDefaultEnv) }
+func testConfigDefaultEnv(t *testing.T, exporter packagestest.Exporter) {
+       const driverJSON = `{
+  "Roots": ["gopackagesdriver"],
+  "Packages": [{"ID": "gopackagesdriver", "Name": "gopackagesdriver"}]
+}`
+       var (
+               pathKey      string
+               driverScript packagestest.Writer
+       )
+       switch runtime.GOOS {
+       case "android":
+               t.Skip("doesn't run on android")
+       case "windows":
+               // TODO(jayconrod): write an equivalent batch script for windows.
+               // Hint: "type" can be used to read a file to stdout.
+               t.Skip("test requires sh")
+       case "plan9":
+               pathKey = "path"
+               driverScript = packagestest.Script(`#!/bin/rc
+
+cat <<'EOF'
+` + driverJSON + `
+EOF
+`)
+       default:
+               pathKey = "PATH"
+               driverScript = packagestest.Script(`#!/bin/sh
+
+cat - <<'EOF'
+` + driverJSON + `
+EOF
+`)
+       }
+       exported := packagestest.Export(t, exporter, []packagestest.Module{{
+               Name: "golang.org/fake",
+               Files: map[string]interface{}{
+                       "bin/gopackagesdriver": driverScript,
+                       "golist/golist.go":     "package golist",
+               }}})
+       defer exported.Cleanup()
+       driver := exported.File("golang.org/fake", "bin/gopackagesdriver")
+       binDir := filepath.Dir(driver)
+       if err := os.Chmod(driver, 0755); err != nil {
+               t.Fatal(err)
+       }
+
+       path, ok := os.LookupEnv(pathKey)
+       var pathWithDriver string
+       if ok {
+               pathWithDriver = binDir + string(os.PathListSeparator) + path
+       } else {
+               pathWithDriver = binDir
+       }
+       for _, test := range []struct {
+               desc    string
+               path    string
+               driver  string
+               wantIDs string
+       }{
+               {
+                       desc:    "driver_off",
+                       path:    pathWithDriver,
+                       driver:  "off",
+                       wantIDs: "[golist]",
+               }, {
+                       desc:    "driver_unset",
+                       path:    pathWithDriver,
+                       driver:  "",
+                       wantIDs: "[gopackagesdriver]",
+               }, {
+                       desc:    "driver_set",
+                       path:    "",
+                       driver:  driver,
+                       wantIDs: "[gopackagesdriver]",
+               },
+       } {
+               t.Run(test.desc, func(t *testing.T) {
+                       oldPath := os.Getenv(pathKey)
+                       os.Setenv(pathKey, test.path)
+                       defer os.Setenv(pathKey, oldPath)
+                       // Clone exported.Config
+                       config := exported.Config
+                       config.Env = append([]string{}, exported.Config.Env...)
+                       config.Env = append(config.Env, "GOPACKAGESDRIVER="+test.driver)
+                       pkgs, err := packages.Load(exported.Config, "golist")
+                       if err != nil {
+                               t.Fatal(err)
+                       }
+
+                       gotIds := make([]string, len(pkgs))
+                       for i, pkg := range pkgs {
+                               gotIds[i] = pkg.ID
+                       }
+                       if fmt.Sprint(pkgs) != test.wantIDs {
+                               t.Errorf("got %v; want %v", gotIds, test.wantIDs)
+                       }
+               })
+       }
+}
+
+// This test that a simple x test package layout loads correctly.
+// There was a bug in go list where it returned multiple copies of the same
+// package (specifically in this case of golang.org/fake/a), and this triggered
+// a bug in go/packages where it would leave an empty entry in the root package
+// list. This would then cause a nil pointer crash.
+// This bug was triggered by the simple package layout below, and thus this
+// test will make sure the bug remains fixed.
+func TestBasicXTest(t *testing.T) { packagestest.TestAll(t, testBasicXTest) }
+func testBasicXTest(t *testing.T, exporter packagestest.Exporter) {
+       exported := packagestest.Export(t, exporter, []packagestest.Module{{
+               Name: "golang.org/fake",
+               Files: map[string]interface{}{
+                       "a/a.go":      `package a;`,
+                       "a/a_test.go": `package a_test;`,
+               }}})
+       defer exported.Cleanup()
+
+       exported.Config.Mode = packages.LoadFiles
+       exported.Config.Tests = true
+       _, err := packages.Load(exported.Config, "golang.org/fake/a")
+       if err != nil {
+               t.Fatal(err)
+       }
+}
+
+func TestErrorMissingFile(t *testing.T) { packagestest.TestAll(t, testErrorMissingFile) }
+func testErrorMissingFile(t *testing.T, exporter packagestest.Exporter) {
+       exported := packagestest.Export(t, exporter, []packagestest.Module{{
+               Name: "golang.org/fake",
+               Files: map[string]interface{}{
+                       "a/a_test.go": `package a;`,
+               }}})
+       defer exported.Cleanup()
+
+       exported.Config.Mode = packages.LoadSyntax
+       exported.Config.Tests = false
+       pkgs, err := packages.Load(exported.Config, "missing.go")
+       if err != nil {
+               t.Fatal(err)
+       }
+       if len(pkgs) == 0 && runtime.GOOS == "windows" {
+               t.Skip("Issue #31344: the ad-hoc command-line-arguments package isn't created on windows")
+       }
+       if len(pkgs) != 1 || (pkgs[0].PkgPath != "command-line-arguments" && pkgs[0].PkgPath != "missing.go") {
+               t.Fatalf("packages.Load: want [command-line-arguments] or [missing.go], got %v", pkgs)
+       }
+       if len(pkgs[0].Errors) == 0 {
+               t.Errorf("result of Load: want package with errors, got none: %+v", pkgs[0])
+       }
+}
+
+func TestReturnErrorWhenUsingNonGoFiles(t *testing.T) {
+       packagestest.TestAll(t, testReturnErrorWhenUsingNonGoFiles)
+}
+func testReturnErrorWhenUsingNonGoFiles(t *testing.T, exporter packagestest.Exporter) {
+       exported := packagestest.Export(t, exporter, []packagestest.Module{{
+               Name: "golang.org/gopatha",
+               Files: map[string]interface{}{
+                       "a/a.go": `package a`,
+               }}, {
+               Name: "golang.org/gopathb",
+               Files: map[string]interface{}{
+                       "b/b.c": `package b`,
+               }}})
+       defer exported.Cleanup()
+       config := packages.Config{Env: append(os.Environ(), "GOPACKAGESDRIVER=off")}
+       pkgs, err := packages.Load(&config, "b/b.c")
+       if err != nil {
+               return
+       }
+       // Go <1.14 calls the package command-line-arguments while Go 1.14+ uses the file names.
+       if len(pkgs) != 1 || (pkgs[0].PkgPath != "command-line-arguments" && pkgs[0].PkgPath != "b/b.c") {
+               t.Fatalf("packages.Load: want [command-line-arguments] or [b/b.c], got %v", pkgs)
+       }
+       if len(pkgs[0].Errors) != 1 {
+               t.Fatalf("result of Load: want package with one error, got: %+v", pkgs[0])
+       }
+}
+
+func TestReturnErrorWhenUsingGoFilesInMultipleDirectories(t *testing.T) {
+       packagestest.TestAll(t, testReturnErrorWhenUsingGoFilesInMultipleDirectories)
+}
+func testReturnErrorWhenUsingGoFilesInMultipleDirectories(t *testing.T, exporter packagestest.Exporter) {
+       exported := packagestest.Export(t, exporter, []packagestest.Module{{
+               Name: "golang.org/gopatha",
+               Files: map[string]interface{}{
+                       "a/a.go": `package a`,
+                       "b/b.go": `package b`,
+               }}})
+       defer exported.Cleanup()
+       want := "named files must all be in one directory"
+       pkgs, err := packages.Load(exported.Config, exported.File("golang.org/gopatha", "a/a.go"), exported.File("golang.org/gopatha", "b/b.go"))
+       if err != nil {
+               // Check if the error returned is the one we expected.
+               if !strings.Contains(err.Error(), want) {
+                       t.Fatalf("want error message: %s, got: %s", want, err.Error())
+               }
+               return
+       }
+       if len(pkgs) != 1 || pkgs[0].PkgPath != "command-line-arguments" {
+               t.Fatalf("packages.Load: want [command-line-arguments], got %v", pkgs)
+       }
+       if len(pkgs[0].Errors) != 1 {
+               t.Fatalf("result of Load: want package with one error, got: %+v", pkgs[0])
+       }
+       got := pkgs[0].Errors[0].Error()
+       if !strings.Contains(got, want) {
+               t.Fatalf("want error message: %s, got: %s", want, got)
+       }
+}
+
+func TestReturnErrorForUnexpectedDirectoryLayout(t *testing.T) {
+       packagestest.TestAll(t, testReturnErrorForUnexpectedDirectoryLayout)
+}
+func testReturnErrorForUnexpectedDirectoryLayout(t *testing.T, exporter packagestest.Exporter) {
+       exported := packagestest.Export(t, exporter, []packagestest.Module{{
+               Name: "golang.org/gopatha",
+               Files: map[string]interface{}{
+                       "a/testdata/a.go": `package a; import _ "b"`,
+                       "a/vendor/b/b.go": `package b; import _ "fmt"`,
+               }}})
+       defer exported.Cleanup()
+       want := "unexpected directory layout"
+       // triggering this error requires a relative package path
+       exported.Config.Dir = filepath.Dir(exported.File("golang.org/gopatha", "a/testdata/a.go"))
+       pkgs, err := packages.Load(exported.Config, ".")
+
+       // This error doesn't seem to occur in module mode; so only
+       // complain if we get zero packages while also getting no error.
+       if err == nil {
+               if len(pkgs) == 0 {
+                       // TODO(dh): we'll need to expand on the error check if/when Go stops emitting this error
+                       t.Fatalf("want error, got nil")
+               }
+               return
+       }
+       // Check if the error returned is the one we expected.
+       if !strings.Contains(err.Error(), want) {
+               t.Fatalf("want error message: %s, got: %s", want, err.Error())
+       }
+}
+
+func TestMissingDependency(t *testing.T) { packagestest.TestAll(t, testMissingDependency) }
+func testMissingDependency(t *testing.T, exporter packagestest.Exporter) {
+       exported := packagestest.Export(t, exporter, []packagestest.Module{{
+               Name: "golang.org/fake",
+               Files: map[string]interface{}{
+                       "a/a.go": `package a; import _ "this/package/doesnt/exist"`,
+               }}})
+       defer exported.Cleanup()
+
+       exported.Config.Mode = packages.LoadAllSyntax
+       pkgs, err := packages.Load(exported.Config, "golang.org/fake/a")
+       if err != nil {
+               t.Fatal(err)
+       }
+       if len(pkgs) != 1 && pkgs[0].PkgPath != "golang.org/fake/a" {
+               t.Fatalf("packages.Load: want [golang.org/fake/a], got %v", pkgs)
+       }
+       if len(pkgs[0].Errors) == 0 {
+               t.Errorf("result of Load: want package with errors, got none: %+v", pkgs[0])
+       }
+}
+
+func TestAdHocContains(t *testing.T) { packagestest.TestAll(t, testAdHocContains) }
+func testAdHocContains(t *testing.T, exporter packagestest.Exporter) {
+       exported := packagestest.Export(t, exporter, []packagestest.Module{{
+               Name: "golang.org/fake",
+               Files: map[string]interface{}{
+                       "a/a.go": `package a;`,
+               }}})
+       defer exported.Cleanup()
+
+       tmpfile, err := ioutil.TempFile("", "adhoc*.go")
+       filename := tmpfile.Name()
+       if err != nil {
+               t.Fatal(err)
+       }
+       fmt.Fprint(tmpfile, `package main; import "fmt"; func main() { fmt.Println("time for coffee") }`)
+       if err := tmpfile.Close(); err != nil {
+               t.Fatal(err)
+       }
+
+       defer func() {
+               if err := os.Remove(filename); err != nil {
+                       t.Fatal(err)
+               }
+       }()
+
+       exported.Config.Mode = packages.NeedImports | packages.NeedFiles
+       pkgs, err := packages.Load(exported.Config, "file="+filename)
+       if err != nil {
+               t.Fatal(err)
+       }
+       if len(pkgs) != 1 && pkgs[0].PkgPath != "command-line-arguments" {
+               t.Fatalf("packages.Load: want [command-line-arguments], got %v", pkgs)
+       }
+       pkg := pkgs[0]
+       if _, ok := pkg.Imports["fmt"]; !ok || len(pkg.Imports) != 1 {
+               t.Fatalf("Imports of loaded package: want [fmt], got %v", pkg.Imports)
+       }
+       if len(pkg.GoFiles) != 1 || pkg.GoFiles[0] != filename {
+               t.Fatalf("GoFiles of loaded package: want [%s], got %v", filename, pkg.GoFiles)
+       }
+}
+
+func TestCgoNoCcompiler(t *testing.T) { packagestest.TestAll(t, testCgoNoCcompiler) }
+func testCgoNoCcompiler(t *testing.T, exporter packagestest.Exporter) {
+       testenv.NeedsTool(t, "cgo")
+       exported := packagestest.Export(t, exporter, []packagestest.Module{{
+               Name: "golang.org/fake",
+               Files: map[string]interface{}{
+                       "a/a.go": `package a
+import "net/http"
+const A = http.MethodGet
+`,
+               }}})
+       defer exported.Cleanup()
+
+       // Explicitly enable cgo but configure a nonexistent C compiler.
+       exported.Config.Env = append(exported.Config.Env, "CGO_ENABLED=1", "CC=doesnotexist")
+       exported.Config.Mode = packages.LoadAllSyntax
+       initial, err := packages.Load(exported.Config, "golang.org/fake/a")
+
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       // Check value of a.A.
+       a := initial[0]
+       aA := constant(a, "A")
+       if aA == nil {
+               t.Fatalf("a.A: got nil")
+       }
+       got := aA.Val().String()
+       if got != "\"GET\"" {
+               t.Errorf("a.A: got %s, want %s", got, "\"GET\"")
+       }
+}
+
+func TestCgoMissingFile(t *testing.T) { packagestest.TestAll(t, testCgoMissingFile) }
+func testCgoMissingFile(t *testing.T, exporter packagestest.Exporter) {
+       testenv.NeedsTool(t, "cgo")
+       exported := packagestest.Export(t, exporter, []packagestest.Module{{
+               Name: "golang.org/fake",
+               Files: map[string]interface{}{
+                       "a/a.go": `package a
+
+// #include "foo.h"
+import "C"
+
+const A = 4
+`,
+               }}})
+       defer exported.Cleanup()
+
+       // Explicitly enable cgo.
+       exported.Config.Env = append(exported.Config.Env, "CGO_ENABLED=1")
+       exported.Config.Mode = packages.LoadAllSyntax
+       initial, err := packages.Load(exported.Config, "golang.org/fake/a")
+
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       // Check value of a.A.
+       a := initial[0]
+       aA := constant(a, "A")
+       if aA == nil {
+               t.Fatalf("a.A: got nil")
+       }
+       got := aA.Val().String()
+       if got != "4" {
+               t.Errorf("a.A: got %s, want %s", got, "4")
+       }
+}
+
+func TestLoadImportsC(t *testing.T) {
+       // This test checks that when a package depends on the
+       // test variant of "syscall", "unsafe", or "runtime/cgo", that dependency
+       // is not removed when those packages are added when it imports "C".
+       //
+       // For this test to work, the external test of syscall must have a dependency
+       // on net, and net must import "syscall" and "C".
+       if runtime.GOOS == "windows" {
+               t.Skipf("skipping on windows; packages on windows do not satisfy conditions for test.")
+       }
+       if runtime.GOOS == "plan9" {
+               // See https://golang.org/issue/27100.
+               t.Skip(`skipping on plan9; for some reason "net [syscall.test]" is not loaded`)
+       }
+       testenv.NeedsGoPackages(t)
+
+       cfg := &packages.Config{
+               Context: testCtx,
+               Mode:    packages.LoadImports,
+               Tests:   true,
+       }
+       initial, err := packages.Load(cfg, "syscall", "net")
+       if err != nil {
+               t.Fatalf("failed to load imports: %v", err)
+       }
+
+       _, all := importGraph(initial)
+
+       for _, test := range []struct {
+               pattern    string
+               wantImport string // an import to check for
+       }{
+               {"net", "syscall:syscall"},
+               {"net [syscall.test]", "syscall:syscall [syscall.test]"},
+               {"syscall_test [syscall.test]", "net:net [syscall.test]"},
+       } {
+               // Test the import paths.
+               pkg := all[test.pattern]
+               if pkg == nil {
+                       t.Errorf("package %q not loaded", test.pattern)
+                       continue
+               }
+               if imports := strings.Join(imports(pkg), " "); !strings.Contains(imports, test.wantImport) {
+                       t.Errorf("package %q: got \n%s, \nwant to have %s", test.pattern, imports, test.wantImport)
+               }
+       }
+}
+
+func TestCgoNoSyntax(t *testing.T) {
+       packagestest.TestAll(t, testCgoNoSyntax)
+}
+func testCgoNoSyntax(t *testing.T, exporter packagestest.Exporter) {
+       testenv.NeedsTool(t, "cgo")
+
+       exported := packagestest.Export(t, exporter, []packagestest.Module{{
+               Name: "golang.org/fake",
+               Files: map[string]interface{}{
+                       "c/c.go": `package c; import "C"`,
+               },
+       }})
+
+       // Explicitly enable cgo.
+       exported.Config.Env = append(exported.Config.Env, "CGO_ENABLED=1")
+
+       modes := []packages.LoadMode{
+               packages.NeedTypes,
+               packages.NeedName | packages.NeedTypes,
+               packages.NeedName | packages.NeedTypes | packages.NeedImports,
+               packages.NeedName | packages.NeedTypes | packages.NeedImports | packages.NeedDeps,
+               packages.NeedName | packages.NeedImports,
+       }
+       for _, mode := range modes {
+               t.Run(fmt.Sprint(mode), func(t *testing.T) {
+                       exported.Config.Mode = mode
+                       pkgs, err := packages.Load(exported.Config, "golang.org/fake/c")
+                       if err != nil {
+                               t.Fatal(err)
+                       }
+                       if len(pkgs) != 1 {
+                               t.Fatalf("Expected 1 package, got %v", pkgs)
+                       }
+                       pkg := pkgs[0]
+                       if len(pkg.Errors) != 0 {
+                               t.Fatalf("Expected no errors in package, got %v", pkg.Errors)
+                       }
+               })
+       }
+}
+
+func TestCgoBadPkgConfig(t *testing.T) {
+       packagestest.TestAll(t, testCgoBadPkgConfig)
+}
+func testCgoBadPkgConfig(t *testing.T, exporter packagestest.Exporter) {
+       testenv.NeedsTool(t, "cgo")
+
+       exported := packagestest.Export(t, exporter, []packagestest.Module{{
+               Name: "golang.org/fake",
+               Files: map[string]interface{}{
+                       "c/c.go": `package c
+
+// #cgo pkg-config: --cflags --  foo
+import "C"`,
+               },
+       }})
+
+       dir := buildFakePkgconfig(t, exported.Config.Env)
+       defer os.RemoveAll(dir)
+       env := exported.Config.Env
+       for i, v := range env {
+               if strings.HasPrefix(v, "PATH=") {
+                       env[i] = "PATH=" + dir + string(os.PathListSeparator) + v[len("PATH="):]
+               }
+       }
+
+       exported.Config.Env = append(exported.Config.Env, "CGO_ENABLED=1")
+
+       exported.Config.Mode = packages.NeedName | packages.NeedCompiledGoFiles
+       pkgs, err := packages.Load(exported.Config, "golang.org/fake/c")
+       if err != nil {
+               t.Fatal(err)
+       }
+       if len(pkgs) != 1 {
+               t.Fatalf("Expected 1 package, got %v", pkgs)
+       }
+       if pkgs[0].Name != "c" {
+               t.Fatalf("Expected package to have name \"c\", got %q", pkgs[0].Name)
+       }
+}
+
+func buildFakePkgconfig(t *testing.T, env []string) string {
+       tmpdir, err := ioutil.TempDir("", "fakepkgconfig")
+       if err != nil {
+               t.Fatal(err)
+       }
+       err = ioutil.WriteFile(filepath.Join(tmpdir, "pkg-config.go"), []byte(`
+package main
+
+import "fmt"
+import "os"
+
+func main() {
+       fmt.Fprintln(os.Stderr, "bad")
+       os.Exit(2)
+}
+`), 0644)
+       if err != nil {
+               os.RemoveAll(tmpdir)
+               t.Fatal(err)
+       }
+       cmd := exec.Command("go", "build", "-o", "pkg-config", "pkg-config.go")
+       cmd.Dir = tmpdir
+       cmd.Env = env
+
+       if b, err := cmd.CombinedOutput(); err != nil {
+               os.RemoveAll(tmpdir)
+               fmt.Println(os.Environ())
+               t.Log(string(b))
+               t.Fatal(err)
+       }
+       return tmpdir
+}
+
+func TestIssue32814(t *testing.T) { packagestest.TestAll(t, testIssue32814) }
+func testIssue32814(t *testing.T, exporter packagestest.Exporter) {
+       exported := packagestest.Export(t, exporter, []packagestest.Module{{
+               Name:  "golang.org/fake",
+               Files: map[string]interface{}{}}})
+       defer exported.Cleanup()
+
+       exported.Config.Mode = packages.NeedName | packages.NeedTypes | packages.NeedSyntax | packages.NeedTypesInfo | packages.NeedTypesSizes
+       pkgs, err := packages.Load(exported.Config, "fmt")
+
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       if len(pkgs) != 1 && pkgs[0].PkgPath != "fmt" {
+               t.Fatalf("packages.Load: want [fmt], got %v", pkgs)
+       }
+       pkg := pkgs[0]
+       if len(pkg.Errors) != 0 {
+               t.Fatalf("Errors for fmt pkg: got %v, want none", pkg.Errors)
+       }
+       if !pkg.Types.Complete() {
+               t.Fatalf("Types.Complete() for fmt pkg: got %v, want true", pkgs[0].Types.Complete())
+
+       }
+}
+
+func TestLoadTypesInfoWithoutNeedDeps(t *testing.T) {
+       packagestest.TestAll(t, testLoadTypesInfoWithoutNeedDeps)
+}
+func testLoadTypesInfoWithoutNeedDeps(t *testing.T, exporter packagestest.Exporter) {
+       exported := packagestest.Export(t, exporter, []packagestest.Module{{
+               Name: "golang.org/fake",
+               Files: map[string]interface{}{
+                       "a/a.go": `package a; import _ "golang.org/fake/b"`,
+                       "b/b.go": `package b`,
+               }}})
+       defer exported.Cleanup()
+
+       exported.Config.Mode = packages.NeedTypes | packages.NeedTypesInfo | packages.NeedImports
+       pkgs, err := packages.Load(exported.Config, "golang.org/fake/a")
+       if err != nil {
+               t.Fatal(err)
+       }
+       pkg := pkgs[0]
+       if pkg.IllTyped {
+               t.Fatal("Loaded package is ill typed")
+       }
+       const expectedImport = "golang.org/fake/b"
+       if _, ok := pkg.Imports[expectedImport]; !ok || len(pkg.Imports) != 1 {
+               t.Fatalf("Imports of loaded package: want [%s], got %v", expectedImport, pkg.Imports)
+       }
+}
+
+func TestLoadWithNeedDeps(t *testing.T) {
+       packagestest.TestAll(t, testLoadWithNeedDeps)
+}
+func testLoadWithNeedDeps(t *testing.T, exporter packagestest.Exporter) {
+       exported := packagestest.Export(t, exporter, []packagestest.Module{{
+               Name: "golang.org/fake",
+               Files: map[string]interface{}{
+                       "a/a.go": `package a; import _ "golang.org/fake/b"`,
+                       "b/b.go": `package b; import _ "golang.org/fake/c"`,
+                       "c/c.go": `package c`,
+               }}})
+       defer exported.Cleanup()
+
+       exported.Config.Mode = packages.NeedTypes | packages.NeedTypesInfo | packages.NeedImports | packages.NeedDeps
+       pkgs, err := packages.Load(exported.Config, "golang.org/fake/a")
+       if err != nil {
+               t.Fatal(err)
+       }
+       if len(pkgs) != 1 {
+               t.Fatalf("Expected 1 package, got %d", len(pkgs))
+       }
+
+       pkgA := pkgs[0]
+       if pkgA.IllTyped {
+               t.Fatal("Loaded package is ill typed")
+       }
+
+       pkgB := pkgA.Imports["golang.org/fake/b"]
+       if pkgB == nil || len(pkgA.Imports) != 1 {
+               t.Fatalf("Imports of loaded package 'a' are invalid: %v", pkgA.Imports)
+       }
+       if pkgB.Types == nil || !pkgB.Types.Complete() || pkgB.TypesInfo == nil {
+               t.Fatalf("Types of package 'b' are nil or incomplete: %v, %v", pkgB.Types, pkgB.TypesInfo)
+       }
+
+       pkgC := pkgB.Imports["golang.org/fake/c"]
+       if pkgC == nil || len(pkgB.Imports) != 1 {
+               t.Fatalf("Imports of loaded package 'c' are invalid: %v", pkgB.Imports)
+       }
+       if pkgC.Types == nil || !pkgC.Types.Complete() || pkgC.TypesInfo == nil {
+               t.Fatalf("Types of package 'b' are nil or incomplete: %v, %v", pkgC.Types, pkgC.TypesInfo)
+       }
+}
+
+func TestImpliedLoadMode(t *testing.T) {
+       packagestest.TestAll(t, testImpliedLoadMode)
+}
+func testImpliedLoadMode(t *testing.T, exporter packagestest.Exporter) {
+       exported := packagestest.Export(t, exporter, []packagestest.Module{{
+               Name: "golang.org/fake",
+               Files: map[string]interface{}{
+                       "a/a.go": `package a; import _ "golang.org/fake/b"`,
+                       "b/b.go": `package b`,
+               }}})
+       defer exported.Cleanup()
+
+       exported.Config.Mode = packages.NeedTypes | packages.NeedTypesInfo
+       pkgs, err := packages.Load(exported.Config, "golang.org/fake/a")
+       if err != nil {
+               t.Fatal(err)
+       }
+       if len(pkgs) != 1 {
+               t.Fatalf("Expected 1 package, got %d", len(pkgs))
+       }
+
+       pkg := pkgs[0]
+       if pkg.IllTyped {
+               t.Fatalf("Loaded package is ill typed: %v", pkg.Errors)
+       }
+
+       // Check that packages.NeedTypesInfo worked well.
+       if !pkg.Types.Complete() {
+               t.Fatalf("Loaded package types are incomplete")
+       }
+
+       // Check that implied packages.NeedImports by packages.NeedTypesInfo
+       // didn't add Imports.
+       if len(pkg.Imports) != 0 {
+               t.Fatalf("Package imports weren't requested but were returned: %v", pkg.Imports)
+       }
+}
+
+func TestIssue35331(t *testing.T) {
+       packagestest.TestAll(t, testIssue35331)
+}
+func testIssue35331(t *testing.T, exporter packagestest.Exporter) {
+       exported := packagestest.Export(t, exporter, []packagestest.Module{{
+               Name: "golang.org/fake",
+       }})
+       defer exported.Cleanup()
+
+       exported.Config.Mode = packages.NeedName | packages.NeedFiles | packages.NeedCompiledGoFiles |
+               packages.NeedImports | packages.NeedDeps | packages.NeedSyntax
+       exported.Config.Tests = false
+       pkgs, err := packages.Load(exported.Config, "strconv")
+       if err != nil {
+               t.Fatal(err)
+       }
+       if len(pkgs) != 1 {
+               t.Fatalf("Expected 1 package, got %v", pkgs)
+       }
+       packages.Visit(pkgs, func(pkg *packages.Package) bool {
+               if len(pkg.Errors) > 0 {
+                       t.Errorf("Expected no errors in package %q, got %v", pkg.ID, pkg.Errors)
+               }
+               if len(pkg.Syntax) == 0 && pkg.ID != "unsafe" {
+                       t.Errorf("Expected syntax on package %q, got none.", pkg.ID)
+               }
+               return true
+       }, nil)
+}
+
+func TestMultiplePackageVersionsIssue36188(t *testing.T) {
+       packagestest.TestAll(t, testMultiplePackageVersionsIssue36188)
+}
+
+func testMultiplePackageVersionsIssue36188(t *testing.T, exporter packagestest.Exporter) {
+       exported := packagestest.Export(t, exporter, []packagestest.Module{{
+               Name: "golang.org/fake",
+               Files: map[string]interface{}{
+                       "a/a.go": `package a; import _ "golang.org/fake/b"`,
+                       "b/b.go": `package main`,
+               }}})
+       pkgs, err := packages.Load(exported.Config, "golang.org/fake/a", "golang.org/fake/b")
+       if err != nil {
+               t.Fatal(err)
+       }
+       sort.Slice(pkgs, func(i, j int) bool { return pkgs[i].ID < pkgs[j].ID })
+       if len(pkgs) != 2 {
+               t.Fatalf("expected two packages, got %v", pkgs)
+       }
+       if pkgs[0].ID != "golang.org/fake/a" && pkgs[1].ID != "golang.org/fake/b" {
+               t.Fatalf(`expected (sorted) IDs "golang.org/fake/a" and "golang.org/fake/b", got %q and %q`,
+                       pkgs[0].ID, pkgs[1].ID)
+       }
+       if pkgs[0].Errors == nil {
+               t.Errorf(`expected error on package "golang.org/fake/a", got none`)
+       }
+       if pkgs[1].Errors != nil {
+               t.Errorf(`expected no errors on package "golang.org/fake/b", got %v`, pkgs[1].Errors)
+       }
+       defer exported.Cleanup()
+}
+
+func TestLoadModeStrings(t *testing.T) {
+       testcases := []struct {
+               mode     packages.LoadMode
+               expected string
+       }{
+               {
+                       packages.LoadMode(0),
+                       "LoadMode(0)",
+               },
+               {
+                       packages.NeedName,
+                       "LoadMode(NeedName)",
+               },
+               {
+                       packages.NeedFiles,
+                       "LoadMode(NeedFiles)",
+               },
+               {
+                       packages.NeedCompiledGoFiles,
+                       "LoadMode(NeedCompiledGoFiles)",
+               },
+               {
+                       packages.NeedImports,
+                       "LoadMode(NeedImports)",
+               },
+               {
+                       packages.NeedDeps,
+                       "LoadMode(NeedDeps)",
+               },
+               {
+                       packages.NeedExportsFile,
+                       "LoadMode(NeedExportsFile)",
+               },
+               {
+                       packages.NeedTypes,
+                       "LoadMode(NeedTypes)",
+               },
+               {
+                       packages.NeedSyntax,
+                       "LoadMode(NeedSyntax)",
+               },
+               {
+                       packages.NeedTypesInfo,
+                       "LoadMode(NeedTypesInfo)",
+               },
+               {
+                       packages.NeedTypesSizes,
+                       "LoadMode(NeedTypesSizes)",
+               },
+               {
+                       packages.NeedName | packages.NeedExportsFile,
+                       "LoadMode(NeedName|NeedExportsFile)",
+               },
+               {
+                       packages.NeedName | packages.NeedFiles | packages.NeedCompiledGoFiles | packages.NeedImports | packages.NeedDeps | packages.NeedExportsFile | packages.NeedTypes | packages.NeedSyntax | packages.NeedTypesInfo | packages.NeedTypesSizes,
+                       "LoadMode(NeedName|NeedFiles|NeedCompiledGoFiles|NeedImports|NeedDeps|NeedExportsFile|NeedTypes|NeedSyntax|NeedTypesInfo|NeedTypesSizes)",
+               },
+               {
+                       packages.NeedName | 8192,
+                       "LoadMode(NeedName|Unknown)",
+               },
+               {
+                       4096,
+                       "LoadMode(Unknown)",
+               },
+       }
+
+       for tcInd, tc := range testcases {
+               t.Run(fmt.Sprintf("test-%d", tcInd), func(t *testing.T) {
+                       actual := tc.mode.String()
+                       if tc.expected != actual {
+                               t.Errorf("want %#v, got %#v", tc.expected, actual)
+                       }
+               })
+       }
+}
+
+func TestCycleImportStack(t *testing.T) {
+       packagestest.TestAll(t, testCycleImportStack)
+}
+func testCycleImportStack(t *testing.T, exporter packagestest.Exporter) {
+       exported := packagestest.Export(t, exporter, []packagestest.Module{{
+               Name: "golang.org/fake",
+               Files: map[string]interface{}{
+                       "a/a.go": `package a; import _ "golang.org/fake/b"`,
+                       "b/b.go": `package b; import _ "golang.org/fake/a"`,
+               }}})
+       defer exported.Cleanup()
+
+       exported.Config.Mode = packages.NeedName | packages.NeedImports
+       pkgs, err := packages.Load(exported.Config, "golang.org/fake/a")
+       if err != nil {
+               t.Fatal(err)
+       }
+       if len(pkgs) != 1 {
+               t.Fatalf("Expected 1 package, got %v", pkgs)
+       }
+       pkg := pkgs[0]
+       if len(pkg.Errors) != 1 {
+               t.Fatalf("Expected one error in package, got %v", pkg.Errors)
+       }
+       expected := "import cycle not allowed: import stack: [golang.org/fake/a golang.org/fake/b golang.org/fake/a]"
+       if pkg.Errors[0].Msg != expected {
+               t.Fatalf("Expected error %q, got %q", expected, pkg.Errors[0].Msg)
+       }
+}
+
+func TestForTestField(t *testing.T) {
+       packagestest.TestAll(t, testForTestField)
+}
+func testForTestField(t *testing.T, exporter packagestest.Exporter) {
+       exported := packagestest.Export(t, exporter, []packagestest.Module{{
+               Name: "golang.org/fake",
+               Files: map[string]interface{}{
+                       "a/a.go":      `package a; func hello() {};`,
+                       "a/a_test.go": `package a; import "testing"; func TestA1(t *testing.T) {};`,
+                       "a/x_test.go": `package a_test; import "testing"; func TestA2(t *testing.T) {};`,
+               }}})
+       defer exported.Cleanup()
+
+       // Add overlays to make sure they don't affect anything.
+       exported.Config.Overlay = map[string][]byte{
+               "a/a_test.go": []byte(`package a; import "testing"; func TestA1(t *testing.T) { hello(); };`),
+               "a/x_test.go": []byte(`package a_test; import "testing"; func TestA2(t *testing.T) { hello(); };`),
+       }
+       exported.Config.Tests = true
+       exported.Config.Mode = packages.NeedName | packages.NeedImports
+       forTest := "golang.org/fake/a"
+       pkgs, err := packages.Load(exported.Config, forTest)
+       if err != nil {
+               t.Fatal(err)
+       }
+       if len(pkgs) != 4 {
+               t.Errorf("expected 4 packages, got %v", len(pkgs))
+       }
+       for _, pkg := range pkgs {
+               var hasTestFile bool
+               for _, f := range pkg.CompiledGoFiles {
+                       if strings.Contains(f, "a_test.go") || strings.Contains(f, "x_test.go") {
+                               hasTestFile = true
+                               break
+                       }
+               }
+               if !hasTestFile {
+                       continue
+               }
+               got := packagesinternal.GetForTest(pkg)
+               if got != forTest {
+                       t.Errorf("expected %q, got %q", forTest, got)
+               }
+       }
+}
+
+func TestIssue37529(t *testing.T) {
+       packagestest.TestAll(t, testIssue37529)
+}
+func testIssue37529(t *testing.T, exporter packagestest.Exporter) {
+       // Tests #37529. When automatic vendoring is triggered, and we try to determine
+       // the module root dir for a new overlay package, we previously would do a go list -m all,
+       // which is incompatible with automatic vendoring.
+
+       exported := packagestest.Export(t, exporter, []packagestest.Module{{
+               Name: "golang.org/fake",
+               Files: map[string]interface{}{
+                       "c/c2.go":             `package c`,
+                       "a/a.go":              `package a; import "b.com/b"; const A = b.B`,
+                       "vendor/b.com/b/b.go": `package b; const B = 4`,
+               }}})
+       rootDir := filepath.Dir(filepath.Dir(exported.File("golang.org/fake", "a/a.go")))
+       exported.Config.Overlay = map[string][]byte{
+               filepath.Join(rootDir, "c/c.go"): []byte(`package c; import "golang.org/fake/a"; const C = a.A`),
+       }
+       exported.Config.Env = append(exported.Config.Env, "GOFLAGS=-mod=vendor")
+       exported.Config.Mode = packages.LoadAllSyntax
+
+       defer exported.Cleanup()
+
+       initial, err := packages.Load(exported.Config, "golang.org/fake/c")
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       // Check value of a.A.
+       a := initial[0]
+       aA := constant(a, "C")
+       if aA == nil {
+               t.Fatalf("a.A: got nil")
+       }
+       got := aA.Val().String()
+       if got != "4" {
+               t.Errorf("a.A: got %s, want %s", got, "4")
+       }
+}
+
+func TestIssue37098(t *testing.T) { packagestest.TestAll(t, testIssue37098) }
+func testIssue37098(t *testing.T, exporter packagestest.Exporter) {
+       // packages.Load should only return Go sources in
+       // (*Package).CompiledGoFiles.  This tests #37098, where using SWIG to
+       // causes C++ sources to be inadvertently included in
+       // (*Package).CompiledGoFiles.
+       t.Skip("Issue #37098: SWIG causes generated C++ sources in CompiledGoFiles")
+
+       // Create a fake package with an empty Go source, and a SWIG interface
+       // file.
+       exported := packagestest.Export(t, exporter, []packagestest.Module{{
+               Name: "golang.org/fake",
+               Files: map[string]interface{}{
+                       // The "package" statement must be included for SWIG sources to
+                       // be generated.
+                       "a/a.go":      "package a",
+                       "a/a.swigcxx": "",
+               }}})
+       defer exported.Cleanup()
+
+       initial, err := packages.Load(exported.Config, "golang.org/fake/a")
+       if err != nil {
+               t.Fatalf("failed to load the package: %v", err)
+       }
+       // Try and parse each of the files
+       for _, pkg := range initial {
+               for _, file := range pkg.CompiledGoFiles {
+
+                       // Validate that each file can be parsed as a Go source.
+                       fset := token.NewFileSet()
+                       _, err := parser.ParseFile(fset, file, nil, parser.ImportsOnly)
+                       if err != nil {
+                               t.Errorf("Failed to parse file '%s' as a Go source: %v", file, err)
+
+                               contents, err := ioutil.ReadFile(file)
+                               if err != nil {
+                                       t.Fatalf("Failed to read the un-parsable file '%s': %v", file, err)
+                               }
+
+                               // Print out some of the un-parsable file to aid in debugging.
+                               n := len(contents)
+
+                               // Don't print the whole file if it is too large.
+                               const maxBytes = 1000
+                               if n > maxBytes {
+                                       n = maxBytes
+                               }
+
+                               t.Logf("First %d bytes of un-parsable file: %s", n, contents[:n])
+                       }
+               }
+       }
+}
+
+// TestInvalidFilesInXTest checks the fix for golang/go#37971 in Go 1.15.
+func TestInvalidFilesInXTest(t *testing.T) { packagestest.TestAll(t, testInvalidFilesInXTest) }
+func testInvalidFilesInXTest(t *testing.T, exporter packagestest.Exporter) {
+       testenv.NeedsGo1Point(t, 15)
+       exported := packagestest.Export(t, exporter, []packagestest.Module{
+               {
+                       Name: "golang.org/fake",
+                       Files: map[string]interface{}{
+                               "d/d.go":      `package d; import "net/http"; const d = http.MethodGet; func Get() string { return d; }`,
+                               "d/d2.go":     ``, // invalid file
+                               "d/d_test.go": `package d_test; import "testing"; import "golang.org/fake/d"; func TestD(t *testing.T) { d.Get(); }`,
+                       },
+               },
+       })
+       defer exported.Cleanup()
+
+       exported.Config.Mode = packages.NeedName | packages.NeedFiles
+       exported.Config.Tests = true
+
+       initial, err := packages.Load(exported.Config, "golang.org/fake/d")
+       if err != nil {
+               t.Fatal(err)
+       }
+       if len(initial) != 3 {
+               t.Errorf("expected 3 packages, got %d", len(initial))
+       }
+}
+
+func TestTypecheckCgo(t *testing.T) { packagestest.TestAll(t, testTypecheckCgo) }
+func testTypecheckCgo(t *testing.T, exporter packagestest.Exporter) {
+       testenv.NeedsGo1Point(t, 15)
+       testenv.NeedsTool(t, "cgo")
+
+       const cgo = `package cgo
+               import "C"
+
+               func Example() {
+                       C.CString("hi")
+               }
+       `
+       exported := packagestest.Export(t, exporter, []packagestest.Module{
+               {
+                       Name: "golang.org/fake",
+                       Files: map[string]interface{}{
+                               "cgo/cgo.go": cgo,
+                       },
+               },
+       })
+       defer exported.Cleanup()
+
+       exported.Config.Mode = packages.NeedFiles | packages.NeedCompiledGoFiles |
+               packages.NeedSyntax | packages.NeedDeps | packages.NeedTypes |
+               packages.LoadMode(packagesinternal.TypecheckCgo)
+
+       initial, err := packages.Load(exported.Config, "golang.org/fake/cgo")
+       if err != nil {
+               t.Fatal(err)
+       }
+       pkg := initial[0]
+       if len(pkg.Errors) != 0 {
+               t.Fatalf("package has errors: %v", pkg.Errors)
+       }
+
+       expos := pkg.Types.Scope().Lookup("Example").Pos()
+       fname := pkg.Fset.File(expos).Name()
+       if !strings.HasSuffix(fname, "cgo.go") {
+               t.Errorf("position for cgo package was loaded from %v, wanted cgo.go", fname)
+       }
+}
+
+func TestModule(t *testing.T) {
+       packagestest.TestAll(t, testModule)
+}
+func testModule(t *testing.T, exporter packagestest.Exporter) {
+       exported := packagestest.Export(t, exporter, []packagestest.Module{{
+               Name:  "golang.org/fake",
+               Files: map[string]interface{}{"a/a.go": `package a`}}})
+       exported.Config.Mode = packages.NeedModule
+       rootDir := filepath.Dir(filepath.Dir(exported.File("golang.org/fake", "a/a.go")))
+
+       initial, err := packages.Load(exported.Config, "golang.org/fake/a")
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       if len(initial) != 1 {
+               t.Fatal("want exactly one package, got ", initial)
+       }
+       a := initial[0]
+       switch exported.Exporter.Name() {
+       case "GOPATH":
+               if a.Module != nil {
+                       t.Fatal("package.Module: want nil, got ", a.Module)
+               }
+       case "Modules":
+               // Make sure Modules field is set, and spot check a few of its fields.
+               if a.Module == nil {
+                       t.Fatal("package.Module: want non-nil, got nil")
+               }
+               if a.Module.Path != "golang.org/fake" {
+                       t.Fatalf("package.Modile.Path: want \"golang.org/fake\", got %q", a.Module.Path)
+               }
+               if a.Module.GoMod != filepath.Join(rootDir, "go.mod") {
+                       t.Fatalf("package.Module.GoMod: want %q, got %q", filepath.Join(rootDir, "go.mod"), a.Module.GoMod)
+               }
+       default:
+               t.Fatalf("Expected exporter to be GOPATH or Modules, got %v", exported.Exporter.Name())
+       }
+}
+
+func TestExternal_NotHandled(t *testing.T) {
+       packagestest.TestAll(t, testExternal_NotHandled)
+}
+func testExternal_NotHandled(t *testing.T, exporter packagestest.Exporter) {
+       testenv.NeedsGoBuild(t)
+
+       tempdir, err := ioutil.TempDir("", "testexternal")
+       if err != nil {
+               t.Fatal(err)
+       }
+       defer os.RemoveAll(tempdir)
+
+       exported := packagestest.Export(t, exporter, []packagestest.Module{{
+               Name: "golang.org/fake",
+               Files: map[string]interface{}{
+                       "a/a.go": `package a`,
+                       "empty_driver/main.go": `package main
+
+import (
+       "fmt"
+       "io/ioutil"
+       "os"
+)
+
+func main() {
+       ioutil.ReadAll(os.Stdin)
+       fmt.Println("{}")
+}
+`,
+                       "nothandled_driver/main.go": `package main
+
+import (
+       "fmt"
+       "io/ioutil"
+       "os"
+)
+
+func main() {
+       ioutil.ReadAll(os.Stdin)
+       fmt.Println("{\"NotHandled\": true}")
+}
+`,
+               }}})
+       baseEnv := exported.Config.Env
+
+       // As a control, create a fake driver that always returns an empty response.
+       emptyDriverPath := filepath.Join(tempdir, "empty_driver.exe") // Add .exe because Windows expects it.
+       cmd := exec.Command("go", "build", "-o", emptyDriverPath, "golang.org/fake/empty_driver")
+       cmd.Env = baseEnv
+       cmd.Dir = exported.Config.Dir
+       if b, err := cmd.CombinedOutput(); err != nil {
+               t.Log(string(b))
+               t.Fatal(err)
+       }
+
+       exported.Config.Env = append(append([]string{}, baseEnv...), "GOPACKAGESDRIVER="+emptyDriverPath)
+       initial, err := packages.Load(exported.Config, "golang.org/fake/a")
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       if len(initial) != 0 {
+               t.Errorf("package.Load with empty driver: want [], got %v", initial)
+       }
+
+       // Create a fake driver that always returns a NotHandled response.
+       notHandledDriverPath := filepath.Join(tempdir, "nothandled_driver.exe")
+       cmd = exec.Command("go", "build", "-o", notHandledDriverPath, "golang.org/fake/nothandled_driver")
+       cmd.Env = baseEnv
+       cmd.Dir = exported.Config.Dir
+       if b, err := cmd.CombinedOutput(); err != nil {
+               t.Log(string(b))
+               t.Fatal(err)
+       }
+
+       exported.Config.Env = append(append([]string{}, baseEnv...), "GOPACKAGESDRIVER="+notHandledDriverPath)
+       initial, err = packages.Load(exported.Config, "golang.org/fake/a")
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       if len(initial) != 1 || initial[0].PkgPath != "golang.org/fake/a" {
+               t.Errorf("package.Load: want [golang.org/fake/a], got %v", initial)
+       }
+}
+
+func TestInvalidPackageName(t *testing.T) {
+       packagestest.TestAll(t, testInvalidPackageName)
+}
+
+func testInvalidPackageName(t *testing.T, exporter packagestest.Exporter) {
+       testenv.NeedsGo1Point(t, 15)
+
+       exported := packagestest.Export(t, exporter, []packagestest.Module{{
+               Name: "golang.org/fake",
+               Files: map[string]interface{}{
+                       "main.go": `package default
+
+func main() {
+}
+`,
+               },
+       }})
+       defer exported.Cleanup()
+
+       initial, err := packages.Load(exported.Config, "golang.org/fake")
+       if err != nil {
+               t.Fatal(err)
+       }
+       pkg := initial[0]
+       if len(pkg.CompiledGoFiles) != 1 {
+               t.Fatalf("expected 1 Go file in package %s, got %v", pkg.ID, len(pkg.CompiledGoFiles))
+       }
+}
+
+func errorMessages(errors []packages.Error) []string {
+       var msgs []string
+       for _, err := range errors {
+               msgs = append(msgs, err.Msg)
+       }
+       return msgs
+}
+
+func srcs(p *packages.Package) []string {
+       return cleanPaths(append(p.GoFiles[:len(p.GoFiles):len(p.GoFiles)], p.OtherFiles...))
+}
+
+// cleanPaths attempts to reduce path names to stable forms
+func cleanPaths(paths []string) []string {
+       result := make([]string, len(paths))
+       for i, src := range paths {
+               // If the source file doesn't have an extension like .go or .s,
+               // it comes from GOCACHE. The names there aren't predictable.
+               name := filepath.Base(src)
+               if !strings.Contains(name, ".") {
+                       result[i] = fmt.Sprintf("%d.go", i) // make cache names predictable
+               } else {
+                       result[i] = name
+               }
+       }
+       return result
+}
+
+// importGraph returns the import graph as a user-friendly string,
+// and a map containing all packages keyed by ID.
+func importGraph(initial []*packages.Package) (string, map[string]*packages.Package) {
+       out := new(bytes.Buffer)
+
+       initialSet := make(map[*packages.Package]bool)
+       for _, p := range initial {
+               initialSet[p] = true
+       }
+
+       // We can't use Visit because we need to prune
+       // the traversal of specific edges, not just nodes.
+       var nodes, edges []string
+       res := make(map[string]*packages.Package)
+       seen := make(map[*packages.Package]bool)
+       var visit func(p *packages.Package)
+       visit = func(p *packages.Package) {
+               if !seen[p] {
+                       seen[p] = true
+                       if res[p.ID] != nil {
+                               panic("duplicate ID: " + p.ID)
+                       }
+                       res[p.ID] = p
+
+                       star := ' ' // mark initial packages with a star
+                       if initialSet[p] {
+                               star = '*'
+                       }
+                       nodes = append(nodes, fmt.Sprintf("%c %s", star, p.ID))
+
+                       // To avoid a lot of noise,
+                       // we prune uninteresting dependencies of testmain packages,
+                       // which we identify by this import:
+                       isTestMain := p.Imports["testing/internal/testdeps"] != nil
+
+                       for _, imp := range p.Imports {
+                               if isTestMain {
+                                       switch imp.ID {
+                                       case "os", "reflect", "testing", "testing/internal/testdeps":
+                                               continue
+                                       }
+                               }
+                               // math/bits took on a dependency on unsafe in 1.12, which breaks some
+                               // tests. As a short term hack, prune that edge.
+                               // ditto for ("errors", "internal/reflectlite") in 1.13.
+                               // TODO(matloob): think of a cleaner solution, or remove math/bits from the test.
+                               if p.ID == "math/bits" && imp.ID == "unsafe" {
+                                       continue
+                               }
+                               edges = append(edges, fmt.Sprintf("%s -> %s", p, imp))
+                               visit(imp)
+                       }
+               }
+       }
+       for _, p := range initial {
+               visit(p)
+       }
+
+       // Sort, ignoring leading optional star prefix.
+       sort.Slice(nodes, func(i, j int) bool { return nodes[i][2:] < nodes[j][2:] })
+       for _, node := range nodes {
+               fmt.Fprintf(out, "%s\n", node)
+       }
+
+       sort.Strings(edges)
+       for _, edge := range edges {
+               fmt.Fprintf(out, "  %s\n", edge)
+       }
+
+       return out.String(), res
+}
+
+func constant(p *packages.Package, name string) *types.Const {
+       if p == nil || p.Types == nil {
+               return nil
+       }
+       c := p.Types.Scope().Lookup(name)
+       if c == nil {
+               return nil
+       }
+       return c.(*types.Const)
+}
+
+func copyAll(srcPath, dstPath string) error {
+       return filepath.Walk(srcPath, func(path string, info os.FileInfo, _ error) error {
+               if info.IsDir() {
+                       return nil
+               }
+               contents, err := ioutil.ReadFile(path)
+               if err != nil {
+                       return err
+               }
+               rel, err := filepath.Rel(srcPath, path)
+               if err != nil {
+                       return err
+               }
+               dstFilePath := strings.Replace(filepath.Join(dstPath, rel), "definitelynot_go.mod", "go.mod", -1)
+               if err := os.MkdirAll(filepath.Dir(dstFilePath), 0755); err != nil {
+                       return err
+               }
+               if err := ioutil.WriteFile(dstFilePath, contents, 0644); err != nil {
+                       return err
+               }
+               return nil
+       })
+}