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