diff --git a/cmd/testscript/testdata/work.txt b/cmd/testscript/testdata/work.txt index 65017ec4..42b4135a 100644 --- a/cmd/testscript/testdata/work.txt +++ b/cmd/testscript/testdata/work.txt @@ -9,11 +9,11 @@ unquote file.txt dir/file.txt testscript -v -work file.txt dir/file.txt -stderr '^temporary work directory: \Q'$WORK'\E[/\\]tmp[/\\]' -stderr '^temporary work directory for file.txt: \Q'$WORK'\E[/\\]tmp[/\\]' -stderr '^temporary work directory for dir[/\\]file.txt: \Q'$WORK'\E[/\\]tmp[/\\]' -expandone $WORK/tmp/testscript*/file.txt/script.txt -expandone $WORK/tmp/testscript*/file.txt1/script.txt +stderr '^temporary work directory: \Q'$WORK'\E[/\\]\.tmp[/\\]' +stderr '^temporary work directory for file.txt: \Q'$WORK'\E[/\\]\.tmp[/\\]' +stderr '^temporary work directory for dir[/\\]file.txt: \Q'$WORK'\E[/\\]\.tmp[/\\]' +expandone $WORK/.tmp/testscript*/file.txt/script.txt +expandone $WORK/.tmp/testscript*/file.txt1/script.txt -- file.txt -- >exec true diff --git a/testscript/testdata/setupfiles.txt b/testscript/testdata/setupfiles.txt index d27a7c22..8e9626fc 100644 --- a/testscript/testdata/setupfiles.txt +++ b/testscript/testdata/setupfiles.txt @@ -1,6 +1,6 @@ # check that the Setup function saw the unarchived files, # including the temp directory that's always created. -setup-filenames a b tmp +setup-filenames .tmp a b -- a -- -- b/c -- diff --git a/testscript/testscript.go b/testscript/testscript.go index 75a6c9a6..52768819 100644 --- a/testscript/testscript.go +++ b/testscript/testscript.go @@ -289,13 +289,23 @@ type backgroundCmd struct { // It returns the comment section of the txtar archive. func (ts *TestScript) setup() string { ts.workdir = filepath.Join(ts.testTempDir, "script-"+ts.name) - ts.Check(os.MkdirAll(filepath.Join(ts.workdir, "tmp"), 0777)) + + // Establish a temporary directory in workdir, but use a prefix that ensures + // this directory will not be walked when resolving the ./... pattern from + // workdir. This is important because when resolving a ./... pattern, cmd/go + // (which is used by go/packages) creates temporary build files and + // directories. This can, and does, therefore interfere with the ./... + // pattern when used from workdir and can lead to race conditions within + // cmd/go as it walks directories to match the ./... pattern. + tmpDir := filepath.Join(ts.workdir, ".tmp") + + ts.Check(os.MkdirAll(tmpDir, 0777)) env := &Env{ Vars: []string{ "WORK=" + ts.workdir, // must be first for ts.abbrev "PATH=" + os.Getenv("PATH"), homeEnvName() + "=/no-home", - tempEnvName() + "=" + filepath.Join(ts.workdir, "tmp"), + tempEnvName() + "=" + tmpDir, "devnull=" + os.DevNull, "/=" + string(os.PathSeparator), ":=" + string(os.PathListSeparator),