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