| # This file demonstrates the effect of lazy loading on the reproducibility of |
| # tests (and tests of test dependencies) outside the main module. |
| # |
| # It is similar to the cases in mod_all.txt and mod_lazy_test_horizon.txt, but |
| # focuses on the effect of "go test" on specific packages instead of the "all" |
| # pattern. |
| |
| # The package import graph used in this test looks like: |
| # |
| # lazy ---- a |
| # | |
| # a_test ---- b |
| # | |
| # b_test ---- c |
| # |
| # And the non-lazy module dependency graph looks like: |
| # |
| # lazy ---- a.1 ---- b.1 ---- c.1 |
| |
| cp go.mod go.mod.old |
| go mod tidy |
| cmp go.mod go.mod.old |
| |
| |
| # In Go 1.15 mode, 'go list -m all' includes modules needed by the |
| # transitive closure of tests of dependencies of tests of dependencies of …. |
| |
| go list -m all |
| stdout '^example.com/b v0.1.0 ' |
| stdout '^example.com/c v0.1.0 ' |
| cmp go.mod go.mod.old |
| |
| # 'go test' (or equivalent) of any such dependency, no matter how remote, does |
| # not update the go.mod file. |
| |
| go list -test -deps example.com/a |
| stdout example.com/b |
| ! stdout example.com/c |
| |
| [!short] go test -c -o $devnull example.com/a |
| [!short] cmp go.mod go.mod.old |
| |
| go list -test -deps example.com/b |
| stdout example.com/c |
| |
| [!short] go test -c -o $devnull example.com/b |
| [!short] cmp go.mod go.mod.old |
| |
| go mod edit -go=1.17 a/go.mod |
| go mod edit -go=1.17 b1/go.mod |
| go mod edit -go=1.17 b2/go.mod |
| go mod edit -go=1.17 c1/go.mod |
| go mod edit -go=1.17 c2/go.mod |
| go mod edit -go=1.17 |
| |
| |
| # After changing to 'go 1.17` uniformly, 'go list -m all' should prune out |
| # example.com/c, because it is not imported by any package (or test of a package) |
| # transitively imported by the main module. |
| # |
| # example.com/a is imported, |
| # and example.com/b is needed in order to run 'go test example.com/a', |
| # but example.com/c is not needed because we don't expect the user to need to run |
| # 'go test example.com/b'. |
| |
| # If we skip directly to adding a new import of c, the dependency is too far |
| # away for a deepening scan to find, which is fine because the package whose |
| # test imported it wasn't even it "all". It should resolve from the latest |
| # version of its module. |
| |
| # However, if we reach c by running successive tests starting from the main |
| # module, we should end up with exactly the version required by b, with an update |
| # to the go.mod file as soon as we test a test dependency that is not itself in |
| # "all". |
| |
| cp go.mod go.mod.117 |
| go mod tidy |
| cmp go.mod go.mod.117 |
| |
| go list -m all |
| stdout '^example.com/b v0.1.0 ' |
| ! stdout '^example.com/c ' |
| |
| # 'go test' of a package (transitively) imported by the main module |
| # should work without changes to the go.mod file. |
| |
| go list -test -deps example.com/a |
| stdout example.com/b |
| ! stdout example.com/c |
| |
| [!short] go test -c -o $devnull example.com/a |
| |
| # However, 'go test' of a package that is itself a dependency should require an |
| # update to the go.mod file. |
| ! go list -test -deps example.com/b |
| |
| # TODO(#36460): The hint here is wrong. We should suggest |
| # 'go get -t example.com/b@v0.1.0' instead of 'go mod tidy'. |
| stderr '^go: updates to go\.mod needed; to update it:\n\tgo mod tidy$' |
| |
| [!short] ! go test -c -o $devnull example.com/b |
| [!short] stderr '^go: updates to go\.mod needed; to update it:\n\tgo mod tidy$' |
| |
| go get -t example.com/b@v0.1.0 |
| go list -test -deps example.com/b |
| stdout example.com/c |
| |
| [!short] go test -c -o $devnull example.com/b |
| |
| # The update should bring the version required by b, not the latest version of c. |
| |
| go list -m example.com/c |
| stdout '^example.com/c v0.1.0 ' |
| |
| cmp go.mod go.mod.b |
| |
| |
| # We should reach the same state if we arrive at it via `go test -mod=mod`. |
| |
| cp go.mod.117 go.mod |
| |
| [short] go list -mod=mod -test -deps example.com/a |
| [!short] go test -mod=mod -c -o $devnull example.com/a |
| |
| [short] go list -mod=mod -test -deps example.com/b |
| [!short] go test -mod=mod -c -o $devnull example.com/b |
| |
| cmp go.mod go.mod.b |
| |
| |
| |
| -- go.mod -- |
| module example.com/lazy |
| |
| go 1.15 |
| |
| require example.com/a v0.1.0 |
| |
| replace ( |
| example.com/a v0.1.0 => ./a |
| example.com/b v0.1.0 => ./b1 |
| example.com/b v0.2.0 => ./b2 |
| example.com/c v0.1.0 => ./c1 |
| example.com/c v0.2.0 => ./c2 |
| ) |
| -- go.mod.b -- |
| module example.com/lazy |
| |
| go 1.17 |
| |
| require example.com/a v0.1.0 |
| |
| require example.com/b v0.1.0 // indirect |
| |
| replace ( |
| example.com/a v0.1.0 => ./a |
| example.com/b v0.1.0 => ./b1 |
| example.com/b v0.2.0 => ./b2 |
| example.com/c v0.1.0 => ./c1 |
| example.com/c v0.2.0 => ./c2 |
| ) |
| -- lazy.go -- |
| package lazy |
| |
| import ( |
| _ "example.com/a" |
| ) |
| -- a/go.mod -- |
| module example.com/a |
| |
| go 1.15 |
| |
| require example.com/b v0.1.0 |
| -- a/a.go -- |
| package a |
| -- a/a_test.go -- |
| package a |
| |
| import ( |
| "testing" |
| |
| _ "example.com/b" |
| ) |
| |
| func TestUsingB(t *testing.T) { |
| // … |
| } |
| -- b1/go.mod -- |
| module example.com/b |
| |
| go 1.15 |
| |
| require example.com/c v0.1.0 |
| -- b1/b.go -- |
| package b |
| -- b1/b_test.go -- |
| package b |
| |
| import _ "example.com/c" |
| -- b2/go.mod -- |
| module example.com/b |
| |
| go 1.15 |
| |
| require example.com/c v0.1.0 |
| -- b2/b.go -- |
| package b |
| This file should not be used, so this syntax error should be ignored. |
| -- b2/b_test.go -- |
| package b |
| This file should not be used, so this syntax error should be ignored. |
| -- c1/go.mod -- |
| module example.com/c |
| |
| go 1.15 |
| -- c1/c.go -- |
| package c |
| -- c2/go.mod -- |
| module example.com/c |
| |
| go 1.15 |
| -- c2/c.go -- |
| package c |
| This file should not be used, so this syntax error should be ignored. |