github.com/slayercat/go@v0.0.0-20170428012452-c51559813f61/src/cmd/go/vendor_test.go (about)

     1  // Copyright 2015 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  // Tests for vendoring semantics.
     6  
     7  package main_test
     8  
     9  import (
    10  	"bytes"
    11  	"fmt"
    12  	"internal/testenv"
    13  	"path/filepath"
    14  	"regexp"
    15  	"strings"
    16  	"testing"
    17  )
    18  
    19  func TestVendorImports(t *testing.T) {
    20  	tg := testgo(t)
    21  	defer tg.cleanup()
    22  	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
    23  	tg.run("list", "-f", "{{.ImportPath}} {{.Imports}}", "vend/...", "vend/vendor/...", "vend/x/vendor/...")
    24  	want := `
    25  		vend [vend/vendor/p r]
    26  		vend/dir1 []
    27  		vend/hello [fmt vend/vendor/strings]
    28  		vend/subdir [vend/vendor/p r]
    29  		vend/x [vend/x/vendor/p vend/vendor/q vend/x/vendor/r vend/dir1 vend/vendor/vend/dir1/dir2]
    30  		vend/x/invalid [vend/x/invalid/vendor/foo]
    31  		vend/vendor/p []
    32  		vend/vendor/q []
    33  		vend/vendor/strings []
    34  		vend/vendor/vend/dir1/dir2 []
    35  		vend/x/vendor/p []
    36  		vend/x/vendor/p/p [notfound]
    37  		vend/x/vendor/r []
    38  	`
    39  	want = strings.Replace(want+"\t", "\n\t\t", "\n", -1)
    40  	want = strings.TrimPrefix(want, "\n")
    41  
    42  	have := tg.stdout.String()
    43  
    44  	if have != want {
    45  		t.Errorf("incorrect go list output:\n%s", diffSortedOutputs(have, want))
    46  	}
    47  }
    48  
    49  func TestVendorBuild(t *testing.T) {
    50  	tg := testgo(t)
    51  	defer tg.cleanup()
    52  	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
    53  	tg.run("build", "vend/x")
    54  }
    55  
    56  func TestVendorRun(t *testing.T) {
    57  	tg := testgo(t)
    58  	defer tg.cleanup()
    59  	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
    60  	tg.cd(filepath.Join(tg.pwd(), "testdata/src/vend/hello"))
    61  	tg.run("run", "hello.go")
    62  	tg.grepStdout("hello, world", "missing hello world output")
    63  }
    64  
    65  func TestVendorGOPATH(t *testing.T) {
    66  	tg := testgo(t)
    67  	defer tg.cleanup()
    68  	changeVolume := func(s string, f func(s string) string) string {
    69  		vol := filepath.VolumeName(s)
    70  		return f(vol) + s[len(vol):]
    71  	}
    72  	gopath := changeVolume(filepath.Join(tg.pwd(), "testdata"), strings.ToLower)
    73  	tg.setenv("GOPATH", gopath)
    74  	cd := changeVolume(filepath.Join(tg.pwd(), "testdata/src/vend/hello"), strings.ToUpper)
    75  	tg.cd(cd)
    76  	tg.run("run", "hello.go")
    77  	tg.grepStdout("hello, world", "missing hello world output")
    78  }
    79  
    80  func TestVendorTest(t *testing.T) {
    81  	tg := testgo(t)
    82  	defer tg.cleanup()
    83  	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
    84  	tg.cd(filepath.Join(tg.pwd(), "testdata/src/vend/hello"))
    85  	tg.run("test", "-v")
    86  	tg.grepStdout("TestMsgInternal", "missing use in internal test")
    87  	tg.grepStdout("TestMsgExternal", "missing use in external test")
    88  }
    89  
    90  func TestVendorInvalid(t *testing.T) {
    91  	tg := testgo(t)
    92  	defer tg.cleanup()
    93  	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
    94  
    95  	tg.runFail("build", "vend/x/invalid")
    96  	tg.grepStderr("must be imported as foo", "missing vendor import error")
    97  }
    98  
    99  func TestVendorImportError(t *testing.T) {
   100  	tg := testgo(t)
   101  	defer tg.cleanup()
   102  	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
   103  
   104  	tg.runFail("build", "vend/x/vendor/p/p")
   105  
   106  	re := regexp.MustCompile(`cannot find package "notfound" in any of:
   107  	.*[\\/]testdata[\\/]src[\\/]vend[\\/]x[\\/]vendor[\\/]notfound \(vendor tree\)
   108  	.*[\\/]testdata[\\/]src[\\/]vend[\\/]vendor[\\/]notfound
   109  	.*[\\/]src[\\/]notfound \(from \$GOROOT\)
   110  	.*[\\/]testdata[\\/]src[\\/]notfound \(from \$GOPATH\)`)
   111  
   112  	if !re.MatchString(tg.stderr.String()) {
   113  		t.Errorf("did not find expected search list in error text")
   114  	}
   115  }
   116  
   117  // diffSortedOutput prepares a diff of the already sorted outputs haveText and wantText.
   118  // The diff shows common lines prefixed by a tab, lines present only in haveText
   119  // prefixed by "unexpected: ", and lines present only in wantText prefixed by "missing: ".
   120  func diffSortedOutputs(haveText, wantText string) string {
   121  	var diff bytes.Buffer
   122  	have := splitLines(haveText)
   123  	want := splitLines(wantText)
   124  	for len(have) > 0 || len(want) > 0 {
   125  		if len(want) == 0 || len(have) > 0 && have[0] < want[0] {
   126  			fmt.Fprintf(&diff, "unexpected: %s\n", have[0])
   127  			have = have[1:]
   128  			continue
   129  		}
   130  		if len(have) == 0 || len(want) > 0 && want[0] < have[0] {
   131  			fmt.Fprintf(&diff, "missing: %s\n", want[0])
   132  			want = want[1:]
   133  			continue
   134  		}
   135  		fmt.Fprintf(&diff, "\t%s\n", want[0])
   136  		want = want[1:]
   137  		have = have[1:]
   138  	}
   139  	return diff.String()
   140  }
   141  
   142  func splitLines(s string) []string {
   143  	x := strings.Split(s, "\n")
   144  	if x[len(x)-1] == "" {
   145  		x = x[:len(x)-1]
   146  	}
   147  	return x
   148  }
   149  
   150  func TestVendorGet(t *testing.T) {
   151  	tg := testgo(t)
   152  	defer tg.cleanup()
   153  	tg.tempFile("src/v/m.go", `
   154  		package main
   155  		import ("fmt"; "vendor.org/p")
   156  		func main() {
   157  			fmt.Println(p.C)
   158  		}`)
   159  	tg.tempFile("src/v/m_test.go", `
   160  		package main
   161  		import ("fmt"; "testing"; "vendor.org/p")
   162  		func TestNothing(t *testing.T) {
   163  			fmt.Println(p.C)
   164  		}`)
   165  	tg.tempFile("src/v/vendor/vendor.org/p/p.go", `
   166  		package p
   167  		const C = 1`)
   168  	tg.setenv("GOPATH", tg.path("."))
   169  	tg.cd(tg.path("src/v"))
   170  	tg.run("run", "m.go")
   171  	tg.run("test")
   172  	tg.run("list", "-f", "{{.Imports}}")
   173  	tg.grepStdout("v/vendor/vendor.org/p", "import not in vendor directory")
   174  	tg.run("list", "-f", "{{.TestImports}}")
   175  	tg.grepStdout("v/vendor/vendor.org/p", "test import not in vendor directory")
   176  	tg.run("get")
   177  	tg.run("get", "-t")
   178  }
   179  
   180  func TestVendorGetUpdate(t *testing.T) {
   181  	testenv.MustHaveExternalNetwork(t)
   182  
   183  	tg := testgo(t)
   184  	defer tg.cleanup()
   185  	tg.makeTempdir()
   186  	tg.setenv("GOPATH", tg.path("."))
   187  	tg.run("get", "github.com/rsc/go-get-issue-11864")
   188  	tg.run("get", "-u", "github.com/rsc/go-get-issue-11864")
   189  }
   190  
   191  func TestVendorGetU(t *testing.T) {
   192  	testenv.MustHaveExternalNetwork(t)
   193  
   194  	tg := testgo(t)
   195  	defer tg.cleanup()
   196  	tg.makeTempdir()
   197  	tg.setenv("GOPATH", tg.path("."))
   198  	tg.run("get", "-u", "github.com/rsc/go-get-issue-11864")
   199  }
   200  
   201  func TestVendorGetTU(t *testing.T) {
   202  	testenv.MustHaveExternalNetwork(t)
   203  
   204  	tg := testgo(t)
   205  	defer tg.cleanup()
   206  	tg.makeTempdir()
   207  	tg.setenv("GOPATH", tg.path("."))
   208  	tg.run("get", "-t", "-u", "github.com/rsc/go-get-issue-11864/...")
   209  }
   210  
   211  func TestVendorGetBadVendor(t *testing.T) {
   212  	testenv.MustHaveExternalNetwork(t)
   213  
   214  	for _, suffix := range []string{"bad/imp", "bad/imp2", "bad/imp3", "..."} {
   215  		t.Run(suffix, func(t *testing.T) {
   216  			tg := testgo(t)
   217  			defer tg.cleanup()
   218  			tg.makeTempdir()
   219  			tg.setenv("GOPATH", tg.path("."))
   220  			tg.runFail("get", "-t", "-u", "github.com/rsc/go-get-issue-18219/"+suffix)
   221  			tg.grepStderr("must be imported as", "did not find error about vendor import")
   222  			tg.mustNotExist(tg.path("src/github.com/rsc/vendor"))
   223  		})
   224  	}
   225  }
   226  
   227  func TestGetSubmodules(t *testing.T) {
   228  	testenv.MustHaveExternalNetwork(t)
   229  
   230  	tg := testgo(t)
   231  	defer tg.cleanup()
   232  	tg.makeTempdir()
   233  	tg.setenv("GOPATH", tg.path("."))
   234  	tg.run("get", "-d", "github.com/rsc/go-get-issue-12612")
   235  	tg.run("get", "-u", "-d", "github.com/rsc/go-get-issue-12612")
   236  	tg.mustExist(tg.path("src/github.com/rsc/go-get-issue-12612/vendor/golang.org/x/crypto/.git"))
   237  }
   238  
   239  func TestVendorCache(t *testing.T) {
   240  	tg := testgo(t)
   241  	defer tg.cleanup()
   242  	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/testvendor"))
   243  	tg.runFail("build", "p")
   244  	tg.grepStderr("must be imported as x", "did not fail to build p")
   245  }
   246  
   247  func TestVendorTest2(t *testing.T) {
   248  	testenv.MustHaveExternalNetwork(t)
   249  
   250  	tg := testgo(t)
   251  	defer tg.cleanup()
   252  	tg.makeTempdir()
   253  	tg.setenv("GOPATH", tg.path("."))
   254  	tg.run("get", "github.com/rsc/go-get-issue-11864")
   255  
   256  	// build -i should work
   257  	tg.run("build", "-i", "github.com/rsc/go-get-issue-11864")
   258  	tg.run("build", "-i", "github.com/rsc/go-get-issue-11864/t")
   259  
   260  	// test -i should work like build -i (golang.org/issue/11988)
   261  	tg.run("test", "-i", "github.com/rsc/go-get-issue-11864")
   262  	tg.run("test", "-i", "github.com/rsc/go-get-issue-11864/t")
   263  
   264  	// test should work too
   265  	tg.run("test", "github.com/rsc/go-get-issue-11864")
   266  	tg.run("test", "github.com/rsc/go-get-issue-11864/t")
   267  
   268  	// external tests should observe internal test exports (golang.org/issue/11977)
   269  	tg.run("test", "github.com/rsc/go-get-issue-11864/vendor/vendor.org/tx2")
   270  }
   271  
   272  func TestVendorTest3(t *testing.T) {
   273  	testenv.MustHaveExternalNetwork(t)
   274  
   275  	tg := testgo(t)
   276  	defer tg.cleanup()
   277  	tg.makeTempdir()
   278  	tg.setenv("GOPATH", tg.path("."))
   279  	tg.run("get", "github.com/clsung/go-vendor-issue-14613")
   280  
   281  	tg.run("build", "-o", tg.path("a.out"), "-i", "github.com/clsung/go-vendor-issue-14613")
   282  
   283  	// test folder should work
   284  	tg.run("test", "-i", "github.com/clsung/go-vendor-issue-14613")
   285  	tg.run("test", "github.com/clsung/go-vendor-issue-14613")
   286  
   287  	// test with specified _test.go should work too
   288  	tg.cd(filepath.Join(tg.path("."), "src"))
   289  	tg.run("test", "-i", "github.com/clsung/go-vendor-issue-14613/vendor_test.go")
   290  	tg.run("test", "github.com/clsung/go-vendor-issue-14613/vendor_test.go")
   291  
   292  	// test with imported and not used
   293  	tg.run("test", "-i", "github.com/clsung/go-vendor-issue-14613/vendor/mylibtesttest/myapp/myapp_test.go")
   294  	tg.runFail("test", "github.com/clsung/go-vendor-issue-14613/vendor/mylibtesttest/myapp/myapp_test.go")
   295  	tg.grepStderr("imported and not used:", `should say "imported and not used"`)
   296  }
   297  
   298  func TestVendorList(t *testing.T) {
   299  	testenv.MustHaveExternalNetwork(t)
   300  
   301  	tg := testgo(t)
   302  	defer tg.cleanup()
   303  	tg.makeTempdir()
   304  	tg.setenv("GOPATH", tg.path("."))
   305  	tg.run("get", "github.com/rsc/go-get-issue-11864")
   306  
   307  	tg.run("list", "-f", `{{join .TestImports "\n"}}`, "github.com/rsc/go-get-issue-11864/t")
   308  	tg.grepStdout("go-get-issue-11864/vendor/vendor.org/p", "did not find vendor-expanded p")
   309  
   310  	tg.run("list", "-f", `{{join .XTestImports "\n"}}`, "github.com/rsc/go-get-issue-11864/tx")
   311  	tg.grepStdout("go-get-issue-11864/vendor/vendor.org/p", "did not find vendor-expanded p")
   312  
   313  	tg.run("list", "-f", `{{join .XTestImports "\n"}}`, "github.com/rsc/go-get-issue-11864/vendor/vendor.org/tx2")
   314  	tg.grepStdout("go-get-issue-11864/vendor/vendor.org/tx2", "did not find vendor-expanded tx2")
   315  
   316  	tg.run("list", "-f", `{{join .XTestImports "\n"}}`, "github.com/rsc/go-get-issue-11864/vendor/vendor.org/tx3")
   317  	tg.grepStdout("go-get-issue-11864/vendor/vendor.org/tx3", "did not find vendor-expanded tx3")
   318  }
   319  
   320  func TestVendor12156(t *testing.T) {
   321  	// Former index out of range panic.
   322  	tg := testgo(t)
   323  	defer tg.cleanup()
   324  	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/testvendor2"))
   325  	tg.cd(filepath.Join(tg.pwd(), "testdata/testvendor2/src/p"))
   326  	tg.runFail("build", "p.go")
   327  	tg.grepStderrNot("panic", "panicked")
   328  	tg.grepStderr(`cannot find package "x"`, "wrong error")
   329  }