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