github.com/cockroachdb/tools@v0.0.0-20230222021103-a6d27438930d/go/packages/packages_test.go (about)

     1  // Copyright 2018 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package packages_test
     6  
     7  import (
     8  	"bytes"
     9  	"context"
    10  	"encoding/json"
    11  	"flag"
    12  	"fmt"
    13  	"go/ast"
    14  	constantpkg "go/constant"
    15  	"go/parser"
    16  	"go/token"
    17  	"go/types"
    18  	"io/ioutil"
    19  	"os"
    20  	"os/exec"
    21  	"path/filepath"
    22  	"reflect"
    23  	"runtime"
    24  	"sort"
    25  	"strings"
    26  	"testing"
    27  	"time"
    28  
    29  	"golang.org/x/tools/go/packages"
    30  	"golang.org/x/tools/go/packages/packagestest"
    31  	"golang.org/x/tools/internal/packagesinternal"
    32  	"golang.org/x/tools/internal/testenv"
    33  )
    34  
    35  // testCtx is canceled when the test binary is about to time out.
    36  //
    37  // If https://golang.org/issue/28135 is accepted, uses of this variable in test
    38  // functions should be replaced by t.Context().
    39  var testCtx = context.Background()
    40  
    41  func TestMain(m *testing.M) {
    42  	testenv.ExitIfSmallMachine()
    43  
    44  	timeoutFlag := flag.Lookup("test.timeout")
    45  	if timeoutFlag != nil {
    46  		if d := timeoutFlag.Value.(flag.Getter).Get().(time.Duration); d != 0 {
    47  			aBitShorter := d * 95 / 100
    48  			var cancel context.CancelFunc
    49  			testCtx, cancel = context.WithTimeout(testCtx, aBitShorter)
    50  			defer cancel()
    51  		}
    52  	}
    53  
    54  	os.Exit(m.Run())
    55  }
    56  
    57  func skipIfShort(t *testing.T, reason string) {
    58  	if testing.Short() {
    59  		t.Skipf("skipping slow test in short mode: %s", reason)
    60  	}
    61  }
    62  
    63  // testAllOrModulesParallel tests f, in parallel, against all packagestest
    64  // exporters in long mode, but only against the Modules exporter in short mode.
    65  func testAllOrModulesParallel(t *testing.T, f func(*testing.T, packagestest.Exporter)) {
    66  	t.Parallel()
    67  	packagestest.TestAll(t, func(t *testing.T, exporter packagestest.Exporter) {
    68  		t.Helper()
    69  
    70  		switch exporter.Name() {
    71  		case "Modules":
    72  		case "GOPATH":
    73  			if testing.Short() {
    74  				t.Skipf("skipping GOPATH test in short mode")
    75  			}
    76  		default:
    77  			t.Fatalf("unexpected exporter %q", exporter.Name())
    78  		}
    79  
    80  		t.Parallel()
    81  		f(t, exporter)
    82  	})
    83  }
    84  
    85  // TODO(adonovan): more test cases to write:
    86  //
    87  // - When the tests fail, make them print a 'cd & load' command
    88  //   that will allow the maintainer to interact with the failing scenario.
    89  // - errors in go-list metadata
    90  // - a foo.test package that cannot be built for some reason (e.g.
    91  //   import error) will result in a JSON blob with no name and a
    92  //   nonexistent testmain file in GoFiles. Test that we handle this
    93  //   gracefully.
    94  // - test more Flags.
    95  //
    96  // LoadSyntax & LoadAllSyntax modes:
    97  //   - Fset may be user-supplied or not.
    98  //   - Packages.Info is correctly set.
    99  //   - typechecker configuration is honored
   100  //   - import cycles are gracefully handled in type checker.
   101  //   - test typechecking of generated test main and cgo.
   102  
   103  // The zero-value of Config has LoadFiles mode.
   104  func TestLoadZeroConfig(t *testing.T) {
   105  	testenv.NeedsGoPackages(t)
   106  	t.Parallel()
   107  
   108  	initial, err := packages.Load(nil, "hash")
   109  	if err != nil {
   110  		t.Fatal(err)
   111  	}
   112  	if len(initial) != 1 {
   113  		t.Fatalf("got %s, want [hash]", initial)
   114  	}
   115  	hash := initial[0]
   116  	// Even though the hash package has imports,
   117  	// they are not reported.
   118  	got := fmt.Sprintf("srcs=%v imports=%v", srcs(hash), hash.Imports)
   119  	want := "srcs=[hash.go] imports=map[]"
   120  	if got != want {
   121  		t.Fatalf("got %s, want %s", got, want)
   122  	}
   123  }
   124  
   125  func TestLoadImportsGraph(t *testing.T) { testAllOrModulesParallel(t, testLoadImportsGraph) }
   126  func testLoadImportsGraph(t *testing.T, exporter packagestest.Exporter) {
   127  	exported := packagestest.Export(t, exporter, []packagestest.Module{{
   128  		Name: "golang.org/fake",
   129  		Files: map[string]interface{}{
   130  			"a/a.go":             `package a; const A = 1`,
   131  			"b/b.go":             `package b; import ("golang.org/fake/a"; _ "container/list"); var B = a.A`,
   132  			"c/c.go":             `package c; import (_ "golang.org/fake/b"; _ "unsafe")`,
   133  			"c/c2.go":            "// +build ignore\n\n" + `package c; import _ "fmt"`,
   134  			"subdir/d/d.go":      `package d`,
   135  			"subdir/d/d_test.go": `package d; import _ "math/bits"`,
   136  			"subdir/d/x_test.go": `package d_test; import _ "golang.org/fake/subdir/d"`, // TODO(adonovan): test bad import here
   137  			"subdir/e/d.go":      `package e`,
   138  			"e/e.go":             `package main; import _ "golang.org/fake/b"`,
   139  			"e/e2.go":            `package main; import _ "golang.org/fake/c"`,
   140  			"f/f.go":             `package f`,
   141  		}}})
   142  	defer exported.Cleanup()
   143  	exported.Config.Mode = packages.LoadImports
   144  	initial, err := packages.Load(exported.Config, "golang.org/fake/c", "golang.org/fake/subdir/d", "golang.org/fake/e")
   145  	if err != nil {
   146  		t.Fatal(err)
   147  	}
   148  
   149  	// Check graph topology.
   150  	graph, _ := importGraph(initial)
   151  	wantGraph := `
   152    container/list
   153    golang.org/fake/a
   154    golang.org/fake/b
   155  * golang.org/fake/c
   156  * golang.org/fake/e
   157  * golang.org/fake/subdir/d
   158  * golang.org/fake/subdir/d [golang.org/fake/subdir/d.test]
   159  * golang.org/fake/subdir/d.test
   160  * golang.org/fake/subdir/d_test [golang.org/fake/subdir/d.test]
   161    math/bits
   162    unsafe
   163    golang.org/fake/b -> container/list
   164    golang.org/fake/b -> golang.org/fake/a
   165    golang.org/fake/c -> golang.org/fake/b
   166    golang.org/fake/c -> unsafe
   167    golang.org/fake/e -> golang.org/fake/b
   168    golang.org/fake/e -> golang.org/fake/c
   169    golang.org/fake/subdir/d [golang.org/fake/subdir/d.test] -> math/bits
   170    golang.org/fake/subdir/d.test -> golang.org/fake/subdir/d [golang.org/fake/subdir/d.test]
   171    golang.org/fake/subdir/d.test -> golang.org/fake/subdir/d_test [golang.org/fake/subdir/d.test]
   172    golang.org/fake/subdir/d_test [golang.org/fake/subdir/d.test] -> golang.org/fake/subdir/d [golang.org/fake/subdir/d.test]
   173  `[1:]
   174  
   175  	if graph != wantGraph {
   176  		t.Errorf("wrong import graph: got <<%s>>, want <<%s>>", graph, wantGraph)
   177  	}
   178  
   179  	exported.Config.Tests = true
   180  	initial, err = packages.Load(exported.Config, "golang.org/fake/c", "golang.org/fake/subdir/d", "golang.org/fake/e")
   181  	if err != nil {
   182  		t.Fatal(err)
   183  	}
   184  
   185  	// Check graph topology.
   186  	graph, all := importGraph(initial)
   187  	wantGraph = `
   188    container/list
   189    golang.org/fake/a
   190    golang.org/fake/b
   191  * golang.org/fake/c
   192  * golang.org/fake/e
   193  * golang.org/fake/subdir/d
   194  * golang.org/fake/subdir/d [golang.org/fake/subdir/d.test]
   195  * golang.org/fake/subdir/d.test
   196  * golang.org/fake/subdir/d_test [golang.org/fake/subdir/d.test]
   197    math/bits
   198    unsafe
   199    golang.org/fake/b -> container/list
   200    golang.org/fake/b -> golang.org/fake/a
   201    golang.org/fake/c -> golang.org/fake/b
   202    golang.org/fake/c -> unsafe
   203    golang.org/fake/e -> golang.org/fake/b
   204    golang.org/fake/e -> golang.org/fake/c
   205    golang.org/fake/subdir/d [golang.org/fake/subdir/d.test] -> math/bits
   206    golang.org/fake/subdir/d.test -> golang.org/fake/subdir/d [golang.org/fake/subdir/d.test]
   207    golang.org/fake/subdir/d.test -> golang.org/fake/subdir/d_test [golang.org/fake/subdir/d.test]
   208    golang.org/fake/subdir/d_test [golang.org/fake/subdir/d.test] -> golang.org/fake/subdir/d [golang.org/fake/subdir/d.test]
   209  `[1:]
   210  
   211  	if graph != wantGraph {
   212  		t.Errorf("wrong import graph: got <<%s>>, want <<%s>>", graph, wantGraph)
   213  	}
   214  
   215  	// Check node information: kind, name, srcs.
   216  	for _, test := range []struct {
   217  		id          string
   218  		wantName    string
   219  		wantKind    string
   220  		wantSrcs    string
   221  		wantIgnored string
   222  	}{
   223  		{"golang.org/fake/a", "a", "package", "a.go", ""},
   224  		{"golang.org/fake/b", "b", "package", "b.go", ""},
   225  		{"golang.org/fake/c", "c", "package", "c.go", "c2.go"}, // c2.go is ignored
   226  		{"golang.org/fake/e", "main", "command", "e.go e2.go", ""},
   227  		{"container/list", "list", "package", "list.go", ""},
   228  		{"golang.org/fake/subdir/d", "d", "package", "d.go", ""},
   229  		{"golang.org/fake/subdir/d.test", "main", "command", "0.go", ""},
   230  		{"unsafe", "unsafe", "package", "", ""},
   231  	} {
   232  		p, ok := all[test.id]
   233  		if !ok {
   234  			t.Errorf("no package %s", test.id)
   235  			continue
   236  		}
   237  		if p.Name != test.wantName {
   238  			t.Errorf("%s.Name = %q, want %q", test.id, p.Name, test.wantName)
   239  		}
   240  
   241  		// kind
   242  		var kind string
   243  		if p.Name == "main" {
   244  			kind += "command"
   245  		} else {
   246  			kind += "package"
   247  		}
   248  		if kind != test.wantKind {
   249  			t.Errorf("%s.Kind = %q, want %q", test.id, kind, test.wantKind)
   250  		}
   251  
   252  		if srcs := strings.Join(srcs(p), " "); srcs != test.wantSrcs {
   253  			t.Errorf("%s.Srcs = [%s], want [%s]", test.id, srcs, test.wantSrcs)
   254  		}
   255  		if ignored := strings.Join(cleanPaths(p.IgnoredFiles), " "); ignored != test.wantIgnored {
   256  			t.Errorf("%s.Srcs = [%s], want [%s]", test.id, ignored, test.wantIgnored)
   257  		}
   258  	}
   259  
   260  	// Test an ad-hoc package, analogous to "go run hello.go".
   261  	if initial, err := packages.Load(exported.Config, exported.File("golang.org/fake", "c/c.go")); len(initial) == 0 {
   262  		t.Errorf("failed to obtain metadata for ad-hoc package: %s", err)
   263  	} else {
   264  		got := fmt.Sprintf("%s %s", initial[0].ID, srcs(initial[0]))
   265  		if want := "command-line-arguments [c.go]"; got != want {
   266  			t.Errorf("oops: got %s, want %s", got, want)
   267  		}
   268  	}
   269  
   270  	// Wildcards
   271  	// See StdlibTest for effective test of "std" wildcard.
   272  	// TODO(adonovan): test "all" returns everything in the current module.
   273  	{
   274  		// "..." (subdirectory)
   275  		initial, err = packages.Load(exported.Config, "golang.org/fake/subdir/...")
   276  		if err != nil {
   277  			t.Fatal(err)
   278  		}
   279  		graph, _ = importGraph(initial)
   280  		wantGraph = `
   281  * golang.org/fake/subdir/d
   282  * golang.org/fake/subdir/d [golang.org/fake/subdir/d.test]
   283  * golang.org/fake/subdir/d.test
   284  * golang.org/fake/subdir/d_test [golang.org/fake/subdir/d.test]
   285  * golang.org/fake/subdir/e
   286    math/bits
   287    golang.org/fake/subdir/d [golang.org/fake/subdir/d.test] -> math/bits
   288    golang.org/fake/subdir/d.test -> golang.org/fake/subdir/d [golang.org/fake/subdir/d.test]
   289    golang.org/fake/subdir/d.test -> golang.org/fake/subdir/d_test [golang.org/fake/subdir/d.test]
   290    golang.org/fake/subdir/d_test [golang.org/fake/subdir/d.test] -> golang.org/fake/subdir/d [golang.org/fake/subdir/d.test]
   291  `[1:]
   292  
   293  		if graph != wantGraph {
   294  			t.Errorf("wrong import graph: got <<%s>>, want <<%s>>", graph, wantGraph)
   295  		}
   296  	}
   297  }
   298  
   299  func TestLoadImportsTestVariants(t *testing.T) {
   300  	testAllOrModulesParallel(t, testLoadImportsTestVariants)
   301  }
   302  func testLoadImportsTestVariants(t *testing.T, exporter packagestest.Exporter) {
   303  	exported := packagestest.Export(t, exporter, []packagestest.Module{{
   304  		Name: "golang.org/fake",
   305  		Files: map[string]interface{}{
   306  			"a/a.go":       `package a; import _ "golang.org/fake/b"`,
   307  			"b/b.go":       `package b`,
   308  			"b/b_test.go":  `package b`,
   309  			"b/bx_test.go": `package b_test; import _ "golang.org/fake/a"`,
   310  		}}})
   311  	defer exported.Cleanup()
   312  	exported.Config.Mode = packages.LoadImports
   313  	exported.Config.Tests = true
   314  
   315  	initial, err := packages.Load(exported.Config, "golang.org/fake/a", "golang.org/fake/b")
   316  	if err != nil {
   317  		t.Fatal(err)
   318  	}
   319  
   320  	// Check graph topology.
   321  	graph, _ := importGraph(initial)
   322  	wantGraph := `
   323  * golang.org/fake/a
   324    golang.org/fake/a [golang.org/fake/b.test]
   325  * golang.org/fake/b
   326  * golang.org/fake/b [golang.org/fake/b.test]
   327  * golang.org/fake/b.test
   328  * golang.org/fake/b_test [golang.org/fake/b.test]
   329    golang.org/fake/a -> golang.org/fake/b
   330    golang.org/fake/a [golang.org/fake/b.test] -> golang.org/fake/b [golang.org/fake/b.test]
   331    golang.org/fake/b.test -> golang.org/fake/b [golang.org/fake/b.test]
   332    golang.org/fake/b.test -> golang.org/fake/b_test [golang.org/fake/b.test]
   333    golang.org/fake/b_test [golang.org/fake/b.test] -> golang.org/fake/a [golang.org/fake/b.test]
   334  `[1:]
   335  
   336  	if graph != wantGraph {
   337  		t.Errorf("wrong import graph: got <<%s>>, want <<%s>>", graph, wantGraph)
   338  	}
   339  }
   340  
   341  func TestLoadAbsolutePath(t *testing.T) {
   342  	t.Parallel()
   343  
   344  	exported := packagestest.Export(t, packagestest.GOPATH, []packagestest.Module{{
   345  		Name: "golang.org/gopatha",
   346  		Files: map[string]interface{}{
   347  			"a/a.go": `package a`,
   348  		}}, {
   349  		Name: "golang.org/gopathb",
   350  		Files: map[string]interface{}{
   351  			"b/b.go": `package b`,
   352  		}}})
   353  	defer exported.Cleanup()
   354  
   355  	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")))
   356  	if err != nil {
   357  		t.Fatalf("failed to load imports: %v", err)
   358  	}
   359  
   360  	got := []string{}
   361  	for _, p := range initial {
   362  		got = append(got, p.ID)
   363  	}
   364  	sort.Strings(got)
   365  	want := []string{"golang.org/gopatha/a", "golang.org/gopathb/b"}
   366  	if !reflect.DeepEqual(got, want) {
   367  		t.Fatalf("initial packages loaded: got [%s], want [%s]", got, want)
   368  	}
   369  }
   370  
   371  func TestVendorImports(t *testing.T) {
   372  	t.Parallel()
   373  
   374  	exported := packagestest.Export(t, packagestest.GOPATH, []packagestest.Module{{
   375  		Name: "golang.org/fake",
   376  		Files: map[string]interface{}{
   377  			"a/a.go":          `package a; import _ "b"; import _ "golang.org/fake/c";`,
   378  			"a/vendor/b/b.go": `package b; import _ "golang.org/fake/c"`,
   379  			"c/c.go":          `package c; import _ "b"`,
   380  			"c/vendor/b/b.go": `package b`,
   381  		}}})
   382  	defer exported.Cleanup()
   383  	exported.Config.Mode = packages.LoadImports
   384  	initial, err := packages.Load(exported.Config, "golang.org/fake/a", "golang.org/fake/c")
   385  	if err != nil {
   386  		t.Fatal(err)
   387  	}
   388  
   389  	graph, all := importGraph(initial)
   390  	wantGraph := `
   391  * golang.org/fake/a
   392    golang.org/fake/a/vendor/b
   393  * golang.org/fake/c
   394    golang.org/fake/c/vendor/b
   395    golang.org/fake/a -> golang.org/fake/a/vendor/b
   396    golang.org/fake/a -> golang.org/fake/c
   397    golang.org/fake/a/vendor/b -> golang.org/fake/c
   398    golang.org/fake/c -> golang.org/fake/c/vendor/b
   399  `[1:]
   400  	if graph != wantGraph {
   401  		t.Errorf("wrong import graph: got <<%s>>, want <<%s>>", graph, wantGraph)
   402  	}
   403  
   404  	for _, test := range []struct {
   405  		pattern     string
   406  		wantImports string
   407  	}{
   408  		{"golang.org/fake/a", "b:golang.org/fake/a/vendor/b golang.org/fake/c:golang.org/fake/c"},
   409  		{"golang.org/fake/c", "b:golang.org/fake/c/vendor/b"},
   410  		{"golang.org/fake/a/vendor/b", "golang.org/fake/c:golang.org/fake/c"},
   411  		{"golang.org/fake/c/vendor/b", ""},
   412  	} {
   413  		// Test the import paths.
   414  		pkg := all[test.pattern]
   415  		if imports := strings.Join(imports(pkg), " "); imports != test.wantImports {
   416  			t.Errorf("package %q: got %s, want %s", test.pattern, imports, test.wantImports)
   417  		}
   418  	}
   419  }
   420  
   421  func imports(p *packages.Package) []string {
   422  	if p == nil {
   423  		return nil
   424  	}
   425  	keys := make([]string, 0, len(p.Imports))
   426  	for k, v := range p.Imports {
   427  		keys = append(keys, fmt.Sprintf("%s:%s", k, v.ID))
   428  	}
   429  	sort.Strings(keys)
   430  	return keys
   431  }
   432  
   433  func TestConfigDir(t *testing.T) { testAllOrModulesParallel(t, testConfigDir) }
   434  func testConfigDir(t *testing.T, exporter packagestest.Exporter) {
   435  	exported := packagestest.Export(t, exporter, []packagestest.Module{{
   436  		Name: "golang.org/fake",
   437  		Files: map[string]interface{}{
   438  			"a/a.go":   `package a; const Name = "a" `,
   439  			"a/b/b.go": `package b; const Name = "a/b"`,
   440  			"b/b.go":   `package b; const Name = "b"`,
   441  		}}})
   442  	defer exported.Cleanup()
   443  	aDir := filepath.Dir(exported.File("golang.org/fake", "a/a.go"))
   444  	bDir := filepath.Dir(exported.File("golang.org/fake", "b/b.go"))
   445  	baseDir := filepath.Dir(aDir)
   446  
   447  	for _, test := range []struct {
   448  		dir     string
   449  		pattern string
   450  		want    string // value of Name constant
   451  		fails   bool
   452  	}{
   453  		{dir: bDir, pattern: "golang.org/fake/a", want: `"a"`},
   454  		{dir: bDir, pattern: "golang.org/fake/b", want: `"b"`},
   455  		{dir: bDir, pattern: "./a", fails: true},
   456  		{dir: bDir, pattern: "./b", fails: true},
   457  		{dir: baseDir, pattern: "golang.org/fake/a", want: `"a"`},
   458  		{dir: baseDir, pattern: "golang.org/fake/b", want: `"b"`},
   459  		{dir: baseDir, pattern: "./a", want: `"a"`},
   460  		{dir: baseDir, pattern: "./b", want: `"b"`},
   461  		{dir: aDir, pattern: "golang.org/fake/a", want: `"a"`},
   462  		{dir: aDir, pattern: "golang.org/fake/b", want: `"b"`},
   463  		{dir: aDir, pattern: "./a", fails: true},
   464  		{dir: aDir, pattern: "./b", want: `"a/b"`},
   465  	} {
   466  		exported.Config.Mode = packages.LoadSyntax // Use LoadSyntax to ensure that files can be opened.
   467  		exported.Config.Dir = test.dir
   468  		initial, err := packages.Load(exported.Config, test.pattern)
   469  		var got string
   470  		fails := false
   471  		if err != nil {
   472  			fails = true
   473  		} else if len(initial) > 0 {
   474  			if len(initial[0].Errors) > 0 {
   475  				fails = true
   476  			} else if c := constant(initial[0], "Name"); c != nil {
   477  				got = c.Val().String()
   478  			}
   479  		}
   480  		if got != test.want {
   481  			t.Errorf("dir %q, pattern %q: got %s, want %s",
   482  				test.dir, test.pattern, got, test.want)
   483  		}
   484  		if fails != test.fails {
   485  			// TODO: remove when go#28023 is fixed
   486  			if test.fails && strings.HasPrefix(test.pattern, "./") && exporter == packagestest.Modules {
   487  				// Currently go list in module mode does not handle missing directories correctly.
   488  				continue
   489  			}
   490  			t.Errorf("dir %q, pattern %q: error %v, want %v",
   491  				test.dir, test.pattern, fails, test.fails)
   492  		}
   493  	}
   494  }
   495  
   496  func TestConfigFlags(t *testing.T) { testAllOrModulesParallel(t, testConfigFlags) }
   497  func testConfigFlags(t *testing.T, exporter packagestest.Exporter) {
   498  	// Test satisfying +build line tags, with -tags flag.
   499  	exported := packagestest.Export(t, exporter, []packagestest.Module{{
   500  		Name: "golang.org/fake",
   501  		Files: map[string]interface{}{
   502  			// package a
   503  			"a/a.go": `package a; import _ "golang.org/fake/a/b"`,
   504  			"a/b.go": `// +build tag
   505  
   506  package a`,
   507  			"a/c.go": `// +build tag tag2
   508  
   509  package a`,
   510  			"a/d.go": `// +build tag,tag2
   511  
   512  package a`,
   513  			// package a/b
   514  			"a/b/a.go": `package b`,
   515  			"a/b/b.go": `// +build tag
   516  
   517  package b`,
   518  		}}})
   519  	defer exported.Cleanup()
   520  
   521  	for _, test := range []struct {
   522  		pattern        string
   523  		tags           []string
   524  		wantSrcs       string
   525  		wantImportSrcs string
   526  	}{
   527  		{`golang.org/fake/a`, []string{}, "a.go", "a.go"},
   528  		{`golang.org/fake/a`, []string{`-tags=tag`}, "a.go b.go c.go", "a.go b.go"},
   529  		{`golang.org/fake/a`, []string{`-tags=tag2`}, "a.go c.go", "a.go"},
   530  		{`golang.org/fake/a`, []string{`-tags=tag tag2`}, "a.go b.go c.go d.go", "a.go b.go"},
   531  	} {
   532  		exported.Config.Mode = packages.LoadImports
   533  		exported.Config.BuildFlags = test.tags
   534  
   535  		initial, err := packages.Load(exported.Config, test.pattern)
   536  		if err != nil {
   537  			t.Error(err)
   538  			continue
   539  		}
   540  		if len(initial) != 1 {
   541  			t.Errorf("test tags %v: pattern %s, expected 1 package, got %d packages.", test.tags, test.pattern, len(initial))
   542  			continue
   543  		}
   544  		pkg := initial[0]
   545  		if srcs := strings.Join(srcs(pkg), " "); srcs != test.wantSrcs {
   546  			t.Errorf("test tags %v: srcs of package %s = [%s], want [%s]", test.tags, test.pattern, srcs, test.wantSrcs)
   547  		}
   548  		for path, ipkg := range pkg.Imports {
   549  			if srcs := strings.Join(srcs(ipkg), " "); srcs != test.wantImportSrcs {
   550  				t.Errorf("build tags %v: srcs of imported package %s = [%s], want [%s]", test.tags, path, srcs, test.wantImportSrcs)
   551  			}
   552  		}
   553  
   554  	}
   555  }
   556  
   557  func TestLoadTypes(t *testing.T) { testAllOrModulesParallel(t, testLoadTypes) }
   558  func testLoadTypes(t *testing.T, exporter packagestest.Exporter) {
   559  	// In LoadTypes and LoadSyntax modes, the compiler will
   560  	// fail to generate an export data file for c, because it has
   561  	// a type error.  The loader should fall back loading a and c
   562  	// from source, but use the export data for b.
   563  
   564  	exported := packagestest.Export(t, exporter, []packagestest.Module{{
   565  		Name: "golang.org/fake",
   566  		Files: map[string]interface{}{
   567  			"a/a.go": `package a; import "golang.org/fake/b"; import "golang.org/fake/c"; const A = "a" + b.B + c.C`,
   568  			"b/b.go": `package b; const B = "b"`,
   569  			"c/c.go": `package c; const C = "c" + 1`,
   570  		}}})
   571  	defer exported.Cleanup()
   572  
   573  	exported.Config.Mode = packages.LoadTypes
   574  	initial, err := packages.Load(exported.Config, "golang.org/fake/a")
   575  	if err != nil {
   576  		t.Fatal(err)
   577  	}
   578  
   579  	graph, all := importGraph(initial)
   580  	wantGraph := `
   581  * golang.org/fake/a
   582    golang.org/fake/b
   583    golang.org/fake/c
   584    golang.org/fake/a -> golang.org/fake/b
   585    golang.org/fake/a -> golang.org/fake/c
   586  `[1:]
   587  	if graph != wantGraph {
   588  		t.Errorf("wrong import graph: got <<%s>>, want <<%s>>", graph, wantGraph)
   589  	}
   590  
   591  	for _, id := range []string{
   592  		"golang.org/fake/a",
   593  		"golang.org/fake/b",
   594  		"golang.org/fake/c",
   595  	} {
   596  		p := all[id]
   597  		if p == nil {
   598  			t.Errorf("missing package: %s", id)
   599  			continue
   600  		}
   601  		if p.Types == nil {
   602  			t.Errorf("missing types.Package for %s", p)
   603  			continue
   604  		} else if !p.Types.Complete() {
   605  			t.Errorf("incomplete types.Package for %s", p)
   606  		} else if p.TypesSizes == nil {
   607  			t.Errorf("TypesSizes is not filled in for %s", p)
   608  		}
   609  
   610  	}
   611  }
   612  
   613  // TestLoadTypesBits is equivalent to TestLoadTypes except that it only requests
   614  // the types using the NeedTypes bit.
   615  func TestLoadTypesBits(t *testing.T) { testAllOrModulesParallel(t, testLoadTypesBits) }
   616  func testLoadTypesBits(t *testing.T, exporter packagestest.Exporter) {
   617  	exported := packagestest.Export(t, exporter, []packagestest.Module{{
   618  		Name: "golang.org/fake",
   619  		Files: map[string]interface{}{
   620  			"a/a.go": `package a; import "golang.org/fake/b"; const A = "a" + b.B`,
   621  			"b/b.go": `package b; import "golang.org/fake/c"; const B = "b" + c.C`,
   622  			"c/c.go": `package c; import "golang.org/fake/d"; const C = "c" + d.D`,
   623  			"d/d.go": `package d; import "golang.org/fake/e"; const D = "d" + e.E`,
   624  			"e/e.go": `package e; import "golang.org/fake/f"; const E = "e" + f.F`,
   625  			"f/f.go": `package f; const F = "f"`,
   626  		}}})
   627  	defer exported.Cleanup()
   628  
   629  	exported.Config.Mode = packages.NeedTypes | packages.NeedImports
   630  	initial, err := packages.Load(exported.Config, "golang.org/fake/a", "golang.org/fake/c")
   631  	if err != nil {
   632  		t.Fatal(err)
   633  	}
   634  
   635  	graph, all := importGraph(initial)
   636  	wantGraph := `
   637  * golang.org/fake/a
   638    golang.org/fake/b
   639  * golang.org/fake/c
   640    golang.org/fake/d
   641    golang.org/fake/e
   642    golang.org/fake/f
   643    golang.org/fake/a -> golang.org/fake/b
   644    golang.org/fake/b -> golang.org/fake/c
   645    golang.org/fake/c -> golang.org/fake/d
   646    golang.org/fake/d -> golang.org/fake/e
   647    golang.org/fake/e -> golang.org/fake/f
   648  `[1:]
   649  	if graph != wantGraph {
   650  		t.Errorf("wrong import graph: got <<%s>>, want <<%s>>", graph, wantGraph)
   651  	}
   652  
   653  	for _, test := range []struct {
   654  		id string
   655  	}{
   656  		{"golang.org/fake/a"},
   657  		{"golang.org/fake/b"},
   658  		{"golang.org/fake/c"},
   659  		{"golang.org/fake/d"},
   660  		{"golang.org/fake/e"},
   661  		{"golang.org/fake/f"},
   662  	} {
   663  		p := all[test.id]
   664  		if p == nil {
   665  			t.Errorf("missing package: %s", test.id)
   666  			continue
   667  		}
   668  		if p.Types == nil {
   669  			t.Errorf("missing types.Package for %s", p)
   670  			continue
   671  		}
   672  		// We don't request the syntax, so we shouldn't get it.
   673  		if p.Syntax != nil {
   674  			t.Errorf("Syntax unexpectedly provided for %s", p)
   675  		}
   676  		if p.Errors != nil {
   677  			t.Errorf("errors in package: %s: %s", p, p.Errors)
   678  		}
   679  	}
   680  
   681  	// Check value of constant.
   682  	aA := constant(all["golang.org/fake/a"], "A")
   683  	if aA == nil {
   684  		t.Fatalf("a.A: got nil")
   685  	}
   686  	if got, want := fmt.Sprintf("%v %v", aA, aA.Val()), `const golang.org/fake/a.A untyped string "abcdef"`; got != want {
   687  		t.Errorf("a.A: got %s, want %s", got, want)
   688  	}
   689  }
   690  
   691  func TestLoadSyntaxOK(t *testing.T) { testAllOrModulesParallel(t, testLoadSyntaxOK) }
   692  func testLoadSyntaxOK(t *testing.T, exporter packagestest.Exporter) {
   693  	exported := packagestest.Export(t, exporter, []packagestest.Module{{
   694  		Name: "golang.org/fake",
   695  		Files: map[string]interface{}{
   696  			"a/a.go": `package a; import "golang.org/fake/b"; const A = "a" + b.B`,
   697  			"b/b.go": `package b; import "golang.org/fake/c"; const B = "b" + c.C`,
   698  			"c/c.go": `package c; import "golang.org/fake/d"; const C = "c" + d.D`,
   699  			"d/d.go": `package d; import "golang.org/fake/e"; const D = "d" + e.E`,
   700  			"e/e.go": `package e; import "golang.org/fake/f"; const E = "e" + f.F`,
   701  			"f/f.go": `package f; const F = "f"`,
   702  		}}})
   703  	defer exported.Cleanup()
   704  
   705  	exported.Config.Mode = packages.LoadSyntax
   706  	initial, err := packages.Load(exported.Config, "golang.org/fake/a", "golang.org/fake/c")
   707  	if err != nil {
   708  		t.Fatal(err)
   709  	}
   710  
   711  	graph, all := importGraph(initial)
   712  	wantGraph := `
   713  * golang.org/fake/a
   714    golang.org/fake/b
   715  * golang.org/fake/c
   716    golang.org/fake/d
   717    golang.org/fake/e
   718    golang.org/fake/f
   719    golang.org/fake/a -> golang.org/fake/b
   720    golang.org/fake/b -> golang.org/fake/c
   721    golang.org/fake/c -> golang.org/fake/d
   722    golang.org/fake/d -> golang.org/fake/e
   723    golang.org/fake/e -> golang.org/fake/f
   724  `[1:]
   725  	if graph != wantGraph {
   726  		t.Errorf("wrong import graph: got <<%s>>, want <<%s>>", graph, wantGraph)
   727  	}
   728  
   729  	for _, test := range []struct {
   730  		id           string
   731  		wantSyntax   bool
   732  		wantComplete bool
   733  	}{
   734  		{"golang.org/fake/a", true, true},   // source package
   735  		{"golang.org/fake/b", true, true},   // source package because depends on initial package
   736  		{"golang.org/fake/c", true, true},   // source package
   737  		{"golang.org/fake/d", false, true},  // export data package
   738  		{"golang.org/fake/e", false, false}, // export data package
   739  		{"golang.org/fake/f", false, false}, // export data package
   740  	} {
   741  		// TODO(matloob): LoadSyntax and LoadAllSyntax are now equivalent, wantSyntax and wantComplete
   742  		// are true for all packages in the transitive dependency set. Add test cases on the individual
   743  		// Need* fields to check the equivalents on the new API.
   744  		p := all[test.id]
   745  		if p == nil {
   746  			t.Errorf("missing package: %s", test.id)
   747  			continue
   748  		}
   749  		if p.Types == nil {
   750  			t.Errorf("missing types.Package for %s", p)
   751  			continue
   752  		} else if p.Types.Complete() != test.wantComplete {
   753  			if test.wantComplete {
   754  				t.Errorf("incomplete types.Package for %s", p)
   755  			} else {
   756  				t.Errorf("unexpected complete types.Package for %s", p)
   757  			}
   758  		}
   759  		if (p.Syntax != nil) != test.wantSyntax {
   760  			if test.wantSyntax {
   761  				t.Errorf("missing ast.Files for %s", p)
   762  			} else {
   763  				t.Errorf("unexpected ast.Files for for %s", p)
   764  			}
   765  		}
   766  		if p.Errors != nil {
   767  			t.Errorf("errors in package: %s: %s", p, p.Errors)
   768  		}
   769  	}
   770  
   771  	// Check value of constant.
   772  	aA := constant(all["golang.org/fake/a"], "A")
   773  	if aA == nil {
   774  		t.Fatalf("a.A: got nil")
   775  	}
   776  	if got, want := fmt.Sprintf("%v %v", aA, aA.Val()), `const golang.org/fake/a.A untyped string "abcdef"`; got != want {
   777  		t.Errorf("a.A: got %s, want %s", got, want)
   778  	}
   779  }
   780  
   781  func TestLoadDiamondTypes(t *testing.T) { testAllOrModulesParallel(t, testLoadDiamondTypes) }
   782  func testLoadDiamondTypes(t *testing.T, exporter packagestest.Exporter) {
   783  	// We make a diamond dependency and check the type d.D is the same through both paths
   784  	exported := packagestest.Export(t, exporter, []packagestest.Module{{
   785  		Name: "golang.org/fake",
   786  		Files: map[string]interface{}{
   787  			"a/a.go": `package a; import ("golang.org/fake/b"; "golang.org/fake/c"); var _ = b.B == c.C`,
   788  			"b/b.go": `package b; import "golang.org/fake/d"; var B d.D`,
   789  			"c/c.go": `package c; import "golang.org/fake/d"; var C d.D`,
   790  			"d/d.go": `package d; type D int`,
   791  		}}})
   792  	defer exported.Cleanup()
   793  
   794  	exported.Config.Mode = packages.LoadSyntax
   795  	initial, err := packages.Load(exported.Config, "golang.org/fake/a")
   796  	if err != nil {
   797  		t.Fatal(err)
   798  	}
   799  	packages.Visit(initial, nil, func(pkg *packages.Package) {
   800  		for _, err := range pkg.Errors {
   801  			t.Errorf("package %s: %v", pkg.ID, err)
   802  		}
   803  	})
   804  
   805  	graph, _ := importGraph(initial)
   806  	wantGraph := `
   807  * golang.org/fake/a
   808    golang.org/fake/b
   809    golang.org/fake/c
   810    golang.org/fake/d
   811    golang.org/fake/a -> golang.org/fake/b
   812    golang.org/fake/a -> golang.org/fake/c
   813    golang.org/fake/b -> golang.org/fake/d
   814    golang.org/fake/c -> golang.org/fake/d
   815  `[1:]
   816  	if graph != wantGraph {
   817  		t.Errorf("wrong import graph: got <<%s>>, want <<%s>>", graph, wantGraph)
   818  	}
   819  }
   820  
   821  func TestLoadSyntaxError(t *testing.T) { testAllOrModulesParallel(t, testLoadSyntaxError) }
   822  func testLoadSyntaxError(t *testing.T, exporter packagestest.Exporter) {
   823  	// A type error in a lower-level package (e) prevents go list
   824  	// from producing export data for all packages that depend on it
   825  	// [a-e]. Only f should be loaded from export data, and the rest
   826  	// should be IllTyped.
   827  	exported := packagestest.Export(t, exporter, []packagestest.Module{{
   828  		Name: "golang.org/fake",
   829  		Files: map[string]interface{}{
   830  			"a/a.go": `package a; import "golang.org/fake/b"; const A = "a" + b.B`,
   831  			"b/b.go": `package b; import "golang.org/fake/c"; const B = "b" + c.C`,
   832  			"c/c.go": `package c; import "golang.org/fake/d"; const C = "c" + d.D`,
   833  			"d/d.go": `package d; import "golang.org/fake/e"; const D = "d" + e.E`,
   834  			"e/e.go": `package e; import "golang.org/fake/f"; const E = "e" + f.F + 1`, // type error
   835  			"f/f.go": `package f; const F = "f"`,
   836  		}}})
   837  	defer exported.Cleanup()
   838  
   839  	exported.Config.Mode = packages.LoadSyntax
   840  	initial, err := packages.Load(exported.Config, "golang.org/fake/a", "golang.org/fake/c")
   841  	if err != nil {
   842  		t.Fatal(err)
   843  	}
   844  
   845  	all := make(map[string]*packages.Package)
   846  	packages.Visit(initial, nil, func(p *packages.Package) {
   847  		all[p.ID] = p
   848  	})
   849  
   850  	for _, test := range []struct {
   851  		id           string
   852  		wantSyntax   bool
   853  		wantIllTyped bool
   854  	}{
   855  		{"golang.org/fake/a", true, true},
   856  		{"golang.org/fake/b", true, true},
   857  		{"golang.org/fake/c", true, true},
   858  		{"golang.org/fake/d", true, true},
   859  		{"golang.org/fake/e", true, true},
   860  		{"golang.org/fake/f", false, false},
   861  	} {
   862  		p := all[test.id]
   863  		if p == nil {
   864  			t.Errorf("missing package: %s", test.id)
   865  			continue
   866  		}
   867  		if p.Types == nil {
   868  			t.Errorf("missing types.Package for %s", p)
   869  			continue
   870  		} else if !p.Types.Complete() {
   871  			t.Errorf("incomplete types.Package for %s", p)
   872  		}
   873  		if (p.Syntax != nil) != test.wantSyntax {
   874  			if test.wantSyntax {
   875  				t.Errorf("missing ast.Files for %s", test.id)
   876  			} else {
   877  				t.Errorf("unexpected ast.Files for for %s", test.id)
   878  			}
   879  		}
   880  		if p.IllTyped != test.wantIllTyped {
   881  			t.Errorf("IllTyped was %t for %s", p.IllTyped, test.id)
   882  		}
   883  	}
   884  
   885  	// Check value of constant.
   886  	aA := constant(all["golang.org/fake/a"], "A")
   887  	if aA == nil {
   888  		t.Fatalf("a.A: got nil")
   889  	}
   890  	if got, want := aA.String(), `const golang.org/fake/a.A invalid type`; got != want {
   891  		t.Errorf("a.A: got %s, want %s", got, want)
   892  	}
   893  }
   894  
   895  // This function tests use of the ParseFile hook to modify
   896  // the AST after parsing.
   897  func TestParseFileModifyAST(t *testing.T) { testAllOrModulesParallel(t, testParseFileModifyAST) }
   898  func testParseFileModifyAST(t *testing.T, exporter packagestest.Exporter) {
   899  	exported := packagestest.Export(t, exporter, []packagestest.Module{{
   900  		Name: "golang.org/fake",
   901  		Files: map[string]interface{}{
   902  			"a/a.go": `package a; const A = "a" `,
   903  		}}})
   904  	defer exported.Cleanup()
   905  
   906  	exported.Config.Mode = packages.LoadAllSyntax
   907  	exported.Config.ParseFile = func(fset *token.FileSet, filename string, src []byte) (*ast.File, error) {
   908  		const mode = parser.AllErrors | parser.ParseComments
   909  		f, err := parser.ParseFile(fset, filename, src, mode)
   910  		// modify AST to change `const A = "a"` to `const A = "b"`
   911  		spec := f.Decls[0].(*ast.GenDecl).Specs[0].(*ast.ValueSpec)
   912  		spec.Values[0].(*ast.BasicLit).Value = `"b"`
   913  		return f, err
   914  	}
   915  	initial, err := packages.Load(exported.Config, "golang.org/fake/a")
   916  	if err != nil {
   917  		t.Error(err)
   918  	}
   919  
   920  	// Check value of a.A has been set to "b"
   921  	a := initial[0]
   922  	got := constant(a, "A").Val().String()
   923  	if got != `"b"` {
   924  		t.Errorf("a.A: got %s, want %s", got, `"b"`)
   925  	}
   926  }
   927  
   928  func TestAdHocPackagesBadImport(t *testing.T) {
   929  	t.Parallel()
   930  
   931  	// This test doesn't use packagestest because we are testing ad-hoc packages,
   932  	// which are outside of $GOPATH and outside of a module.
   933  	tmp, err := ioutil.TempDir("", "a")
   934  	if err != nil {
   935  		t.Fatal(err)
   936  	}
   937  	defer os.RemoveAll(tmp)
   938  
   939  	filename := filepath.Join(tmp, "a.go")
   940  	content := []byte(`package a
   941  import _ "badimport"
   942  const A = 1
   943  `)
   944  	if err := ioutil.WriteFile(filename, content, 0775); err != nil {
   945  		t.Fatal(err)
   946  	}
   947  
   948  	// Make sure that the user's value of GO111MODULE does not affect test results.
   949  	for _, go111module := range []string{"off", "auto", "on"} {
   950  		config := &packages.Config{
   951  			Env:  append(os.Environ(), "GOPACKAGESDRIVER=off", fmt.Sprintf("GO111MODULE=%s", go111module)),
   952  			Dir:  tmp,
   953  			Mode: packages.LoadAllSyntax,
   954  			Logf: t.Logf,
   955  		}
   956  		initial, err := packages.Load(config, fmt.Sprintf("file=%s", filename))
   957  		if err != nil {
   958  			t.Error(err)
   959  		}
   960  		if len(initial) == 0 {
   961  			t.Fatalf("no packages for %s with GO111MODULE=%s", filename, go111module)
   962  		}
   963  		// Check value of a.A.
   964  		a := initial[0]
   965  		// There's an error because there's a bad import.
   966  		aA := constant(a, "A")
   967  		if aA == nil {
   968  			t.Errorf("a.A: got nil")
   969  			return
   970  		}
   971  		got := aA.Val().String()
   972  		if want := "1"; got != want {
   973  			t.Errorf("a.A: got %s, want %s", got, want)
   974  		}
   975  	}
   976  }
   977  
   978  func TestLoadAllSyntaxImportErrors(t *testing.T) {
   979  	testAllOrModulesParallel(t, testLoadAllSyntaxImportErrors)
   980  }
   981  func testLoadAllSyntaxImportErrors(t *testing.T, exporter packagestest.Exporter) {
   982  	// TODO(matloob): Remove this once go list -e -compiled is fixed.
   983  	// See https://golang.org/issue/26755
   984  	t.Skip("go list -compiled -e fails with non-zero exit status for empty packages")
   985  
   986  	exported := packagestest.Export(t, exporter, []packagestest.Module{{
   987  		Name: "golang.org/fake",
   988  		Files: map[string]interface{}{
   989  			"unicycle/unicycle.go": `package unicycle; import _ "unicycle"`,
   990  			"bicycle1/bicycle1.go": `package bicycle1; import _ "bicycle2"`,
   991  			"bicycle2/bicycle2.go": `package bicycle2; import _ "bicycle1"`,
   992  			"bad/bad.go":           `not a package declaration`,
   993  			"empty/README.txt":     `not a go file`,
   994  			"root/root.go": `package root
   995  import (
   996  	_ "bicycle1"
   997  	_ "unicycle"
   998  	_ "nonesuch"
   999  	_ "empty"
  1000  	_ "bad"
  1001  )`,
  1002  		}}})
  1003  	defer exported.Cleanup()
  1004  
  1005  	exported.Config.Mode = packages.LoadAllSyntax
  1006  	initial, err := packages.Load(exported.Config, "root")
  1007  	if err != nil {
  1008  		t.Fatal(err)
  1009  	}
  1010  
  1011  	// Cycle-forming edges are removed from the graph:
  1012  	// 	bicycle2 -> bicycle1
  1013  	//      unicycle -> unicycle
  1014  	graph, all := importGraph(initial)
  1015  	wantGraph := `
  1016    bicycle1
  1017    bicycle2
  1018  * root
  1019    unicycle
  1020    bicycle1 -> bicycle2
  1021    root -> bicycle1
  1022    root -> unicycle
  1023  `[1:]
  1024  	if graph != wantGraph {
  1025  		t.Errorf("wrong import graph: got <<%s>>, want <<%s>>", graph, wantGraph)
  1026  	}
  1027  	for _, test := range []struct {
  1028  		id       string
  1029  		wantErrs []string
  1030  	}{
  1031  		{"bicycle1", nil},
  1032  		{"bicycle2", []string{
  1033  			"could not import bicycle1 (import cycle: [root bicycle1 bicycle2])",
  1034  		}},
  1035  		{"unicycle", []string{
  1036  			"could not import unicycle (import cycle: [root unicycle])",
  1037  		}},
  1038  		{"root", []string{
  1039  			`could not import bad (missing package: "bad")`,
  1040  			`could not import empty (missing package: "empty")`,
  1041  			`could not import nonesuch (missing package: "nonesuch")`,
  1042  		}},
  1043  	} {
  1044  		p := all[test.id]
  1045  		if p == nil {
  1046  			t.Errorf("missing package: %s", test.id)
  1047  			continue
  1048  		}
  1049  		if p.Types == nil {
  1050  			t.Errorf("missing types.Package for %s", test.id)
  1051  		}
  1052  		if p.Syntax == nil {
  1053  			t.Errorf("missing ast.Files for %s", test.id)
  1054  		}
  1055  		if !p.IllTyped {
  1056  			t.Errorf("IllTyped was false for %s", test.id)
  1057  		}
  1058  		if errs := errorMessages(p.Errors); !reflect.DeepEqual(errs, test.wantErrs) {
  1059  			t.Errorf("in package %s, got errors %s, want %s", p, errs, test.wantErrs)
  1060  		}
  1061  	}
  1062  }
  1063  
  1064  func TestAbsoluteFilenames(t *testing.T) { testAllOrModulesParallel(t, testAbsoluteFilenames) }
  1065  func testAbsoluteFilenames(t *testing.T, exporter packagestest.Exporter) {
  1066  	exported := packagestest.Export(t, exporter, []packagestest.Module{{
  1067  		Name: "golang.org/fake",
  1068  		Files: map[string]interface{}{
  1069  			"a/a.go":          `package a; const A = 1`,
  1070  			"b/b.go":          `package b; import ("golang.org/fake/a"; _ "errors"); var B = a.A`,
  1071  			"b/vendor/a/a.go": `package a; const A = 1`,
  1072  			"c/c.go":          `package c; import (_ "golang.org/fake/b"; _ "unsafe")`,
  1073  			"c/c2.go":         "// +build ignore\n\n" + `package c; import _ "fmt"`,
  1074  			"subdir/d/d.go":   `package d`,
  1075  			"subdir/e/d.go":   `package e`,
  1076  			"e/e.go":          `package main; import _ "golang.org/fake/b"`,
  1077  			"e/e2.go":         `package main; import _ "golang.org/fake/c"`,
  1078  			"f/f.go":          `package f`,
  1079  			"f/f.s":           ``,
  1080  			"g/g.go":          `package g; import _ "embed";` + "\n//go:embed g2.txt\n" + `var s string`,
  1081  			"g/g2.txt":        "hello",
  1082  			"h/h.go":          `package g; import _ "embed";` + "\n//go:embed a*.txt\n" + `var s string`,
  1083  			"h/aa.txt":        "hello",
  1084  		}}})
  1085  	defer exported.Cleanup()
  1086  	exported.Config.Dir = filepath.Dir(filepath.Dir(exported.File("golang.org/fake", "a/a.go")))
  1087  
  1088  	checkFile := func(filename string) {
  1089  		if !filepath.IsAbs(filename) {
  1090  			t.Errorf("filename is not absolute: %s", filename)
  1091  		}
  1092  		if _, err := os.Stat(filename); err != nil {
  1093  			t.Errorf("stat error, %s: %v", filename, err)
  1094  		}
  1095  	}
  1096  
  1097  	for _, test := range []struct {
  1098  		pattern string
  1099  		want    string
  1100  	}{
  1101  		// Import paths
  1102  		{"golang.org/fake/a", "a.go"},
  1103  		{"golang.org/fake/b/vendor/a", "a.go"},
  1104  		{"golang.org/fake/b", "b.go"},
  1105  		{"golang.org/fake/c", "c.go"},
  1106  		{"golang.org/fake/subdir/d", "d.go"},
  1107  		{"golang.org/fake/subdir/e", "d.go"},
  1108  		{"golang.org/fake/e", "e.go e2.go"},
  1109  		{"golang.org/fake/f", "f.go f.s"},
  1110  		{"golang.org/fake/g", "g.go g2.txt"},
  1111  		{"golang.org/fake/h", "h.go aa.txt"},
  1112  		// Relative paths
  1113  		{"./a", "a.go"},
  1114  		{"./b/vendor/a", "a.go"},
  1115  		{"./b", "b.go"},
  1116  		{"./c", "c.go"},
  1117  		{"./subdir/d", "d.go"},
  1118  		{"./subdir/e", "d.go"},
  1119  		{"./e", "e.go e2.go"},
  1120  		{"./f", "f.go f.s"},
  1121  		{"./g", "g.go g2.txt"},
  1122  		{"./h", "h.go aa.txt"},
  1123  	} {
  1124  		exported.Config.Mode = packages.LoadFiles | packages.NeedEmbedFiles
  1125  		pkgs, err := packages.Load(exported.Config, test.pattern)
  1126  		if err != nil {
  1127  			t.Errorf("pattern %s: %v", test.pattern, err)
  1128  			continue
  1129  		}
  1130  
  1131  		if got := strings.Join(srcs(pkgs[0]), " "); got != test.want {
  1132  			t.Errorf("in package %s, got %s, want %s", test.pattern, got, test.want)
  1133  		}
  1134  
  1135  		// Test that files in all packages exist and are absolute paths.
  1136  		_, all := importGraph(pkgs)
  1137  		for _, pkg := range all {
  1138  			for _, filename := range pkg.GoFiles {
  1139  				checkFile(filename)
  1140  			}
  1141  			for _, filename := range pkg.OtherFiles {
  1142  				checkFile(filename)
  1143  			}
  1144  			for _, filename := range pkg.EmbedFiles {
  1145  				checkFile(filename)
  1146  			}
  1147  			for _, filename := range pkg.IgnoredFiles {
  1148  				checkFile(filename)
  1149  			}
  1150  		}
  1151  	}
  1152  }
  1153  
  1154  func TestContains(t *testing.T) { testAllOrModulesParallel(t, testContains) }
  1155  func testContains(t *testing.T, exporter packagestest.Exporter) {
  1156  	exported := packagestest.Export(t, exporter, []packagestest.Module{{
  1157  		Name: "golang.org/fake",
  1158  		Files: map[string]interface{}{
  1159  			"a/a.go": `package a; import "golang.org/fake/b"`,
  1160  			"b/b.go": `package b; import "golang.org/fake/c"`,
  1161  			"c/c.go": `package c`,
  1162  		}}})
  1163  	defer exported.Cleanup()
  1164  	bFile := exported.File("golang.org/fake", "b/b.go")
  1165  	exported.Config.Mode = packages.LoadImports
  1166  	initial, err := packages.Load(exported.Config, "file="+bFile)
  1167  	if err != nil {
  1168  		t.Fatal(err)
  1169  	}
  1170  
  1171  	graph, _ := importGraph(initial)
  1172  	wantGraph := `
  1173  * golang.org/fake/b
  1174    golang.org/fake/c
  1175    golang.org/fake/b -> golang.org/fake/c
  1176  `[1:]
  1177  	if graph != wantGraph {
  1178  		t.Errorf("wrong import graph: got <<%s>>, want <<%s>>", graph, wantGraph)
  1179  	}
  1180  }
  1181  
  1182  // This test ensures that the effective GOARCH variable in the
  1183  // application determines the Sizes function used by the type checker.
  1184  // This behavior is a stop-gap until we make the build system's query
  1185  // tool report the correct sizes function for the actual configuration.
  1186  func TestSizes(t *testing.T) { testAllOrModulesParallel(t, testSizes) }
  1187  func testSizes(t *testing.T, exporter packagestest.Exporter) {
  1188  	// Only run this test on operating systems that have both an amd64 and 386 port.
  1189  	switch runtime.GOOS {
  1190  	case "linux", "windows", "freebsd", "openbsd", "netbsd", "android":
  1191  	default:
  1192  		t.Skipf("skipping test on %s", runtime.GOOS)
  1193  	}
  1194  
  1195  	exported := packagestest.Export(t, exporter, []packagestest.Module{{
  1196  		Name: "golang.org/fake",
  1197  		Files: map[string]interface{}{
  1198  			"a/a.go": `package a; import "unsafe"; const WordSize = 8*unsafe.Sizeof(int(0))`,
  1199  		}}})
  1200  	defer exported.Cleanup()
  1201  
  1202  	exported.Config.Mode = packages.LoadSyntax
  1203  	savedEnv := exported.Config.Env
  1204  	for arch, wantWordSize := range map[string]int64{"386": 32, "amd64": 64} {
  1205  		exported.Config.Env = append(savedEnv, "GOARCH="+arch)
  1206  		initial, err := packages.Load(exported.Config, "golang.org/fake/a")
  1207  		if err != nil {
  1208  			t.Fatal(err)
  1209  		}
  1210  		if packages.PrintErrors(initial) > 0 {
  1211  			t.Fatal("there were errors")
  1212  		}
  1213  		gotWordSize, _ := constantpkg.Int64Val(constant(initial[0], "WordSize").Val())
  1214  		if gotWordSize != wantWordSize {
  1215  			t.Errorf("for GOARCH=%s, got word size %d, want %d", arch, gotWordSize, wantWordSize)
  1216  		}
  1217  	}
  1218  }
  1219  
  1220  // TestContainsFallbackSticks ensures that when there are both contains and non-contains queries
  1221  // the decision whether to fallback to the pre-1.11 go list sticks across both sets of calls to
  1222  // go list.
  1223  func TestContainsFallbackSticks(t *testing.T) {
  1224  	testAllOrModulesParallel(t, testContainsFallbackSticks)
  1225  }
  1226  func testContainsFallbackSticks(t *testing.T, exporter packagestest.Exporter) {
  1227  	exported := packagestest.Export(t, exporter, []packagestest.Module{{
  1228  		Name: "golang.org/fake",
  1229  		Files: map[string]interface{}{
  1230  			"a/a.go": `package a; import "golang.org/fake/b"`,
  1231  			"b/b.go": `package b; import "golang.org/fake/c"`,
  1232  			"c/c.go": `package c`,
  1233  		}}})
  1234  	defer exported.Cleanup()
  1235  
  1236  	exported.Config.Mode = packages.LoadImports
  1237  	bFile := exported.File("golang.org/fake", "b/b.go")
  1238  	initial, err := packages.Load(exported.Config, "golang.org/fake/a", "file="+bFile)
  1239  	if err != nil {
  1240  		t.Fatal(err)
  1241  	}
  1242  
  1243  	graph, _ := importGraph(initial)
  1244  	wantGraph := `
  1245  * golang.org/fake/a
  1246  * golang.org/fake/b
  1247    golang.org/fake/c
  1248    golang.org/fake/a -> golang.org/fake/b
  1249    golang.org/fake/b -> golang.org/fake/c
  1250  `[1:]
  1251  	if graph != wantGraph {
  1252  		t.Errorf("wrong import graph: got <<%s>>, want <<%s>>", graph, wantGraph)
  1253  	}
  1254  }
  1255  
  1256  // Test that Load with no patterns is equivalent to loading "." via the golist
  1257  // driver.
  1258  func TestNoPatterns(t *testing.T) { testAllOrModulesParallel(t, testNoPatterns) }
  1259  func testNoPatterns(t *testing.T, exporter packagestest.Exporter) {
  1260  	exported := packagestest.Export(t, exporter, []packagestest.Module{{
  1261  		Name: "golang.org/fake",
  1262  		Files: map[string]interface{}{
  1263  			"a/a.go":   `package a;`,
  1264  			"a/b/b.go": `package b;`,
  1265  		}}})
  1266  	defer exported.Cleanup()
  1267  
  1268  	aDir := filepath.Dir(exported.File("golang.org/fake", "a/a.go"))
  1269  	exported.Config.Dir = aDir
  1270  
  1271  	initial, err := packages.Load(exported.Config)
  1272  	if err != nil {
  1273  		t.Fatal(err)
  1274  	}
  1275  	if len(initial) != 1 || initial[0].Name != "a" {
  1276  		t.Fatalf(`Load() = %v, wanted just the package in the current directory`, initial)
  1277  	}
  1278  }
  1279  
  1280  func TestJSON(t *testing.T) { testAllOrModulesParallel(t, testJSON) }
  1281  func testJSON(t *testing.T, exporter packagestest.Exporter) {
  1282  	//TODO: add in some errors
  1283  	exported := packagestest.Export(t, exporter, []packagestest.Module{{
  1284  		Name: "golang.org/fake",
  1285  		Files: map[string]interface{}{
  1286  			"a/a.go": `package a; const A = 1`,
  1287  			"b/b.go": `package b; import "golang.org/fake/a"; var B = a.A`,
  1288  			"c/c.go": `package c; import "golang.org/fake/b" ; var C = b.B`,
  1289  			"d/d.go": `package d; import "golang.org/fake/b" ; var D = b.B`,
  1290  		}}})
  1291  	defer exported.Cleanup()
  1292  
  1293  	exported.Config.Mode = packages.LoadImports
  1294  	initial, err := packages.Load(exported.Config, "golang.org/fake/c", "golang.org/fake/d")
  1295  	if err != nil {
  1296  		t.Fatal(err)
  1297  	}
  1298  
  1299  	// Visit and print all packages.
  1300  	buf := &bytes.Buffer{}
  1301  	enc := json.NewEncoder(buf)
  1302  	enc.SetIndent("", "\t")
  1303  	packages.Visit(initial, nil, func(pkg *packages.Package) {
  1304  		// trim the source lists for stable results
  1305  		pkg.GoFiles = cleanPaths(pkg.GoFiles)
  1306  		pkg.CompiledGoFiles = cleanPaths(pkg.CompiledGoFiles)
  1307  		pkg.OtherFiles = cleanPaths(pkg.OtherFiles)
  1308  		pkg.IgnoredFiles = cleanPaths(pkg.IgnoredFiles)
  1309  		if err := enc.Encode(pkg); err != nil {
  1310  			t.Fatal(err)
  1311  		}
  1312  	})
  1313  
  1314  	wantJSON := `
  1315  {
  1316  	"ID": "golang.org/fake/a",
  1317  	"Name": "a",
  1318  	"PkgPath": "golang.org/fake/a",
  1319  	"GoFiles": [
  1320  		"a.go"
  1321  	],
  1322  	"CompiledGoFiles": [
  1323  		"a.go"
  1324  	]
  1325  }
  1326  {
  1327  	"ID": "golang.org/fake/b",
  1328  	"Name": "b",
  1329  	"PkgPath": "golang.org/fake/b",
  1330  	"GoFiles": [
  1331  		"b.go"
  1332  	],
  1333  	"CompiledGoFiles": [
  1334  		"b.go"
  1335  	],
  1336  	"Imports": {
  1337  		"golang.org/fake/a": "golang.org/fake/a"
  1338  	}
  1339  }
  1340  {
  1341  	"ID": "golang.org/fake/c",
  1342  	"Name": "c",
  1343  	"PkgPath": "golang.org/fake/c",
  1344  	"GoFiles": [
  1345  		"c.go"
  1346  	],
  1347  	"CompiledGoFiles": [
  1348  		"c.go"
  1349  	],
  1350  	"Imports": {
  1351  		"golang.org/fake/b": "golang.org/fake/b"
  1352  	}
  1353  }
  1354  {
  1355  	"ID": "golang.org/fake/d",
  1356  	"Name": "d",
  1357  	"PkgPath": "golang.org/fake/d",
  1358  	"GoFiles": [
  1359  		"d.go"
  1360  	],
  1361  	"CompiledGoFiles": [
  1362  		"d.go"
  1363  	],
  1364  	"Imports": {
  1365  		"golang.org/fake/b": "golang.org/fake/b"
  1366  	}
  1367  }
  1368  `[1:]
  1369  
  1370  	if buf.String() != wantJSON {
  1371  		t.Errorf("wrong JSON: got <<%s>>, want <<%s>>", buf.String(), wantJSON)
  1372  	}
  1373  	// now decode it again
  1374  	var decoded []*packages.Package
  1375  	dec := json.NewDecoder(buf)
  1376  	for dec.More() {
  1377  		p := new(packages.Package)
  1378  		if err := dec.Decode(p); err != nil {
  1379  			t.Fatal(err)
  1380  		}
  1381  		decoded = append(decoded, p)
  1382  	}
  1383  	if len(decoded) != 4 {
  1384  		t.Fatalf("got %d packages, want 4", len(decoded))
  1385  	}
  1386  	for i, want := range []*packages.Package{{
  1387  		ID:   "golang.org/fake/a",
  1388  		Name: "a",
  1389  	}, {
  1390  		ID:   "golang.org/fake/b",
  1391  		Name: "b",
  1392  		Imports: map[string]*packages.Package{
  1393  			"golang.org/fake/a": {ID: "golang.org/fake/a"},
  1394  		},
  1395  	}, {
  1396  		ID:   "golang.org/fake/c",
  1397  		Name: "c",
  1398  		Imports: map[string]*packages.Package{
  1399  			"golang.org/fake/b": {ID: "golang.org/fake/b"},
  1400  		},
  1401  	}, {
  1402  		ID:   "golang.org/fake/d",
  1403  		Name: "d",
  1404  		Imports: map[string]*packages.Package{
  1405  			"golang.org/fake/b": {ID: "golang.org/fake/b"},
  1406  		},
  1407  	}} {
  1408  		got := decoded[i]
  1409  		if got.ID != want.ID {
  1410  			t.Errorf("Package %d has ID %q want %q", i, got.ID, want.ID)
  1411  		}
  1412  		if got.Name != want.Name {
  1413  			t.Errorf("Package %q has Name %q want %q", got.ID, got.Name, want.Name)
  1414  		}
  1415  		if len(got.Imports) != len(want.Imports) {
  1416  			t.Errorf("Package %q has %d imports want %d", got.ID, len(got.Imports), len(want.Imports))
  1417  			continue
  1418  		}
  1419  		for path, ipkg := range got.Imports {
  1420  			if want.Imports[path] == nil {
  1421  				t.Errorf("Package %q has unexpected import %q", got.ID, path)
  1422  				continue
  1423  			}
  1424  			if want.Imports[path].ID != ipkg.ID {
  1425  				t.Errorf("Package %q import %q is %q want %q", got.ID, path, ipkg.ID, want.Imports[path].ID)
  1426  			}
  1427  		}
  1428  	}
  1429  }
  1430  
  1431  func TestRejectInvalidQueries(t *testing.T) {
  1432  	t.Parallel()
  1433  
  1434  	queries := []string{"key=", "key=value"}
  1435  	cfg := &packages.Config{
  1436  		Mode: packages.LoadImports,
  1437  		Env:  append(os.Environ(), "GO111MODULE=off", "GOPACKAGESDRIVER=off"),
  1438  	}
  1439  	for _, q := range queries {
  1440  		if _, err := packages.Load(cfg, q); err == nil {
  1441  			t.Errorf("packages.Load(%q) succeeded. Expected \"invalid query type\" error", q)
  1442  		} else if !strings.Contains(err.Error(), "invalid query type") {
  1443  			t.Errorf("packages.Load(%q): got error %v, want \"invalid query type\" error", q, err)
  1444  		}
  1445  	}
  1446  }
  1447  
  1448  func TestPatternPassthrough(t *testing.T) { testAllOrModulesParallel(t, testPatternPassthrough) }
  1449  func testPatternPassthrough(t *testing.T, exporter packagestest.Exporter) {
  1450  	exported := packagestest.Export(t, exporter, []packagestest.Module{{
  1451  		Name: "golang.org/fake",
  1452  		Files: map[string]interface{}{
  1453  			"a/a.go": `package a;`,
  1454  		}}})
  1455  	defer exported.Cleanup()
  1456  
  1457  	initial, err := packages.Load(exported.Config, "pattern=a")
  1458  	if err != nil {
  1459  		t.Fatal(err)
  1460  	}
  1461  
  1462  	graph, _ := importGraph(initial)
  1463  	wantGraph := `
  1464  * a
  1465  `[1:]
  1466  	if graph != wantGraph {
  1467  		t.Errorf("wrong import graph: got <<%s>>, want <<%s>>", graph, wantGraph)
  1468  	}
  1469  
  1470  }
  1471  
  1472  func TestConfigDefaultEnv(t *testing.T) {
  1473  	// packagestest.TestAll instead of testAllOrModulesParallel because this test
  1474  	// can't be parallelized (it modifies the environment).
  1475  	packagestest.TestAll(t, testConfigDefaultEnv)
  1476  }
  1477  func testConfigDefaultEnv(t *testing.T, exporter packagestest.Exporter) {
  1478  	const driverJSON = `{
  1479    "Roots": ["gopackagesdriver"],
  1480    "Packages": [{"ID": "gopackagesdriver", "Name": "gopackagesdriver"}]
  1481  }`
  1482  	var (
  1483  		pathKey      string
  1484  		driverScript packagestest.Writer
  1485  	)
  1486  	switch runtime.GOOS {
  1487  	case "android":
  1488  		t.Skip("doesn't run on android")
  1489  	case "windows":
  1490  		// TODO(jayconrod): write an equivalent batch script for windows.
  1491  		// Hint: "type" can be used to read a file to stdout.
  1492  		t.Skip("test requires sh")
  1493  	case "plan9":
  1494  		pathKey = "path"
  1495  		driverScript = packagestest.Script(`#!/bin/rc
  1496  
  1497  cat <<'EOF'
  1498  ` + driverJSON + `
  1499  EOF
  1500  `)
  1501  	default:
  1502  		pathKey = "PATH"
  1503  		driverScript = packagestest.Script(`#!/bin/sh
  1504  
  1505  cat - <<'EOF'
  1506  ` + driverJSON + `
  1507  EOF
  1508  `)
  1509  	}
  1510  	exported := packagestest.Export(t, exporter, []packagestest.Module{{
  1511  		Name: "golang.org/fake",
  1512  		Files: map[string]interface{}{
  1513  			"bin/gopackagesdriver": driverScript,
  1514  			"golist/golist.go":     "package golist",
  1515  		}}})
  1516  	defer exported.Cleanup()
  1517  	driver := exported.File("golang.org/fake", "bin/gopackagesdriver")
  1518  	binDir := filepath.Dir(driver)
  1519  	if err := os.Chmod(driver, 0755); err != nil {
  1520  		t.Fatal(err)
  1521  	}
  1522  
  1523  	path, ok := os.LookupEnv(pathKey)
  1524  	var pathWithDriver string
  1525  	if ok {
  1526  		pathWithDriver = binDir + string(os.PathListSeparator) + path
  1527  	} else {
  1528  		pathWithDriver = binDir
  1529  	}
  1530  	for _, test := range []struct {
  1531  		desc    string
  1532  		path    string
  1533  		driver  string
  1534  		wantIDs string
  1535  	}{
  1536  		{
  1537  			desc:    "driver_off",
  1538  			path:    pathWithDriver,
  1539  			driver:  "off",
  1540  			wantIDs: "[golist]",
  1541  		}, {
  1542  			desc:    "driver_unset",
  1543  			path:    pathWithDriver,
  1544  			driver:  "",
  1545  			wantIDs: "[gopackagesdriver]",
  1546  		}, {
  1547  			desc:    "driver_set",
  1548  			path:    "",
  1549  			driver:  driver,
  1550  			wantIDs: "[gopackagesdriver]",
  1551  		},
  1552  	} {
  1553  		t.Run(test.desc, func(t *testing.T) {
  1554  			oldPath := os.Getenv(pathKey)
  1555  			os.Setenv(pathKey, test.path)
  1556  			defer os.Setenv(pathKey, oldPath)
  1557  			// Clone exported.Config
  1558  			config := exported.Config
  1559  			config.Env = append([]string{}, exported.Config.Env...)
  1560  			config.Env = append(config.Env, "GOPACKAGESDRIVER="+test.driver)
  1561  			pkgs, err := packages.Load(exported.Config, "golist")
  1562  			if err != nil {
  1563  				t.Fatal(err)
  1564  			}
  1565  
  1566  			gotIds := make([]string, len(pkgs))
  1567  			for i, pkg := range pkgs {
  1568  				gotIds[i] = pkg.ID
  1569  			}
  1570  			if fmt.Sprint(pkgs) != test.wantIDs {
  1571  				t.Errorf("got %v; want %v", gotIds, test.wantIDs)
  1572  			}
  1573  		})
  1574  	}
  1575  }
  1576  
  1577  // This test that a simple x test package layout loads correctly.
  1578  // There was a bug in go list where it returned multiple copies of the same
  1579  // package (specifically in this case of golang.org/fake/a), and this triggered
  1580  // a bug in go/packages where it would leave an empty entry in the root package
  1581  // list. This would then cause a nil pointer crash.
  1582  // This bug was triggered by the simple package layout below, and thus this
  1583  // test will make sure the bug remains fixed.
  1584  func TestBasicXTest(t *testing.T) { testAllOrModulesParallel(t, testBasicXTest) }
  1585  func testBasicXTest(t *testing.T, exporter packagestest.Exporter) {
  1586  	exported := packagestest.Export(t, exporter, []packagestest.Module{{
  1587  		Name: "golang.org/fake",
  1588  		Files: map[string]interface{}{
  1589  			"a/a.go":      `package a;`,
  1590  			"a/a_test.go": `package a_test;`,
  1591  		}}})
  1592  	defer exported.Cleanup()
  1593  
  1594  	exported.Config.Mode = packages.LoadFiles
  1595  	exported.Config.Tests = true
  1596  	_, err := packages.Load(exported.Config, "golang.org/fake/a")
  1597  	if err != nil {
  1598  		t.Fatal(err)
  1599  	}
  1600  }
  1601  
  1602  func TestErrorMissingFile(t *testing.T) { testAllOrModulesParallel(t, testErrorMissingFile) }
  1603  func testErrorMissingFile(t *testing.T, exporter packagestest.Exporter) {
  1604  	exported := packagestest.Export(t, exporter, []packagestest.Module{{
  1605  		Name: "golang.org/fake",
  1606  		Files: map[string]interface{}{
  1607  			"a/a_test.go": `package a;`,
  1608  		}}})
  1609  	defer exported.Cleanup()
  1610  
  1611  	exported.Config.Mode = packages.LoadSyntax
  1612  	exported.Config.Tests = false
  1613  	pkgs, err := packages.Load(exported.Config, "missing.go")
  1614  	if err != nil {
  1615  		t.Fatal(err)
  1616  	}
  1617  	if len(pkgs) == 0 && runtime.GOOS == "windows" {
  1618  		t.Skip("Issue #31344: the ad-hoc command-line-arguments package isn't created on windows")
  1619  	}
  1620  	if len(pkgs) != 1 || (pkgs[0].PkgPath != "command-line-arguments" && pkgs[0].PkgPath != "missing.go") {
  1621  		t.Fatalf("packages.Load: want [command-line-arguments] or [missing.go], got %v", pkgs)
  1622  	}
  1623  	if len(pkgs[0].Errors) == 0 {
  1624  		t.Errorf("result of Load: want package with errors, got none: %+v", pkgs[0])
  1625  	}
  1626  }
  1627  
  1628  func TestReturnErrorWhenUsingNonGoFiles(t *testing.T) {
  1629  	testAllOrModulesParallel(t, testReturnErrorWhenUsingNonGoFiles)
  1630  }
  1631  func testReturnErrorWhenUsingNonGoFiles(t *testing.T, exporter packagestest.Exporter) {
  1632  	exported := packagestest.Export(t, exporter, []packagestest.Module{{
  1633  		Name: "golang.org/gopatha",
  1634  		Files: map[string]interface{}{
  1635  			"a/a.go": `package a`,
  1636  		}}, {
  1637  		Name: "golang.org/gopathb",
  1638  		Files: map[string]interface{}{
  1639  			"b/b.c": `package b`,
  1640  		}}})
  1641  	defer exported.Cleanup()
  1642  	config := packages.Config{Env: append(os.Environ(), "GOPACKAGESDRIVER=off")}
  1643  	pkgs, err := packages.Load(&config, "b/b.c")
  1644  	if err != nil {
  1645  		return
  1646  	}
  1647  	// Go <1.14 calls the package command-line-arguments while Go 1.14+ uses the file names.
  1648  	if len(pkgs) != 1 || (pkgs[0].PkgPath != "command-line-arguments" && pkgs[0].PkgPath != "b/b.c") {
  1649  		t.Fatalf("packages.Load: want [command-line-arguments] or [b/b.c], got %v", pkgs)
  1650  	}
  1651  	if len(pkgs[0].Errors) != 1 {
  1652  		t.Fatalf("result of Load: want package with one error, got: %+v", pkgs[0])
  1653  	}
  1654  }
  1655  
  1656  func TestReturnErrorWhenUsingGoFilesInMultipleDirectories(t *testing.T) {
  1657  	testAllOrModulesParallel(t, testReturnErrorWhenUsingGoFilesInMultipleDirectories)
  1658  }
  1659  func testReturnErrorWhenUsingGoFilesInMultipleDirectories(t *testing.T, exporter packagestest.Exporter) {
  1660  	exported := packagestest.Export(t, exporter, []packagestest.Module{{
  1661  		Name: "golang.org/gopatha",
  1662  		Files: map[string]interface{}{
  1663  			"a/a.go": `package a`,
  1664  			"b/b.go": `package b`,
  1665  		}}})
  1666  	defer exported.Cleanup()
  1667  	want := "named files must all be in one directory"
  1668  	pkgs, err := packages.Load(exported.Config, exported.File("golang.org/gopatha", "a/a.go"), exported.File("golang.org/gopatha", "b/b.go"))
  1669  	if err != nil {
  1670  		// Check if the error returned is the one we expected.
  1671  		if !strings.Contains(err.Error(), want) {
  1672  			t.Fatalf("want error message: %s, got: %s", want, err.Error())
  1673  		}
  1674  		return
  1675  	}
  1676  	if len(pkgs) != 1 || pkgs[0].PkgPath != "command-line-arguments" {
  1677  		t.Fatalf("packages.Load: want [command-line-arguments], got %v", pkgs)
  1678  	}
  1679  	if len(pkgs[0].Errors) != 1 {
  1680  		t.Fatalf("result of Load: want package with one error, got: %+v", pkgs[0])
  1681  	}
  1682  	got := pkgs[0].Errors[0].Error()
  1683  	if !strings.Contains(got, want) {
  1684  		t.Fatalf("want error message: %s, got: %s", want, got)
  1685  	}
  1686  }
  1687  
  1688  func TestReturnErrorForUnexpectedDirectoryLayout(t *testing.T) {
  1689  	testAllOrModulesParallel(t, testReturnErrorForUnexpectedDirectoryLayout)
  1690  }
  1691  func testReturnErrorForUnexpectedDirectoryLayout(t *testing.T, exporter packagestest.Exporter) {
  1692  	exported := packagestest.Export(t, exporter, []packagestest.Module{{
  1693  		Name: "golang.org/gopatha",
  1694  		Files: map[string]interface{}{
  1695  			"a/testdata/a.go": `package a; import _ "b"`,
  1696  			"a/vendor/b/b.go": `package b; import _ "fmt"`,
  1697  		}}})
  1698  	defer exported.Cleanup()
  1699  	want := "unexpected directory layout"
  1700  	// triggering this error requires a relative package path
  1701  	exported.Config.Dir = filepath.Dir(exported.File("golang.org/gopatha", "a/testdata/a.go"))
  1702  	pkgs, err := packages.Load(exported.Config, ".")
  1703  
  1704  	// This error doesn't seem to occur in module mode; so only
  1705  	// complain if we get zero packages while also getting no error.
  1706  	if err == nil {
  1707  		if len(pkgs) == 0 {
  1708  			// TODO(dh): we'll need to expand on the error check if/when Go stops emitting this error
  1709  			t.Fatalf("want error, got nil")
  1710  		}
  1711  		return
  1712  	}
  1713  	// Check if the error returned is the one we expected.
  1714  	if !strings.Contains(err.Error(), want) {
  1715  		t.Fatalf("want error message: %s, got: %s", want, err.Error())
  1716  	}
  1717  }
  1718  
  1719  func TestMissingDependency(t *testing.T) { testAllOrModulesParallel(t, testMissingDependency) }
  1720  func testMissingDependency(t *testing.T, exporter packagestest.Exporter) {
  1721  	exported := packagestest.Export(t, exporter, []packagestest.Module{{
  1722  		Name: "golang.org/fake",
  1723  		Files: map[string]interface{}{
  1724  			"a/a.go": `package a; import _ "this/package/doesnt/exist"`,
  1725  		}}})
  1726  	defer exported.Cleanup()
  1727  
  1728  	exported.Config.Mode = packages.LoadAllSyntax
  1729  	pkgs, err := packages.Load(exported.Config, "golang.org/fake/a")
  1730  	if err != nil {
  1731  		t.Fatal(err)
  1732  	}
  1733  	if len(pkgs) != 1 && pkgs[0].PkgPath != "golang.org/fake/a" {
  1734  		t.Fatalf("packages.Load: want [golang.org/fake/a], got %v", pkgs)
  1735  	}
  1736  	if len(pkgs[0].Errors) == 0 {
  1737  		t.Errorf("result of Load: want package with errors, got none: %+v", pkgs[0])
  1738  	}
  1739  }
  1740  
  1741  func TestAdHocContains(t *testing.T) { testAllOrModulesParallel(t, testAdHocContains) }
  1742  func testAdHocContains(t *testing.T, exporter packagestest.Exporter) {
  1743  	exported := packagestest.Export(t, exporter, []packagestest.Module{{
  1744  		Name: "golang.org/fake",
  1745  		Files: map[string]interface{}{
  1746  			"a/a.go": `package a;`,
  1747  		}}})
  1748  	defer exported.Cleanup()
  1749  
  1750  	tmpfile, err := ioutil.TempFile("", "adhoc*.go")
  1751  	filename := tmpfile.Name()
  1752  	if err != nil {
  1753  		t.Fatal(err)
  1754  	}
  1755  	fmt.Fprint(tmpfile, `package main; import "fmt"; func main() { fmt.Println("time for coffee") }`)
  1756  	if err := tmpfile.Close(); err != nil {
  1757  		t.Fatal(err)
  1758  	}
  1759  
  1760  	defer func() {
  1761  		if err := os.Remove(filename); err != nil {
  1762  			t.Fatal(err)
  1763  		}
  1764  	}()
  1765  
  1766  	exported.Config.Mode = packages.NeedImports | packages.NeedFiles
  1767  	pkgs, err := packages.Load(exported.Config, "file="+filename)
  1768  	if err != nil {
  1769  		t.Fatal(err)
  1770  	}
  1771  	if len(pkgs) != 1 && pkgs[0].PkgPath != "command-line-arguments" {
  1772  		t.Fatalf("packages.Load: want [command-line-arguments], got %v", pkgs)
  1773  	}
  1774  	pkg := pkgs[0]
  1775  	if _, ok := pkg.Imports["fmt"]; !ok || len(pkg.Imports) != 1 {
  1776  		t.Fatalf("Imports of loaded package: want [fmt], got %v", pkg.Imports)
  1777  	}
  1778  	if len(pkg.GoFiles) != 1 || pkg.GoFiles[0] != filename {
  1779  		t.Fatalf("GoFiles of loaded package: want [%s], got %v", filename, pkg.GoFiles)
  1780  	}
  1781  }
  1782  
  1783  func TestCgoNoCcompiler(t *testing.T) { testAllOrModulesParallel(t, testCgoNoCcompiler) }
  1784  func testCgoNoCcompiler(t *testing.T, exporter packagestest.Exporter) {
  1785  	testenv.NeedsTool(t, "cgo")
  1786  	exported := packagestest.Export(t, exporter, []packagestest.Module{{
  1787  		Name: "golang.org/fake",
  1788  		Files: map[string]interface{}{
  1789  			"a/a.go": `package a
  1790  import "net/http"
  1791  const A = http.MethodGet
  1792  `,
  1793  		}}})
  1794  	defer exported.Cleanup()
  1795  
  1796  	// Explicitly enable cgo but configure a nonexistent C compiler.
  1797  	exported.Config.Env = append(exported.Config.Env, "CGO_ENABLED=1", "CC=doesnotexist")
  1798  	exported.Config.Mode = packages.LoadAllSyntax
  1799  	initial, err := packages.Load(exported.Config, "golang.org/fake/a")
  1800  
  1801  	if err != nil {
  1802  		t.Fatal(err)
  1803  	}
  1804  
  1805  	// Check value of a.A.
  1806  	a := initial[0]
  1807  	aA := constant(a, "A")
  1808  	if aA == nil {
  1809  		t.Fatalf("a.A: got nil")
  1810  	}
  1811  	got := aA.Val().String()
  1812  	if got != "\"GET\"" {
  1813  		t.Errorf("a.A: got %s, want %s", got, "\"GET\"")
  1814  	}
  1815  }
  1816  
  1817  func TestCgoMissingFile(t *testing.T) { testAllOrModulesParallel(t, testCgoMissingFile) }
  1818  func testCgoMissingFile(t *testing.T, exporter packagestest.Exporter) {
  1819  	testenv.NeedsTool(t, "cgo")
  1820  	exported := packagestest.Export(t, exporter, []packagestest.Module{{
  1821  		Name: "golang.org/fake",
  1822  		Files: map[string]interface{}{
  1823  			"a/a.go": `package a
  1824  
  1825  // #include "foo.h"
  1826  import "C"
  1827  
  1828  const A = 4
  1829  `,
  1830  		}}})
  1831  	defer exported.Cleanup()
  1832  
  1833  	// Explicitly enable cgo.
  1834  	exported.Config.Env = append(exported.Config.Env, "CGO_ENABLED=1")
  1835  	exported.Config.Mode = packages.LoadAllSyntax
  1836  	initial, err := packages.Load(exported.Config, "golang.org/fake/a")
  1837  
  1838  	if err != nil {
  1839  		t.Fatal(err)
  1840  	}
  1841  
  1842  	// Check value of a.A.
  1843  	a := initial[0]
  1844  	aA := constant(a, "A")
  1845  	if aA == nil {
  1846  		t.Fatalf("a.A: got nil")
  1847  	}
  1848  	got := aA.Val().String()
  1849  	if got != "4" {
  1850  		t.Errorf("a.A: got %s, want %s", got, "4")
  1851  	}
  1852  }
  1853  
  1854  func TestLoadImportsC(t *testing.T) {
  1855  	// This test checks that when a package depends on the
  1856  	// test variant of "syscall", "unsafe", or "runtime/cgo", that dependency
  1857  	// is not removed when those packages are added when it imports "C".
  1858  	//
  1859  	// For this test to work, the external test of syscall must have a dependency
  1860  	// on net, and net must import "syscall" and "C".
  1861  	if runtime.GOOS == "windows" {
  1862  		t.Skipf("skipping on windows; packages on windows do not satisfy conditions for test.")
  1863  	}
  1864  	if runtime.GOOS == "plan9" {
  1865  		// See https://golang.org/issue/27100.
  1866  		t.Skip(`skipping on plan9; for some reason "net [syscall.test]" is not loaded`)
  1867  	}
  1868  	t.Parallel()
  1869  	testenv.NeedsGoPackages(t)
  1870  
  1871  	cfg := &packages.Config{
  1872  		Context: testCtx,
  1873  		Mode:    packages.LoadImports,
  1874  		Tests:   true,
  1875  	}
  1876  	initial, err := packages.Load(cfg, "syscall", "net")
  1877  	if err != nil {
  1878  		t.Fatalf("failed to load imports: %v", err)
  1879  	}
  1880  
  1881  	_, all := importGraph(initial)
  1882  
  1883  	for _, test := range []struct {
  1884  		pattern    string
  1885  		wantImport string // an import to check for
  1886  	}{
  1887  		{"net", "syscall:syscall"},
  1888  		{"net [syscall.test]", "syscall:syscall [syscall.test]"},
  1889  		{"syscall_test [syscall.test]", "net:net [syscall.test]"},
  1890  	} {
  1891  		// Test the import paths.
  1892  		pkg := all[test.pattern]
  1893  		if pkg == nil {
  1894  			t.Errorf("package %q not loaded", test.pattern)
  1895  			continue
  1896  		}
  1897  		if imports := strings.Join(imports(pkg), " "); !strings.Contains(imports, test.wantImport) {
  1898  			t.Errorf("package %q: got \n%s, \nwant to have %s", test.pattern, imports, test.wantImport)
  1899  		}
  1900  	}
  1901  }
  1902  
  1903  func TestCgoNoSyntax(t *testing.T) {
  1904  	testAllOrModulesParallel(t, testCgoNoSyntax)
  1905  }
  1906  func testCgoNoSyntax(t *testing.T, exporter packagestest.Exporter) {
  1907  	testenv.NeedsTool(t, "cgo")
  1908  
  1909  	exported := packagestest.Export(t, exporter, []packagestest.Module{{
  1910  		Name: "golang.org/fake",
  1911  		Files: map[string]interface{}{
  1912  			"c/c.go": `package c; import "C"`,
  1913  		},
  1914  	}})
  1915  
  1916  	// Explicitly enable cgo.
  1917  	exported.Config.Env = append(exported.Config.Env, "CGO_ENABLED=1")
  1918  
  1919  	modes := []packages.LoadMode{
  1920  		packages.NeedTypes,
  1921  		packages.NeedName | packages.NeedTypes,
  1922  		packages.NeedName | packages.NeedTypes | packages.NeedImports,
  1923  		packages.NeedName | packages.NeedTypes | packages.NeedImports | packages.NeedDeps,
  1924  		packages.NeedName | packages.NeedImports,
  1925  	}
  1926  	for _, mode := range modes {
  1927  		mode := mode
  1928  		t.Run(fmt.Sprint(mode), func(t *testing.T) {
  1929  			exported.Config.Mode = mode
  1930  			pkgs, err := packages.Load(exported.Config, "golang.org/fake/c")
  1931  			if err != nil {
  1932  				t.Fatal(err)
  1933  			}
  1934  			if len(pkgs) != 1 {
  1935  				t.Fatalf("Expected 1 package, got %v", pkgs)
  1936  			}
  1937  			pkg := pkgs[0]
  1938  			if len(pkg.Errors) != 0 {
  1939  				t.Fatalf("Expected no errors in package, got %v", pkg.Errors)
  1940  			}
  1941  		})
  1942  	}
  1943  }
  1944  
  1945  func TestCgoBadPkgConfig(t *testing.T) {
  1946  	testAllOrModulesParallel(t, testCgoBadPkgConfig)
  1947  }
  1948  func testCgoBadPkgConfig(t *testing.T, exporter packagestest.Exporter) {
  1949  	skipIfShort(t, "builds and links a fake pkgconfig binary")
  1950  	testenv.NeedsTool(t, "cgo")
  1951  
  1952  	exported := packagestest.Export(t, exporter, []packagestest.Module{{
  1953  		Name: "golang.org/fake",
  1954  		Files: map[string]interface{}{
  1955  			"c/c.go": `package c
  1956  
  1957  // #cgo pkg-config: --cflags --  foo
  1958  import "C"`,
  1959  		},
  1960  	}})
  1961  
  1962  	dir := buildFakePkgconfig(t, exported.Config.Env)
  1963  	defer os.RemoveAll(dir)
  1964  	env := exported.Config.Env
  1965  	for i, v := range env {
  1966  		if strings.HasPrefix(v, "PATH=") {
  1967  			env[i] = "PATH=" + dir + string(os.PathListSeparator) + v[len("PATH="):]
  1968  		}
  1969  	}
  1970  
  1971  	exported.Config.Env = append(exported.Config.Env, "CGO_ENABLED=1")
  1972  
  1973  	exported.Config.Mode = packages.NeedName | packages.NeedCompiledGoFiles
  1974  	pkgs, err := packages.Load(exported.Config, "golang.org/fake/c")
  1975  	if err != nil {
  1976  		t.Fatal(err)
  1977  	}
  1978  	if len(pkgs) != 1 {
  1979  		t.Fatalf("Expected 1 package, got %v", pkgs)
  1980  	}
  1981  	if pkgs[0].Name != "c" {
  1982  		t.Fatalf("Expected package to have name \"c\", got %q", pkgs[0].Name)
  1983  	}
  1984  }
  1985  
  1986  func buildFakePkgconfig(t *testing.T, env []string) string {
  1987  	tmpdir, err := ioutil.TempDir("", "fakepkgconfig")
  1988  	if err != nil {
  1989  		t.Fatal(err)
  1990  	}
  1991  	err = ioutil.WriteFile(filepath.Join(tmpdir, "pkg-config.go"), []byte(`
  1992  package main
  1993  
  1994  import "fmt"
  1995  import "os"
  1996  
  1997  func main() {
  1998  	fmt.Fprintln(os.Stderr, "bad")
  1999  	os.Exit(2)
  2000  }
  2001  `), 0644)
  2002  	if err != nil {
  2003  		os.RemoveAll(tmpdir)
  2004  		t.Fatal(err)
  2005  	}
  2006  	cmd := exec.Command("go", "build", "-o", "pkg-config", "pkg-config.go")
  2007  	cmd.Dir = tmpdir
  2008  	cmd.Env = env
  2009  
  2010  	if b, err := cmd.CombinedOutput(); err != nil {
  2011  		os.RemoveAll(tmpdir)
  2012  		fmt.Println(os.Environ())
  2013  		t.Log(string(b))
  2014  		t.Fatal(err)
  2015  	}
  2016  	return tmpdir
  2017  }
  2018  
  2019  func TestIssue32814(t *testing.T) { testAllOrModulesParallel(t, testIssue32814) }
  2020  func testIssue32814(t *testing.T, exporter packagestest.Exporter) {
  2021  	exported := packagestest.Export(t, exporter, []packagestest.Module{{
  2022  		Name:  "golang.org/fake",
  2023  		Files: map[string]interface{}{}}})
  2024  	defer exported.Cleanup()
  2025  
  2026  	exported.Config.Mode = packages.NeedName | packages.NeedTypes | packages.NeedSyntax | packages.NeedTypesInfo | packages.NeedTypesSizes
  2027  	pkgs, err := packages.Load(exported.Config, "fmt")
  2028  
  2029  	if err != nil {
  2030  		t.Fatal(err)
  2031  	}
  2032  
  2033  	if len(pkgs) != 1 && pkgs[0].PkgPath != "fmt" {
  2034  		t.Fatalf("packages.Load: want [fmt], got %v", pkgs)
  2035  	}
  2036  	pkg := pkgs[0]
  2037  	if len(pkg.Errors) != 0 {
  2038  		t.Fatalf("Errors for fmt pkg: got %v, want none", pkg.Errors)
  2039  	}
  2040  	if !pkg.Types.Complete() {
  2041  		t.Fatalf("Types.Complete() for fmt pkg: got %v, want true", pkgs[0].Types.Complete())
  2042  
  2043  	}
  2044  }
  2045  
  2046  func TestLoadTypesInfoWithoutNeedDeps(t *testing.T) {
  2047  	testAllOrModulesParallel(t, testLoadTypesInfoWithoutNeedDeps)
  2048  }
  2049  func testLoadTypesInfoWithoutNeedDeps(t *testing.T, exporter packagestest.Exporter) {
  2050  	exported := packagestest.Export(t, exporter, []packagestest.Module{{
  2051  		Name: "golang.org/fake",
  2052  		Files: map[string]interface{}{
  2053  			"a/a.go": `package a; import _ "golang.org/fake/b"`,
  2054  			"b/b.go": `package b`,
  2055  		}}})
  2056  	defer exported.Cleanup()
  2057  
  2058  	exported.Config.Mode = packages.NeedTypes | packages.NeedTypesInfo | packages.NeedImports
  2059  	pkgs, err := packages.Load(exported.Config, "golang.org/fake/a")
  2060  	if err != nil {
  2061  		t.Fatal(err)
  2062  	}
  2063  	pkg := pkgs[0]
  2064  	if pkg.IllTyped {
  2065  		t.Fatal("Loaded package is ill typed")
  2066  	}
  2067  	const expectedImport = "golang.org/fake/b"
  2068  	if _, ok := pkg.Imports[expectedImport]; !ok || len(pkg.Imports) != 1 {
  2069  		t.Fatalf("Imports of loaded package: want [%s], got %v", expectedImport, pkg.Imports)
  2070  	}
  2071  }
  2072  
  2073  func TestLoadWithNeedDeps(t *testing.T) {
  2074  	testAllOrModulesParallel(t, testLoadWithNeedDeps)
  2075  }
  2076  func testLoadWithNeedDeps(t *testing.T, exporter packagestest.Exporter) {
  2077  	exported := packagestest.Export(t, exporter, []packagestest.Module{{
  2078  		Name: "golang.org/fake",
  2079  		Files: map[string]interface{}{
  2080  			"a/a.go": `package a; import _ "golang.org/fake/b"`,
  2081  			"b/b.go": `package b; import _ "golang.org/fake/c"`,
  2082  			"c/c.go": `package c`,
  2083  		}}})
  2084  	defer exported.Cleanup()
  2085  
  2086  	exported.Config.Mode = packages.NeedTypes | packages.NeedTypesInfo | packages.NeedImports | packages.NeedDeps
  2087  	pkgs, err := packages.Load(exported.Config, "golang.org/fake/a")
  2088  	if err != nil {
  2089  		t.Fatal(err)
  2090  	}
  2091  	if len(pkgs) != 1 {
  2092  		t.Fatalf("Expected 1 package, got %d", len(pkgs))
  2093  	}
  2094  
  2095  	pkgA := pkgs[0]
  2096  	if pkgA.IllTyped {
  2097  		t.Fatal("Loaded package is ill typed")
  2098  	}
  2099  
  2100  	pkgB := pkgA.Imports["golang.org/fake/b"]
  2101  	if pkgB == nil || len(pkgA.Imports) != 1 {
  2102  		t.Fatalf("Imports of loaded package 'a' are invalid: %v", pkgA.Imports)
  2103  	}
  2104  	if pkgB.Types == nil || !pkgB.Types.Complete() || pkgB.TypesInfo == nil {
  2105  		t.Fatalf("Types of package 'b' are nil or incomplete: %v, %v", pkgB.Types, pkgB.TypesInfo)
  2106  	}
  2107  
  2108  	pkgC := pkgB.Imports["golang.org/fake/c"]
  2109  	if pkgC == nil || len(pkgB.Imports) != 1 {
  2110  		t.Fatalf("Imports of loaded package 'c' are invalid: %v", pkgB.Imports)
  2111  	}
  2112  	if pkgC.Types == nil || !pkgC.Types.Complete() || pkgC.TypesInfo == nil {
  2113  		t.Fatalf("Types of package 'b' are nil or incomplete: %v, %v", pkgC.Types, pkgC.TypesInfo)
  2114  	}
  2115  }
  2116  
  2117  func TestImpliedLoadMode(t *testing.T) {
  2118  	testAllOrModulesParallel(t, testImpliedLoadMode)
  2119  }
  2120  func testImpliedLoadMode(t *testing.T, exporter packagestest.Exporter) {
  2121  	exported := packagestest.Export(t, exporter, []packagestest.Module{{
  2122  		Name: "golang.org/fake",
  2123  		Files: map[string]interface{}{
  2124  			"a/a.go": `package a; import _ "golang.org/fake/b"`,
  2125  			"b/b.go": `package b`,
  2126  		}}})
  2127  	defer exported.Cleanup()
  2128  
  2129  	exported.Config.Mode = packages.NeedTypes | packages.NeedTypesInfo
  2130  	pkgs, err := packages.Load(exported.Config, "golang.org/fake/a")
  2131  	if err != nil {
  2132  		t.Fatal(err)
  2133  	}
  2134  	if len(pkgs) != 1 {
  2135  		t.Fatalf("Expected 1 package, got %d", len(pkgs))
  2136  	}
  2137  
  2138  	pkg := pkgs[0]
  2139  	if pkg.IllTyped {
  2140  		t.Fatalf("Loaded package is ill typed: %v", pkg.Errors)
  2141  	}
  2142  
  2143  	// Check that packages.NeedTypesInfo worked well.
  2144  	if !pkg.Types.Complete() {
  2145  		t.Fatalf("Loaded package types are incomplete")
  2146  	}
  2147  
  2148  	// Check that implied packages.NeedImports by packages.NeedTypesInfo
  2149  	// didn't add Imports.
  2150  	if len(pkg.Imports) != 0 {
  2151  		t.Fatalf("Package imports weren't requested but were returned: %v", pkg.Imports)
  2152  	}
  2153  }
  2154  
  2155  func TestIssue35331(t *testing.T) {
  2156  	testAllOrModulesParallel(t, testIssue35331)
  2157  }
  2158  func testIssue35331(t *testing.T, exporter packagestest.Exporter) {
  2159  	exported := packagestest.Export(t, exporter, []packagestest.Module{{
  2160  		Name: "golang.org/fake",
  2161  	}})
  2162  	defer exported.Cleanup()
  2163  
  2164  	exported.Config.Mode = packages.NeedName | packages.NeedFiles | packages.NeedCompiledGoFiles |
  2165  		packages.NeedImports | packages.NeedDeps | packages.NeedSyntax
  2166  	exported.Config.Tests = false
  2167  	pkgs, err := packages.Load(exported.Config, "strconv")
  2168  	if err != nil {
  2169  		t.Fatal(err)
  2170  	}
  2171  	if len(pkgs) != 1 {
  2172  		t.Fatalf("Expected 1 package, got %v", pkgs)
  2173  	}
  2174  	packages.Visit(pkgs, func(pkg *packages.Package) bool {
  2175  		if len(pkg.Errors) > 0 {
  2176  			t.Errorf("Expected no errors in package %q, got %v", pkg.ID, pkg.Errors)
  2177  		}
  2178  		if len(pkg.Syntax) == 0 && pkg.ID != "unsafe" {
  2179  			t.Errorf("Expected syntax on package %q, got none.", pkg.ID)
  2180  		}
  2181  		return true
  2182  	}, nil)
  2183  }
  2184  
  2185  func TestMultiplePackageVersionsIssue36188(t *testing.T) {
  2186  	testAllOrModulesParallel(t, testMultiplePackageVersionsIssue36188)
  2187  }
  2188  
  2189  func testMultiplePackageVersionsIssue36188(t *testing.T, exporter packagestest.Exporter) {
  2190  	exported := packagestest.Export(t, exporter, []packagestest.Module{{
  2191  		Name: "golang.org/fake",
  2192  		Files: map[string]interface{}{
  2193  			"a/a.go": `package a; import _ "golang.org/fake/b"`,
  2194  			"b/b.go": `package main`,
  2195  		}}})
  2196  	pkgs, err := packages.Load(exported.Config, "golang.org/fake/a", "golang.org/fake/b")
  2197  	if err != nil {
  2198  		t.Fatal(err)
  2199  	}
  2200  	sort.Slice(pkgs, func(i, j int) bool { return pkgs[i].ID < pkgs[j].ID })
  2201  	if len(pkgs) != 2 {
  2202  		t.Fatalf("expected two packages, got %v", pkgs)
  2203  	}
  2204  	if pkgs[0].ID != "golang.org/fake/a" && pkgs[1].ID != "golang.org/fake/b" {
  2205  		t.Fatalf(`expected (sorted) IDs "golang.org/fake/a" and "golang.org/fake/b", got %q and %q`,
  2206  			pkgs[0].ID, pkgs[1].ID)
  2207  	}
  2208  	if pkgs[0].Errors == nil {
  2209  		t.Errorf(`expected error on package "golang.org/fake/a", got none`)
  2210  	}
  2211  	if pkgs[1].Errors != nil {
  2212  		t.Errorf(`expected no errors on package "golang.org/fake/b", got %v`, pkgs[1].Errors)
  2213  	}
  2214  	defer exported.Cleanup()
  2215  }
  2216  
  2217  func TestLoadModeStrings(t *testing.T) {
  2218  	testcases := []struct {
  2219  		mode     packages.LoadMode
  2220  		expected string
  2221  	}{
  2222  		{
  2223  			packages.LoadMode(0),
  2224  			"LoadMode(0)",
  2225  		},
  2226  		{
  2227  			packages.NeedName,
  2228  			"LoadMode(NeedName)",
  2229  		},
  2230  		{
  2231  			packages.NeedFiles,
  2232  			"LoadMode(NeedFiles)",
  2233  		},
  2234  		{
  2235  			packages.NeedCompiledGoFiles,
  2236  			"LoadMode(NeedCompiledGoFiles)",
  2237  		},
  2238  		{
  2239  			packages.NeedImports,
  2240  			"LoadMode(NeedImports)",
  2241  		},
  2242  		{
  2243  			packages.NeedDeps,
  2244  			"LoadMode(NeedDeps)",
  2245  		},
  2246  		{
  2247  			packages.NeedExportFile,
  2248  			"LoadMode(NeedExportFile)",
  2249  		},
  2250  		{
  2251  			packages.NeedTypes,
  2252  			"LoadMode(NeedTypes)",
  2253  		},
  2254  		{
  2255  			packages.NeedSyntax,
  2256  			"LoadMode(NeedSyntax)",
  2257  		},
  2258  		{
  2259  			packages.NeedTypesInfo,
  2260  			"LoadMode(NeedTypesInfo)",
  2261  		},
  2262  		{
  2263  			packages.NeedTypesSizes,
  2264  			"LoadMode(NeedTypesSizes)",
  2265  		},
  2266  		{
  2267  			packages.NeedName | packages.NeedExportFile,
  2268  			"LoadMode(NeedName|NeedExportFile)",
  2269  		},
  2270  		{
  2271  			packages.NeedName | packages.NeedFiles | packages.NeedCompiledGoFiles | packages.NeedImports | packages.NeedDeps | packages.NeedExportFile | packages.NeedTypes | packages.NeedSyntax | packages.NeedTypesInfo | packages.NeedTypesSizes,
  2272  			"LoadMode(NeedName|NeedFiles|NeedCompiledGoFiles|NeedImports|NeedDeps|NeedExportFile|NeedTypes|NeedSyntax|NeedTypesInfo|NeedTypesSizes)",
  2273  		},
  2274  		{
  2275  			packages.NeedName | 8192,
  2276  			"LoadMode(NeedName|Unknown)",
  2277  		},
  2278  		{
  2279  			4096,
  2280  			"LoadMode(Unknown)",
  2281  		},
  2282  	}
  2283  
  2284  	for tcInd, tc := range testcases {
  2285  		t.Run(fmt.Sprintf("test-%d", tcInd), func(t *testing.T) {
  2286  			actual := tc.mode.String()
  2287  			if tc.expected != actual {
  2288  				t.Errorf("want %#v, got %#v", tc.expected, actual)
  2289  			}
  2290  		})
  2291  	}
  2292  }
  2293  
  2294  func TestCycleImportStack(t *testing.T) {
  2295  	testAllOrModulesParallel(t, testCycleImportStack)
  2296  }
  2297  func testCycleImportStack(t *testing.T, exporter packagestest.Exporter) {
  2298  	exported := packagestest.Export(t, exporter, []packagestest.Module{{
  2299  		Name: "golang.org/fake",
  2300  		Files: map[string]interface{}{
  2301  			"a/a.go": `package a; import _ "golang.org/fake/b"`,
  2302  			"b/b.go": `package b; import _ "golang.org/fake/a"`,
  2303  		}}})
  2304  	defer exported.Cleanup()
  2305  
  2306  	exported.Config.Mode = packages.NeedName | packages.NeedImports
  2307  	pkgs, err := packages.Load(exported.Config, "golang.org/fake/a")
  2308  	if err != nil {
  2309  		t.Fatal(err)
  2310  	}
  2311  	if len(pkgs) != 1 {
  2312  		t.Fatalf("Expected 1 package, got %v", pkgs)
  2313  	}
  2314  	pkg := pkgs[0]
  2315  	if len(pkg.Errors) != 1 {
  2316  		t.Fatalf("Expected one error in package, got %v", pkg.Errors)
  2317  	}
  2318  	expected := "import cycle not allowed: import stack: [golang.org/fake/a golang.org/fake/b golang.org/fake/a]"
  2319  	if pkg.Errors[0].Msg != expected {
  2320  		t.Fatalf("Expected error %q, got %q", expected, pkg.Errors[0].Msg)
  2321  	}
  2322  }
  2323  
  2324  func TestForTestField(t *testing.T) {
  2325  	testAllOrModulesParallel(t, testForTestField)
  2326  }
  2327  func testForTestField(t *testing.T, exporter packagestest.Exporter) {
  2328  	exported := packagestest.Export(t, exporter, []packagestest.Module{{
  2329  		Name: "golang.org/fake",
  2330  		Files: map[string]interface{}{
  2331  			"a/a.go":      `package a; func hello() {};`,
  2332  			"a/a_test.go": `package a; import "testing"; func TestA1(t *testing.T) {};`,
  2333  			"a/x_test.go": `package a_test; import "testing"; func TestA2(t *testing.T) {};`,
  2334  		}}})
  2335  	defer exported.Cleanup()
  2336  
  2337  	// Add overlays to make sure they don't affect anything.
  2338  	exported.Config.Overlay = map[string][]byte{
  2339  		"a/a_test.go": []byte(`package a; import "testing"; func TestA1(t *testing.T) { hello(); };`),
  2340  		"a/x_test.go": []byte(`package a_test; import "testing"; func TestA2(t *testing.T) { hello(); };`),
  2341  	}
  2342  	exported.Config.Tests = true
  2343  	exported.Config.Mode = packages.NeedName | packages.NeedImports
  2344  	forTest := "golang.org/fake/a"
  2345  	pkgs, err := packages.Load(exported.Config, forTest)
  2346  	if err != nil {
  2347  		t.Fatal(err)
  2348  	}
  2349  	if len(pkgs) != 4 {
  2350  		t.Errorf("expected 4 packages, got %v", len(pkgs))
  2351  	}
  2352  	for _, pkg := range pkgs {
  2353  		var hasTestFile bool
  2354  		for _, f := range pkg.CompiledGoFiles {
  2355  			if strings.Contains(f, "a_test.go") || strings.Contains(f, "x_test.go") {
  2356  				hasTestFile = true
  2357  				break
  2358  			}
  2359  		}
  2360  		if !hasTestFile {
  2361  			continue
  2362  		}
  2363  		got := packagesinternal.GetForTest(pkg)
  2364  		if got != forTest {
  2365  			t.Errorf("expected %q, got %q", forTest, got)
  2366  		}
  2367  	}
  2368  }
  2369  
  2370  func TestIssue37529(t *testing.T) {
  2371  	testAllOrModulesParallel(t, testIssue37529)
  2372  }
  2373  func testIssue37529(t *testing.T, exporter packagestest.Exporter) {
  2374  	// Tests #37529. When automatic vendoring is triggered, and we try to determine
  2375  	// the module root dir for a new overlay package, we previously would do a go list -m all,
  2376  	// which is incompatible with automatic vendoring.
  2377  
  2378  	exported := packagestest.Export(t, exporter, []packagestest.Module{{
  2379  		Name: "golang.org/fake",
  2380  		Files: map[string]interface{}{
  2381  			"c/c2.go":             `package c`,
  2382  			"a/a.go":              `package a; import "b.com/b"; const A = b.B`,
  2383  			"vendor/b.com/b/b.go": `package b; const B = 4`,
  2384  		}}})
  2385  	rootDir := filepath.Dir(filepath.Dir(exported.File("golang.org/fake", "a/a.go")))
  2386  	exported.Config.Overlay = map[string][]byte{
  2387  		filepath.Join(rootDir, "c/c.go"): []byte(`package c; import "golang.org/fake/a"; const C = a.A`),
  2388  	}
  2389  	exported.Config.Env = append(exported.Config.Env, "GOFLAGS=-mod=vendor")
  2390  	exported.Config.Mode = packages.LoadAllSyntax
  2391  
  2392  	defer exported.Cleanup()
  2393  
  2394  	initial, err := packages.Load(exported.Config, "golang.org/fake/c")
  2395  	if err != nil {
  2396  		t.Fatal(err)
  2397  	}
  2398  
  2399  	// Check value of a.A.
  2400  	a := initial[0]
  2401  	aA := constant(a, "C")
  2402  	if aA == nil {
  2403  		t.Fatalf("a.A: got nil")
  2404  	}
  2405  	got := aA.Val().String()
  2406  	if got != "4" {
  2407  		t.Errorf("a.A: got %s, want %s", got, "4")
  2408  	}
  2409  }
  2410  
  2411  func TestIssue37098(t *testing.T) { testAllOrModulesParallel(t, testIssue37098) }
  2412  func testIssue37098(t *testing.T, exporter packagestest.Exporter) {
  2413  	// packages.Load should only return Go sources in
  2414  	// (*Package).CompiledGoFiles.  This tests #37098, where using SWIG to
  2415  	// causes C++ sources to be inadvertently included in
  2416  	// (*Package).CompiledGoFiles.
  2417  
  2418  	// This is fixed in Go 1.17, but not earlier.
  2419  	testenv.NeedsGo1Point(t, 17)
  2420  
  2421  	if _, err := exec.LookPath("swig"); err != nil {
  2422  		t.Skip("skipping test: swig not available")
  2423  	}
  2424  	if _, err := exec.LookPath("g++"); err != nil {
  2425  		t.Skip("skipping test: g++ not available")
  2426  	}
  2427  
  2428  	// Create a fake package with an empty Go source, and a SWIG interface
  2429  	// file.
  2430  	exported := packagestest.Export(t, exporter, []packagestest.Module{{
  2431  		Name: "golang.org/fake",
  2432  		Files: map[string]interface{}{
  2433  			// The "package" statement must be included for SWIG sources to
  2434  			// be generated.
  2435  			"a/a.go":      "package a",
  2436  			"a/a.swigcxx": "",
  2437  		}}})
  2438  	defer exported.Cleanup()
  2439  
  2440  	initial, err := packages.Load(exported.Config, "golang.org/fake/a")
  2441  	if err != nil {
  2442  		t.Fatalf("failed to load the package: %v", err)
  2443  	}
  2444  	// Try and parse each of the files
  2445  	for _, pkg := range initial {
  2446  		for _, file := range pkg.CompiledGoFiles {
  2447  
  2448  			// Validate that each file can be parsed as a Go source.
  2449  			fset := token.NewFileSet()
  2450  			_, err := parser.ParseFile(fset, file, nil, parser.ImportsOnly)
  2451  			if err != nil {
  2452  				t.Errorf("Failed to parse file '%s' as a Go source: %v", file, err)
  2453  
  2454  				contents, err := ioutil.ReadFile(file)
  2455  				if err != nil {
  2456  					t.Fatalf("Failed to read the un-parsable file '%s': %v", file, err)
  2457  				}
  2458  
  2459  				// Print out some of the un-parsable file to aid in debugging.
  2460  				n := len(contents)
  2461  
  2462  				// Don't print the whole file if it is too large.
  2463  				const maxBytes = 1000
  2464  				if n > maxBytes {
  2465  					n = maxBytes
  2466  				}
  2467  
  2468  				t.Logf("First %d bytes of un-parsable file: %s", n, contents[:n])
  2469  			}
  2470  		}
  2471  	}
  2472  }
  2473  
  2474  // TestIssue56632 checks that CompiledGoFiles does not contain non-go files regardless of
  2475  // whether the NeedFiles mode bit is set.
  2476  func TestIssue56632(t *testing.T) {
  2477  	t.Parallel()
  2478  	testenv.NeedsGoBuild(t)
  2479  	testenv.NeedsTool(t, "cgo")
  2480  
  2481  	exported := packagestest.Export(t, packagestest.GOPATH, []packagestest.Module{{
  2482  		Name: "golang.org/issue56632",
  2483  		Files: map[string]interface{}{
  2484  			"a/a.go": `package a`,
  2485  			"a/a_cgo.go": `package a
  2486  
  2487  import "C"`,
  2488  			"a/a.s": ``,
  2489  			"a/a.c": ``,
  2490  		}}})
  2491  	defer exported.Cleanup()
  2492  
  2493  	modes := []packages.LoadMode{packages.NeedCompiledGoFiles, packages.NeedCompiledGoFiles | packages.NeedFiles, packages.NeedImports | packages.NeedCompiledGoFiles, packages.NeedImports | packages.NeedFiles | packages.NeedCompiledGoFiles}
  2494  	for _, mode := range modes {
  2495  		exported.Config.Mode = mode
  2496  
  2497  		initial, err := packages.Load(exported.Config, "golang.org/issue56632/a")
  2498  		if err != nil {
  2499  			t.Fatalf("failed to load package: %v", err)
  2500  		}
  2501  
  2502  		if len(initial) != 1 {
  2503  			t.Errorf("expected 3 packages, got %d", len(initial))
  2504  		}
  2505  
  2506  		p := initial[0]
  2507  
  2508  		if len(p.Errors) != 0 {
  2509  			t.Errorf("expected no errors, got %v", p.Errors)
  2510  		}
  2511  
  2512  		for _, f := range p.CompiledGoFiles {
  2513  			if strings.HasSuffix(f, ".s") || strings.HasSuffix(f, ".c") {
  2514  				t.Errorf("expected no non-Go CompiledGoFiles, got file %q in CompiledGoFiles", f)
  2515  			}
  2516  		}
  2517  	}
  2518  }
  2519  
  2520  // TestInvalidFilesInXTest checks the fix for golang/go#37971 in Go 1.15.
  2521  func TestInvalidFilesInXTest(t *testing.T) { testAllOrModulesParallel(t, testInvalidFilesInXTest) }
  2522  func testInvalidFilesInXTest(t *testing.T, exporter packagestest.Exporter) {
  2523  	exported := packagestest.Export(t, exporter, []packagestest.Module{
  2524  		{
  2525  			Name: "golang.org/fake",
  2526  			Files: map[string]interface{}{
  2527  				"d/d.go":      `package d; import "net/http"; const d = http.MethodGet; func Get() string { return d; }`,
  2528  				"d/d2.go":     ``, // invalid file
  2529  				"d/d_test.go": `package d_test; import "testing"; import "golang.org/fake/d"; func TestD(t *testing.T) { d.Get(); }`,
  2530  			},
  2531  		},
  2532  	})
  2533  	defer exported.Cleanup()
  2534  
  2535  	exported.Config.Mode = packages.NeedName | packages.NeedFiles
  2536  	exported.Config.Tests = true
  2537  
  2538  	initial, err := packages.Load(exported.Config, "golang.org/fake/d")
  2539  	if err != nil {
  2540  		t.Fatal(err)
  2541  	}
  2542  	if len(initial) != 3 {
  2543  		t.Errorf("expected 3 packages, got %d", len(initial))
  2544  	}
  2545  }
  2546  
  2547  func TestTypecheckCgo(t *testing.T) { testAllOrModulesParallel(t, testTypecheckCgo) }
  2548  func testTypecheckCgo(t *testing.T, exporter packagestest.Exporter) {
  2549  	testenv.NeedsTool(t, "cgo")
  2550  
  2551  	const cgo = `package cgo
  2552  		import "C"
  2553  
  2554  		func Example() {
  2555  			C.CString("hi")
  2556  		}
  2557  	`
  2558  	exported := packagestest.Export(t, exporter, []packagestest.Module{
  2559  		{
  2560  			Name: "golang.org/fake",
  2561  			Files: map[string]interface{}{
  2562  				"cgo/cgo.go": cgo,
  2563  			},
  2564  		},
  2565  	})
  2566  	defer exported.Cleanup()
  2567  
  2568  	exported.Config.Mode = packages.NeedFiles | packages.NeedCompiledGoFiles |
  2569  		packages.NeedSyntax | packages.NeedDeps | packages.NeedTypes |
  2570  		packages.LoadMode(packagesinternal.TypecheckCgo)
  2571  
  2572  	initial, err := packages.Load(exported.Config, "golang.org/fake/cgo")
  2573  	if err != nil {
  2574  		t.Fatal(err)
  2575  	}
  2576  	pkg := initial[0]
  2577  	if len(pkg.Errors) != 0 {
  2578  		t.Fatalf("package has errors: %v", pkg.Errors)
  2579  	}
  2580  
  2581  	expos := pkg.Types.Scope().Lookup("Example").Pos()
  2582  	fname := pkg.Fset.File(expos).Name()
  2583  	if !strings.HasSuffix(fname, "cgo.go") {
  2584  		t.Errorf("position for cgo package was loaded from %v, wanted cgo.go", fname)
  2585  	}
  2586  }
  2587  
  2588  func TestModule(t *testing.T) {
  2589  	testAllOrModulesParallel(t, testModule)
  2590  }
  2591  func testModule(t *testing.T, exporter packagestest.Exporter) {
  2592  	exported := packagestest.Export(t, exporter, []packagestest.Module{{
  2593  		Name:  "golang.org/fake",
  2594  		Files: map[string]interface{}{"a/a.go": `package a`}}})
  2595  	exported.Config.Mode = packages.NeedModule
  2596  	rootDir := filepath.Dir(filepath.Dir(exported.File("golang.org/fake", "a/a.go")))
  2597  
  2598  	initial, err := packages.Load(exported.Config, "golang.org/fake/a")
  2599  	if err != nil {
  2600  		t.Fatal(err)
  2601  	}
  2602  
  2603  	if len(initial) != 1 {
  2604  		t.Fatal("want exactly one package, got ", initial)
  2605  	}
  2606  	a := initial[0]
  2607  	switch exported.Exporter.Name() {
  2608  	case "GOPATH":
  2609  		if a.Module != nil {
  2610  			t.Fatal("package.Module: want nil, got ", a.Module)
  2611  		}
  2612  	case "Modules":
  2613  		// Make sure Modules field is set, and spot check a few of its fields.
  2614  		if a.Module == nil {
  2615  			t.Fatal("package.Module: want non-nil, got nil")
  2616  		}
  2617  		if a.Module.Path != "golang.org/fake" {
  2618  			t.Fatalf("package.Modile.Path: want \"golang.org/fake\", got %q", a.Module.Path)
  2619  		}
  2620  		if a.Module.GoMod != filepath.Join(rootDir, "go.mod") {
  2621  			t.Fatalf("package.Module.GoMod: want %q, got %q", filepath.Join(rootDir, "go.mod"), a.Module.GoMod)
  2622  		}
  2623  	default:
  2624  		t.Fatalf("Expected exporter to be GOPATH or Modules, got %v", exported.Exporter.Name())
  2625  	}
  2626  }
  2627  
  2628  func TestExternal_NotHandled(t *testing.T) {
  2629  	testAllOrModulesParallel(t, testExternal_NotHandled)
  2630  }
  2631  func testExternal_NotHandled(t *testing.T, exporter packagestest.Exporter) {
  2632  	skipIfShort(t, "builds and links fake driver binaries")
  2633  	testenv.NeedsGoBuild(t)
  2634  
  2635  	tempdir, err := ioutil.TempDir("", "testexternal")
  2636  	if err != nil {
  2637  		t.Fatal(err)
  2638  	}
  2639  	defer os.RemoveAll(tempdir)
  2640  
  2641  	exported := packagestest.Export(t, exporter, []packagestest.Module{{
  2642  		Name: "golang.org/fake",
  2643  		Files: map[string]interface{}{
  2644  			"a/a.go": `package a`,
  2645  			"empty_driver/main.go": `package main
  2646  
  2647  import (
  2648  	"fmt"
  2649  	"io/ioutil"
  2650  	"os"
  2651  )
  2652  
  2653  func main() {
  2654  	ioutil.ReadAll(os.Stdin)
  2655  	fmt.Println("{}")
  2656  }
  2657  `,
  2658  			"nothandled_driver/main.go": `package main
  2659  
  2660  import (
  2661  	"fmt"
  2662  	"io/ioutil"
  2663  	"os"
  2664  )
  2665  
  2666  func main() {
  2667  	ioutil.ReadAll(os.Stdin)
  2668  	fmt.Println("{\"NotHandled\": true}")
  2669  }
  2670  `,
  2671  		}}})
  2672  	baseEnv := exported.Config.Env
  2673  
  2674  	// As a control, create a fake driver that always returns an empty response.
  2675  	emptyDriverPath := filepath.Join(tempdir, "empty_driver.exe") // Add .exe because Windows expects it.
  2676  	cmd := exec.Command("go", "build", "-o", emptyDriverPath, "golang.org/fake/empty_driver")
  2677  	cmd.Env = baseEnv
  2678  	cmd.Dir = exported.Config.Dir
  2679  	if b, err := cmd.CombinedOutput(); err != nil {
  2680  		t.Log(string(b))
  2681  		t.Fatal(err)
  2682  	}
  2683  
  2684  	exported.Config.Env = append(append([]string{}, baseEnv...), "GOPACKAGESDRIVER="+emptyDriverPath)
  2685  	initial, err := packages.Load(exported.Config, "golang.org/fake/a")
  2686  	if err != nil {
  2687  		t.Fatal(err)
  2688  	}
  2689  
  2690  	if len(initial) != 0 {
  2691  		t.Errorf("package.Load with empty driver: want [], got %v", initial)
  2692  	}
  2693  
  2694  	// Create a fake driver that always returns a NotHandled response.
  2695  	notHandledDriverPath := filepath.Join(tempdir, "nothandled_driver.exe")
  2696  	cmd = exec.Command("go", "build", "-o", notHandledDriverPath, "golang.org/fake/nothandled_driver")
  2697  	cmd.Env = baseEnv
  2698  	cmd.Dir = exported.Config.Dir
  2699  	if b, err := cmd.CombinedOutput(); err != nil {
  2700  		t.Log(string(b))
  2701  		t.Fatal(err)
  2702  	}
  2703  
  2704  	exported.Config.Env = append(append([]string{}, baseEnv...), "GOPACKAGESDRIVER="+notHandledDriverPath)
  2705  	initial, err = packages.Load(exported.Config, "golang.org/fake/a")
  2706  	if err != nil {
  2707  		t.Fatal(err)
  2708  	}
  2709  
  2710  	if len(initial) != 1 || initial[0].PkgPath != "golang.org/fake/a" {
  2711  		t.Errorf("package.Load: want [golang.org/fake/a], got %v", initial)
  2712  	}
  2713  }
  2714  
  2715  func TestInvalidPackageName(t *testing.T) {
  2716  	testAllOrModulesParallel(t, testInvalidPackageName)
  2717  }
  2718  
  2719  func testInvalidPackageName(t *testing.T, exporter packagestest.Exporter) {
  2720  	exported := packagestest.Export(t, exporter, []packagestest.Module{{
  2721  		Name: "golang.org/fake",
  2722  		Files: map[string]interface{}{
  2723  			"main.go": `package default
  2724  
  2725  func main() {
  2726  }
  2727  `,
  2728  		},
  2729  	}})
  2730  	defer exported.Cleanup()
  2731  
  2732  	initial, err := packages.Load(exported.Config, "golang.org/fake")
  2733  	if err != nil {
  2734  		t.Fatal(err)
  2735  	}
  2736  	pkg := initial[0]
  2737  	if len(pkg.CompiledGoFiles) != 1 {
  2738  		t.Fatalf("expected 1 Go file in package %s, got %v", pkg.ID, len(pkg.CompiledGoFiles))
  2739  	}
  2740  }
  2741  
  2742  func TestEmptyEnvironment(t *testing.T) {
  2743  	t.Parallel()
  2744  
  2745  	cfg := &packages.Config{
  2746  		Env: []string{"FOO=BAR"},
  2747  	}
  2748  	_, err := packages.Load(cfg, "fmt")
  2749  	if err == nil {
  2750  		t.Fatal("Load with explicitly empty environment should fail")
  2751  	}
  2752  }
  2753  
  2754  func TestPackageLoadSingleFile(t *testing.T) {
  2755  	tmp, err := ioutil.TempDir("", "a")
  2756  	if err != nil {
  2757  		t.Fatal(err)
  2758  	}
  2759  	defer os.RemoveAll(tmp)
  2760  
  2761  	filename := filepath.Join(tmp, "a.go")
  2762  
  2763  	if err := ioutil.WriteFile(filename, []byte(`package main; func main() { println("hello world") }`), 0775); err != nil {
  2764  		t.Fatal(err)
  2765  	}
  2766  
  2767  	pkgs, err := packages.Load(&packages.Config{Mode: packages.LoadSyntax, Dir: tmp}, "file="+filename)
  2768  	if err != nil {
  2769  		t.Fatalf("could not load package: %v", err)
  2770  	}
  2771  	if len(pkgs) != 1 {
  2772  		t.Fatalf("expected one package to be loaded, got %d", len(pkgs))
  2773  	}
  2774  	if len(pkgs[0].CompiledGoFiles) != 1 || pkgs[0].CompiledGoFiles[0] != filename {
  2775  		t.Fatalf("expected one compiled go file (%q), got %v", filename, pkgs[0].CompiledGoFiles)
  2776  	}
  2777  }
  2778  
  2779  func errorMessages(errors []packages.Error) []string {
  2780  	var msgs []string
  2781  	for _, err := range errors {
  2782  		msgs = append(msgs, err.Msg)
  2783  	}
  2784  	return msgs
  2785  }
  2786  
  2787  func srcs(p *packages.Package) []string {
  2788  	return cleanPaths(append(append(p.GoFiles[:len(p.GoFiles):len(p.GoFiles)], p.OtherFiles...), p.EmbedFiles...))
  2789  }
  2790  
  2791  // cleanPaths attempts to reduce path names to stable forms
  2792  func cleanPaths(paths []string) []string {
  2793  	result := make([]string, len(paths))
  2794  	for i, src := range paths {
  2795  		// If the source file doesn't have an extension like .go or .s,
  2796  		// it comes from GOCACHE. The names there aren't predictable.
  2797  		name := filepath.Base(src)
  2798  		if !strings.Contains(name, ".") {
  2799  			result[i] = fmt.Sprintf("%d.go", i) // make cache names predictable
  2800  		} else {
  2801  			result[i] = name
  2802  		}
  2803  	}
  2804  	return result
  2805  }
  2806  
  2807  // importGraph returns the import graph as a user-friendly string,
  2808  // and a map containing all packages keyed by ID.
  2809  func importGraph(initial []*packages.Package) (string, map[string]*packages.Package) {
  2810  	out := new(bytes.Buffer)
  2811  
  2812  	initialSet := make(map[*packages.Package]bool)
  2813  	for _, p := range initial {
  2814  		initialSet[p] = true
  2815  	}
  2816  
  2817  	// We can't use Visit because we need to prune
  2818  	// the traversal of specific edges, not just nodes.
  2819  	var nodes, edges []string
  2820  	res := make(map[string]*packages.Package)
  2821  	seen := make(map[*packages.Package]bool)
  2822  	var visit func(p *packages.Package)
  2823  	visit = func(p *packages.Package) {
  2824  		if !seen[p] {
  2825  			seen[p] = true
  2826  			if res[p.ID] != nil {
  2827  				panic("duplicate ID: " + p.ID)
  2828  			}
  2829  			res[p.ID] = p
  2830  
  2831  			star := ' ' // mark initial packages with a star
  2832  			if initialSet[p] {
  2833  				star = '*'
  2834  			}
  2835  			nodes = append(nodes, fmt.Sprintf("%c %s", star, p.ID))
  2836  
  2837  			// To avoid a lot of noise,
  2838  			// we prune uninteresting dependencies of testmain packages,
  2839  			// which we identify by this import:
  2840  			isTestMain := p.Imports["testing/internal/testdeps"] != nil
  2841  
  2842  			for _, imp := range p.Imports {
  2843  				if isTestMain {
  2844  					switch imp.ID {
  2845  					case "os", "reflect", "testing", "testing/internal/testdeps":
  2846  						continue
  2847  					}
  2848  				}
  2849  				// math/bits took on a dependency on unsafe in 1.12, which breaks some
  2850  				// tests. As a short term hack, prune that edge.
  2851  				// ditto for ("errors", "internal/reflectlite") in 1.13.
  2852  				// TODO(matloob): think of a cleaner solution, or remove math/bits from the test.
  2853  				if p.ID == "math/bits" && imp.ID == "unsafe" {
  2854  					continue
  2855  				}
  2856  				edges = append(edges, fmt.Sprintf("%s -> %s", p, imp))
  2857  				visit(imp)
  2858  			}
  2859  		}
  2860  	}
  2861  	for _, p := range initial {
  2862  		visit(p)
  2863  	}
  2864  
  2865  	// Sort, ignoring leading optional star prefix.
  2866  	sort.Slice(nodes, func(i, j int) bool { return nodes[i][2:] < nodes[j][2:] })
  2867  	for _, node := range nodes {
  2868  		fmt.Fprintf(out, "%s\n", node)
  2869  	}
  2870  
  2871  	sort.Strings(edges)
  2872  	for _, edge := range edges {
  2873  		fmt.Fprintf(out, "  %s\n", edge)
  2874  	}
  2875  
  2876  	return out.String(), res
  2877  }
  2878  
  2879  func constant(p *packages.Package, name string) *types.Const {
  2880  	if p == nil || p.Types == nil {
  2881  		return nil
  2882  	}
  2883  	c := p.Types.Scope().Lookup(name)
  2884  	if c == nil {
  2885  		return nil
  2886  	}
  2887  	return c.(*types.Const)
  2888  }
  2889  
  2890  func copyAll(srcPath, dstPath string) error {
  2891  	return filepath.Walk(srcPath, func(path string, info os.FileInfo, _ error) error {
  2892  		if info.IsDir() {
  2893  			return nil
  2894  		}
  2895  		contents, err := ioutil.ReadFile(path)
  2896  		if err != nil {
  2897  			return err
  2898  		}
  2899  		rel, err := filepath.Rel(srcPath, path)
  2900  		if err != nil {
  2901  			return err
  2902  		}
  2903  		dstFilePath := strings.Replace(filepath.Join(dstPath, rel), "definitelynot_go.mod", "go.mod", -1)
  2904  		if err := os.MkdirAll(filepath.Dir(dstFilePath), 0755); err != nil {
  2905  			return err
  2906  		}
  2907  		if err := ioutil.WriteFile(dstFilePath, contents, 0644); err != nil {
  2908  			return err
  2909  		}
  2910  		return nil
  2911  	})
  2912  }
  2913  
  2914  func TestExportFile(t *testing.T) {
  2915  	// This used to trigger the log.Fatal in loadFromExportData.
  2916  	// See go.dev/issue/45584.
  2917  	cfg := new(packages.Config)
  2918  	cfg.Mode = packages.NeedTypes
  2919  	packages.Load(cfg, "fmt")
  2920  }