Skip to content

Commit bc89b17

Browse files
authored
testscript: provide WorkdirRoot as a new Params field (#87)
Via testscript.Params.TestWork, it is possible for the caller to prevent the work directories for scripts from being removed once complete. However the work directories for testscripts are created under a temporary directory and that working directory is not returned to the caller of testscript.Run. This makes it impossible for the caller to programmatically know where the resulting scripts are. We therefore provide testscript.Params.WorkdirRoot. WorkdirRoot specifies the directory within which scripts' work directories will be created. Setting WorkdirRoot implies TestWork=true. If empty, the work directories will be created inside $GOTMPDIR/go-test-script*, where $GOTMPDIR defaults to os.TempDir(). Also fix a bug whereby the value of $WORK was not printed as part of the verbose mode env when Params.TestWork was specified. i.e. it was impossible to see what the working directory was because all instances of the working directory value are replaced with the literal $WORK.
1 parent ae313c1 commit bc89b17

File tree

3 files changed

+46
-4
lines changed

3 files changed

+46
-4
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Intentionally empty test script; used to test Params.WorkdirRoot
2+
3+
-- README.md --
4+
This file exists so that a test for Params.WorkdirRoot can verify the existence of a file
5+
within WorkdirRoot/script-nothing once scripts have finished.

testscript/testscript.go

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,12 @@ type Params struct {
9797
// left intact for later inspection.
9898
TestWork bool
9999

100+
// WorkdirRoot specifies the directory within which scripts' work
101+
// directories will be created. Setting WorkdirRoot implies TestWork=true.
102+
// If empty, the work directories will be created inside
103+
// $GOTMPDIR/go-test-script*, where $GOTMPDIR defaults to os.TempDir().
104+
WorkdirRoot string
105+
100106
// IgnoreMissedCoverage specifies that if coverage information
101107
// is being generated (with the -test.coverprofile flag) and a subcommand
102108
// function passed to RunMain fails to generate coverage information
@@ -160,9 +166,14 @@ func RunT(t T, p Params) {
160166
if len(files) == 0 {
161167
t.Fatal(fmt.Sprintf("no scripts found matching glob: %v", glob))
162168
}
163-
testTempDir, err := ioutil.TempDir(os.Getenv("GOTMPDIR"), "go-test-script")
164-
if err != nil {
165-
t.Fatal(err)
169+
testTempDir := p.WorkdirRoot
170+
if testTempDir == "" {
171+
testTempDir, err = ioutil.TempDir(os.Getenv("GOTMPDIR"), "go-test-script")
172+
if err != nil {
173+
t.Fatal(err)
174+
}
175+
} else {
176+
p.TestWork = true
166177
}
167178
// The temp dir returned by ioutil.TempDir might be a sym linked dir (default
168179
// behaviour in macOS). That could mess up matching that includes $WORK if,
@@ -528,7 +539,7 @@ func (ts *TestScript) condition(cond string) (bool, error) {
528539
// abbrev abbreviates the actual work directory in the string s to the literal string "$WORK".
529540
func (ts *TestScript) abbrev(s string) string {
530541
s = strings.Replace(s, ts.workdir, "$WORK", -1)
531-
if *testWork {
542+
if *testWork || ts.params.TestWork {
532543
// Expose actual $WORK value in environment dump on first line of work script,
533544
// so that the user can find out what directory -testwork left behind.
534545
s = "WORK=" + ts.workdir + "\n" + strings.TrimPrefix(s, "WORK=$WORK\n")

testscript/testscript_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,32 @@ func TestTestwork(t *testing.T) {
203203
}
204204
}
205205

206+
// TestWorkdirRoot tests that a non zero value in Params.WorkdirRoot is honoured
207+
func TestWorkdirRoot(t *testing.T) {
208+
td, err := ioutil.TempDir("", "")
209+
if err != nil {
210+
t.Fatalf("failed to create temp dir: %v", err)
211+
}
212+
defer os.RemoveAll(td)
213+
params := Params{
214+
Dir: filepath.Join("testdata", "nothing"),
215+
WorkdirRoot: td,
216+
}
217+
// Run as a sub-test so that this call blocks until the sub-tests created by
218+
// calling Run (which themselves call t.Parallel) complete.
219+
t.Run("run tests", func(t *testing.T) {
220+
Run(t, params)
221+
})
222+
// Verify that we have a single go-test-script-* named directory
223+
files, err := filepath.Glob(filepath.Join(td, "script-nothing", "README.md"))
224+
if err != nil {
225+
t.Fatal(err)
226+
}
227+
if len(files) != 1 {
228+
t.Fatalf("unexpected files found for kept files; got %q", files)
229+
}
230+
}
231+
206232
// TestBadDir verifies that invoking testscript with a directory that either
207233
// does not exist or that contains no *.txt scripts fails the test
208234
func TestBadDir(t *testing.T) {

0 commit comments

Comments
 (0)