Skip to content

Commit

Permalink
testscript: provide WorkdirRoot as a new Params field (#87)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
myitcv committed Jan 13, 2020
1 parent ae313c1 commit bc89b17
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 4 deletions.
5 changes: 5 additions & 0 deletions testscript/testdata/nothing/nothing.txt
@@ -0,0 +1,5 @@
# Intentionally empty test script; used to test Params.WorkdirRoot

-- README.md --
This file exists so that a test for Params.WorkdirRoot can verify the existence of a file
within WorkdirRoot/script-nothing once scripts have finished.
19 changes: 15 additions & 4 deletions testscript/testscript.go
Expand Up @@ -97,6 +97,12 @@ type Params struct {
// left intact for later inspection.
TestWork bool

// 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().
WorkdirRoot string

// IgnoreMissedCoverage specifies that if coverage information
// is being generated (with the -test.coverprofile flag) and a subcommand
// function passed to RunMain fails to generate coverage information
Expand Down Expand Up @@ -160,9 +166,14 @@ func RunT(t T, p Params) {
if len(files) == 0 {
t.Fatal(fmt.Sprintf("no scripts found matching glob: %v", glob))
}
testTempDir, err := ioutil.TempDir(os.Getenv("GOTMPDIR"), "go-test-script")
if err != nil {
t.Fatal(err)
testTempDir := p.WorkdirRoot
if testTempDir == "" {
testTempDir, err = ioutil.TempDir(os.Getenv("GOTMPDIR"), "go-test-script")
if err != nil {
t.Fatal(err)
}
} else {
p.TestWork = true
}
// The temp dir returned by ioutil.TempDir might be a sym linked dir (default
// behaviour in macOS). That could mess up matching that includes $WORK if,
Expand Down Expand Up @@ -528,7 +539,7 @@ func (ts *TestScript) condition(cond string) (bool, error) {
// abbrev abbreviates the actual work directory in the string s to the literal string "$WORK".
func (ts *TestScript) abbrev(s string) string {
s = strings.Replace(s, ts.workdir, "$WORK", -1)
if *testWork {
if *testWork || ts.params.TestWork {
// Expose actual $WORK value in environment dump on first line of work script,
// so that the user can find out what directory -testwork left behind.
s = "WORK=" + ts.workdir + "\n" + strings.TrimPrefix(s, "WORK=$WORK\n")
Expand Down
26 changes: 26 additions & 0 deletions testscript/testscript_test.go
Expand Up @@ -203,6 +203,32 @@ func TestTestwork(t *testing.T) {
}
}

// TestWorkdirRoot tests that a non zero value in Params.WorkdirRoot is honoured
func TestWorkdirRoot(t *testing.T) {
td, err := ioutil.TempDir("", "")
if err != nil {
t.Fatalf("failed to create temp dir: %v", err)
}
defer os.RemoveAll(td)
params := Params{
Dir: filepath.Join("testdata", "nothing"),
WorkdirRoot: td,
}
// Run as a sub-test so that this call blocks until the sub-tests created by
// calling Run (which themselves call t.Parallel) complete.
t.Run("run tests", func(t *testing.T) {
Run(t, params)
})
// Verify that we have a single go-test-script-* named directory
files, err := filepath.Glob(filepath.Join(td, "script-nothing", "README.md"))
if err != nil {
t.Fatal(err)
}
if len(files) != 1 {
t.Fatalf("unexpected files found for kept files; got %q", files)
}
}

// TestBadDir verifies that invoking testscript with a directory that either
// does not exist or that contains no *.txt scripts fails the test
func TestBadDir(t *testing.T) {
Expand Down

0 comments on commit bc89b17

Please sign in to comment.