1 This directory holds test scripts *.txt run during 'go test cmd/go'.
2 To run a specific script foo.txt
3
4 go test cmd/go -run=Script/^foo$
5
6 In general script files should have short names: a few words, not whole sentences.
7 The first word should be the general category of behavior being tested,
8 often the name of a go subcommand (list, build, test, ...) or concept (vendor, pattern).
9
10 Each script is a text archive (go doc cmd/go/internal/txtar).
11 The script begins with an actual command script to run
12 followed by the content of zero or more supporting files to
13 create in the script's temporary file system before it starts executing.
14
15 As an example, run_hello.txt says:
16
17 # hello world
18 go run hello.go
19 stderr 'hello world'
20 ! stdout .
21
22 -- hello.go --
23 package main
24 func main() { println("hello world") }
25
26 Each script runs in a fresh temporary work directory tree, available to scripts as $WORK.
27 Scripts also have access to these other environment variables:
28
29 GOARCH=<target GOARCH>
30 GOCACHE=<actual GOCACHE being used outside the test>
31 GOEXE=<executable file suffix: .exe on Windows, empty on other systems>
32 GOOS=<target GOOS>
33 GOPATH=$WORK/gopath
34 GOPROXY=<local module proxy serving from cmd/go/testdata/mod>
35 GOROOT=<actual GOROOT>
36 GOROOT_FINAL=<actual GOROOT_FINAL>
37 TESTGO_GOROOT=<GOROOT used to build cmd/go, for use in tests that may change GOROOT>
38 HOME=/no-home
39 PATH=<actual PATH>
40 TMPDIR=$WORK/tmp
41 GODEBUG=<actual GODEBUG>
42 devnull=<value of os.DevNull>
43 goversion=<current Go version; for example, 1.12>
44 :=<OS-specific path list separator>
45
46 The scripts' supporting files are unpacked relative to $GOPATH/src (aka $WORK/gopath/src)
47 and then the script begins execution in that directory as well. Thus the example above runs
48 in $WORK/gopath/src with GOPATH=$WORK/gopath and $WORK/gopath/src/hello.go
49 containing the listed contents.
50
51 The lines at the top of the script are a sequence of commands to be executed
52 by a tiny script engine in ../../script_test.go (not the system shell).
53 The script stops and the overall test fails if any particular command fails.
54
55 Each line is parsed into a sequence of space-separated command words,
56 with environment variable expansion and # marking an end-of-line comment.
57 Adding single quotes around text keeps spaces in that text from being treated
58 as word separators and also disables environment variable expansion.
59 Inside a single-quoted block of text, a repeated single quote indicates
60 a literal single quote, as in:
61
62 'Don''t communicate by sharing memory.'
63
64 A line beginning with # is a comment and conventionally explains what is
65 being done or tested at the start of a new phase in the script.
66
67 The command prefix ! indicates that the command on the rest of the line
68 (typically go or a matching predicate) must fail, not succeed. Only certain
69 commands support this prefix. They are indicated below by [!] in the synopsis.
70
71 The command prefix ? indicates that the command on the rest of the line
72 may or may not succeed, but the test should continue regardless.
73 Commands that support this prefix are indicated by [?].
74
75 The command prefix [cond] indicates that the command on the rest of the line
76 should only run when the condition is satisfied. The available conditions are:
77
78 - GOOS and GOARCH values, like [386], [windows], and so on.
79 - Compiler names, like [gccgo], [gc].
80 - Test environment details:
81 - [short] for testing.Short()
82 - [cgo], [msan], [race] for whether cgo, msan, and the race detector can be used
83 - [net] for whether the external network can be used
84 - [link] for testenv.HasLink()
85 - [root] for os.Geteuid() == 0
86 - [symlink] for testenv.HasSymlink()
87 - [case-sensitive] for whether the file system is case-sensitive
88 - [exec:prog] for whether prog is available for execution (found by exec.LookPath)
89 - [GODEBUG:value] for whether value is one of the comma-separated entries in the GODEBUG variable
90 - [buildmode:value] for whether -buildmode=value is supported
91
92 A condition can be negated: [!short] means to run the rest of the line
93 when testing.Short() is false. Multiple conditions may be given for a single
94 command, for example, '[linux] [amd64] skip'. The command will run if all conditions
95 are satisfied.
96
97 The commands are:
98
99 - [! | ?] cc args... [&]
100 Run the C compiler, the platform specific flags (i.e. `go env GOGCCFLAGS`) will be
101 added automatically before args.
102
103 - cd dir
104 Change to the given directory for future commands.
105 The directory must use slashes as path separator.
106
107 - chmod perm path...
108 Change the permissions of the files or directories named by the path arguments
109 to be equal to perm. Only numerical permissions are supported.
110
111 - cmp file1 file2
112 Check that the named files have the same content.
113 By convention, file1 is the actual data and file2 the expected data.
114 File1 can be "stdout" or "stderr" to use the standard output or standard error
115 from the most recent exec or go command.
116 (If the files have differing content, the failure prints a diff.)
117
118 - cmpenv file1 file2
119 Like cmp, but environment variables are substituted in the file contents
120 before the comparison. For example, $GOOS is replaced by the target GOOS.
121
122 - [! | ?] cp src... dst
123 Copy the listed files to the target file or existing directory.
124 src can include "stdout" or "stderr" to use the standard output or standard error
125 from the most recent exec or go command.
126
127 - env [-r] [key=value...]
128 With no arguments, print the environment to stdout
129 (useful for debugging and for verifying initial state).
130 Otherwise add the listed key=value pairs to the environment.
131 The -r flag causes the values to be escaped using regexp.QuoteMeta
132 before being recorded.
133
134 - [! | ?] exec program [args...] [&]
135 Run the given executable program with the arguments.
136 It must (or must not) succeed.
137 Note that 'exec' does not terminate the script (unlike in Unix shells).
138
139 If the last token is '&', the program executes in the background. The standard
140 output and standard error of the previous command is cleared, but the output
141 of the background process is buffered — and checking of its exit status is
142 delayed — until the next call to 'wait', 'skip', or 'stop' or the end of the
143 test. If any background processes remain at the end of the test, they
144 are terminated using os.Interrupt (if supported) or os.Kill and the test
145 must not depend upon their exit status.
146
147 - [!] exists [-readonly] [-exec] file...
148 Each of the listed files or directories must (or must not) exist.
149 If -readonly is given, the files or directories must be unwritable.
150 If -exec is given, the files or directories must be executable.
151
152 - [! | ?] go args... [&]
153 Run the (test copy of the) go command with the given arguments.
154 It must (or must not) succeed.
155
156 - [!] grep [-count=N] [-q] pattern file
157 The file's content must (or must not) match the regular expression pattern.
158 For positive matches, -count=N specifies an exact number of matches to require.
159 The -q flag disables printing the file content on a mismatch.
160
161 - mkdir path...
162 Create the listed directories, if they do not already exists.
163
164 - rm file...
165 Remove the listed files or directories.
166
167 - skip [message]
168 Mark the test skipped, including the message if given.
169
170 - [!] stale path...
171 The packages named by the path arguments must (or must not)
172 be reported as "stale" by the go command.
173
174 - [!] stderr [-count=N] pattern
175 Apply the grep command (see above) to the standard error
176 from the most recent exec, go, or wait command.
177
178 - [!] stdout [-count=N] pattern
179 Apply the grep command (see above) to the standard output
180 from the most recent exec, go, wait, or env command.
181
182 - stop [message]
183 Stop the test early (marking it as passing), including the message if given.
184
185 - symlink file -> target
186 Create file as a symlink to target. The -> (like in ls -l output) is required.
187
188 - wait
189 Wait for all 'exec' and 'go' commands started in the background (with the '&'
190 token) to exit, and display success or failure status for them.
191 After a call to wait, the 'stderr' and 'stdout' commands will apply to the
192 concatenation of the corresponding streams of the background commands,
193 in the order in which those commands were started.
194
195 When TestScript runs a script and the script fails, by default TestScript shows
196 the execution of the most recent phase of the script (since the last # comment)
197 and only shows the # comments for earlier phases. For example, here is a
198 multi-phase script with a bug in it:
199
200 # GOPATH with p1 in d2, p2 in d2
201 env GOPATH=$WORK/d1${:}$WORK/d2
202
203 # build & install p1
204 env
205 go install -i p1
206 ! stale p1
207 ! stale p2
208
209 # modify p2 - p1 should appear stale
210 cp $WORK/p2x.go $WORK/d2/src/p2/p2.go
211 stale p1 p2
212
213 # build & install p1 again
214 go install -i p11
215 ! stale p1
216 ! stale p2
217
218 -- $WORK/d1/src/p1/p1.go --
219 package p1
220 import "p2"
221 func F() { p2.F() }
222 -- $WORK/d2/src/p2/p2.go --
223 package p2
224 func F() {}
225 -- $WORK/p2x.go --
226 package p2
227 func F() {}
228 func G() {}
229
230 The bug is that the final phase installs p11 instead of p1. The test failure looks like:
231
232 $ go test -run=Script
233 --- FAIL: TestScript (3.75s)
234 --- FAIL: TestScript/install_rebuild_gopath (0.16s)
235 script_test.go:223:
236 # GOPATH with p1 in d2, p2 in d2 (0.000s)
237 # build & install p1 (0.087s)
238 # modify p2 - p1 should appear stale (0.029s)
239 # build & install p1 again (0.022s)
240 > go install -i p11
241 [stderr]
242 can't load package: package p11: cannot find package "p11" in any of:
243 /Users/rsc/go/src/p11 (from $GOROOT)
244 $WORK/d1/src/p11 (from $GOPATH)
245 $WORK/d2/src/p11
246 [exit status 1]
247 FAIL: unexpected go command failure
248
249 script_test.go:73: failed at testdata/script/install_rebuild_gopath.txt:15 in $WORK/gopath/src
250
251 FAIL
252 exit status 1
253 FAIL cmd/go 4.875s
254 $
255
256 Note that the commands in earlier phases have been hidden, so that the relevant
257 commands are more easily found, and the elapsed time for a completed phase
258 is shown next to the phase heading. To see the entire execution, use "go test -v",
259 which also adds an initial environment dump to the beginning of the log.
260
261 Note also that in reported output, the actual name of the per-script temporary directory
262 has been consistently replaced with the literal string $WORK.
263
264 The cmd/go test flag -testwork (which must appear on the "go test" command line after
265 standard test flags) causes each test to log the name of its $WORK directory and other
266 environment variable settings and also to leave that directory behind when it exits,
267 for manual debugging of failing tests:
268
269 $ go test -run=Script -work
270 --- FAIL: TestScript (3.75s)
271 --- FAIL: TestScript/install_rebuild_gopath (0.16s)
272 script_test.go:223:
273 WORK=/tmp/cmd-go-test-745953508/script-install_rebuild_gopath
274 GOARCH=
275 GOCACHE=/Users/rsc/Library/Caches/go-build
276 GOOS=
277 GOPATH=$WORK/gopath
278 GOROOT=/Users/rsc/go
279 HOME=/no-home
280 TMPDIR=$WORK/tmp
281 exe=
282
283 # GOPATH with p1 in d2, p2 in d2 (0.000s)
284 # build & install p1 (0.085s)
285 # modify p2 - p1 should appear stale (0.030s)
286 # build & install p1 again (0.019s)
287 > go install -i p11
288 [stderr]
289 can't load package: package p11: cannot find package "p11" in any of:
290 /Users/rsc/go/src/p11 (from $GOROOT)
291 $WORK/d1/src/p11 (from $GOPATH)
292 $WORK/d2/src/p11
293 [exit status 1]
294 FAIL: unexpected go command failure
295
296 script_test.go:73: failed at testdata/script/install_rebuild_gopath.txt:15 in $WORK/gopath/src
297
298 FAIL
299 exit status 1
300 FAIL cmd/go 4.875s
301 $
302
303 $ WORK=/tmp/cmd-go-test-745953508/script-install_rebuild_gopath
304 $ cd $WORK/d1/src/p1
305 $ cat p1.go
306 package p1
307 import "p2"
308 func F() { p2.F() }
309 $
310
311
View as plain text