...
1# This file demonstrates the effect of lazy loading on the reproducibility of
2# tests (and tests of test dependencies) outside the main module.
3#
4# It is similar to the cases in mod_all.txt and mod_lazy_test_horizon.txt, but
5# focuses on the effect of "go test" on specific packages instead of the "all"
6# pattern.
7
8# The package import graph used in this test looks like:
9#
10# lazy ---- a
11# |
12# a_test ---- b
13# |
14# b_test ---- c
15#
16# And the non-lazy module dependency graph looks like:
17#
18# lazy ---- a.1 ---- b.1 ---- c.1
19
20cp go.mod go.mod.old
21go mod tidy
22cmp go.mod go.mod.old
23
24
25# In Go 1.15 mode, 'go list -m all' includes modules needed by the
26# transitive closure of tests of dependencies of tests of dependencies of ….
27
28go list -m all
29stdout '^example.com/b v0.1.0 '
30stdout '^example.com/c v0.1.0 '
31cmp go.mod go.mod.old
32
33# 'go test' (or equivalent) of any such dependency, no matter how remote, does
34# not update the go.mod file.
35
36go list -test -deps example.com/a
37stdout example.com/b
38! stdout example.com/c
39
40[!short] go test -c -o $devnull example.com/a
41[!short] cmp go.mod go.mod.old
42
43go list -test -deps example.com/b
44stdout example.com/c
45
46[!short] go test -c -o $devnull example.com/b
47[!short] cmp go.mod go.mod.old
48
49go mod edit -go=1.17 a/go.mod
50go mod edit -go=1.17 b1/go.mod
51go mod edit -go=1.17 b2/go.mod
52go mod edit -go=1.17 c1/go.mod
53go mod edit -go=1.17 c2/go.mod
54go mod edit -go=1.17
55
56
57# After changing to 'go 1.17` uniformly, 'go list -m all' should prune out
58# example.com/c, because it is not imported by any package (or test of a package)
59# transitively imported by the main module.
60#
61# example.com/a is imported,
62# and example.com/b is needed in order to run 'go test example.com/a',
63# but example.com/c is not needed because we don't expect the user to need to run
64# 'go test example.com/b'.
65
66# If we skip directly to adding a new import of c, the dependency is too far
67# away for a deepening scan to find, which is fine because the package whose
68# test imported it wasn't even it "all". It should resolve from the latest
69# version of its module.
70
71# However, if we reach c by running successive tests starting from the main
72# module, we should end up with exactly the version required by b, with an update
73# to the go.mod file as soon as we test a test dependency that is not itself in
74# "all".
75
76cp go.mod go.mod.117
77go mod tidy
78cmp go.mod go.mod.117
79
80go list -m all
81stdout '^example.com/b v0.1.0 '
82! stdout '^example.com/c '
83
84# 'go test' of a package (transitively) imported by the main module
85# should work without changes to the go.mod file.
86
87go list -test -deps example.com/a
88stdout example.com/b
89! stdout example.com/c
90
91[!short] go test -c -o $devnull example.com/a
92
93# However, 'go test' of a package that is itself a dependency should require an
94# update to the go.mod file.
95! go list -test -deps example.com/b
96
97 # TODO(#36460): The hint here is wrong. We should suggest
98 # 'go get -t example.com/b@v0.1.0' instead of 'go mod tidy'.
99stderr '^go: updates to go\.mod needed; to update it:\n\tgo mod tidy$'
100
101[!short] ! go test -c -o $devnull example.com/b
102[!short] stderr '^go: updates to go\.mod needed; to update it:\n\tgo mod tidy$'
103
104go get -t example.com/b@v0.1.0
105go list -test -deps example.com/b
106stdout example.com/c
107
108[!short] go test -c -o $devnull example.com/b
109
110# The update should bring the version required by b, not the latest version of c.
111
112go list -m example.com/c
113stdout '^example.com/c v0.1.0 '
114
115cmp go.mod go.mod.b
116
117
118# We should reach the same state if we arrive at it via `go test -mod=mod`.
119
120cp go.mod.117 go.mod
121
122[short] go list -mod=mod -test -deps example.com/a
123[!short] go test -mod=mod -c -o $devnull example.com/a
124
125[short] go list -mod=mod -test -deps example.com/b
126[!short] go test -mod=mod -c -o $devnull example.com/b
127
128cmp go.mod go.mod.b
129
130
131
132-- go.mod --
133module example.com/lazy
134
135go 1.15
136
137require example.com/a v0.1.0
138
139replace (
140 example.com/a v0.1.0 => ./a
141 example.com/b v0.1.0 => ./b1
142 example.com/b v0.2.0 => ./b2
143 example.com/c v0.1.0 => ./c1
144 example.com/c v0.2.0 => ./c2
145)
146-- go.mod.b --
147module example.com/lazy
148
149go 1.17
150
151require example.com/a v0.1.0
152
153require example.com/b v0.1.0 // indirect
154
155replace (
156 example.com/a v0.1.0 => ./a
157 example.com/b v0.1.0 => ./b1
158 example.com/b v0.2.0 => ./b2
159 example.com/c v0.1.0 => ./c1
160 example.com/c v0.2.0 => ./c2
161)
162-- lazy.go --
163package lazy
164
165import (
166 _ "example.com/a"
167)
168-- a/go.mod --
169module example.com/a
170
171go 1.15
172
173require example.com/b v0.1.0
174-- a/a.go --
175package a
176-- a/a_test.go --
177package a
178
179import (
180 "testing"
181
182 _ "example.com/b"
183)
184
185func TestUsingB(t *testing.T) {
186 // …
187}
188-- b1/go.mod --
189module example.com/b
190
191go 1.15
192
193require example.com/c v0.1.0
194-- b1/b.go --
195package b
196-- b1/b_test.go --
197package b
198
199import _ "example.com/c"
200-- b2/go.mod --
201module example.com/b
202
203go 1.15
204
205require example.com/c v0.1.0
206-- b2/b.go --
207package b
208This file should not be used, so this syntax error should be ignored.
209-- b2/b_test.go --
210package b
211This file should not be used, so this syntax error should be ignored.
212-- c1/go.mod --
213module example.com/c
214
215go 1.15
216-- c1/c.go --
217package c
218-- c2/go.mod --
219module example.com/c
220
221go 1.15
222-- c2/c.go --
223package c
224This file should not be used, so this syntax error should be ignored.
View as plain text