summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2013-07-06 13:56:19 +0100
committerLars Wirzenius <liw@liw.fi>2013-07-06 13:56:19 +0100
commit796c4e4182b810225816a2f090d00c21d708d3a3 (patch)
tree92076766d1540e7c41fb65bddd5853493104847e
parent2aab9e3b752d94197ab24af876ee3ae857c3ede9 (diff)
parentb6dd76a6c9ac26487522e047d608e2ac7b5ed8e3 (diff)
downloadcmdtest-796c4e4182b810225816a2f090d00c21d708d3a3.tar.gz
Merge branch 'liw/yarn-snapshots'
-rw-r--r--NEWS3
-rwxr-xr-xyarn66
-rwxr-xr-xyarn.tests/snapshot.script62
3 files changed, 129 insertions, 2 deletions
diff --git a/NEWS b/NEWS
index c948376..f7d4f4f 100644
--- a/NEWS
+++ b/NEWS
@@ -12,6 +12,9 @@ Version 0.X, released UNRELEASED
* FINALLY always worked in yarn, but has now been added to the manual
page as well.
* New yarn option `--run` allows running selected tests only.
+* New yarn option `--snapshot` makes snapshots of the test working
+ directory after each step in a scenario. Combined with the, also
+ new, option `--tempdir` this makes debugging failed tests easier.
Bug fixes:
diff --git a/yarn b/yarn
index e3ed242..c25a929 100755
--- a/yarn
+++ b/yarn
@@ -50,6 +50,18 @@ class YarnRunner(cliapp.Application):
'run only TEST (this option can be repeated)',
metavar='TEST')
+ self.settings.string(
+ ['tempdir'],
+ 'use DIR as the temporary directory for tests; '
+ 'it should be empty or not exist',
+ metavar='DIR')
+
+ self.settings.boolean(
+ ['snapshot'],
+ 'make snapshots of test working directory '
+ 'after each scenario step; you probably '
+ 'want to use this with --tempdir')
+
def setup(self):
self.ts = ttystatus.TerminalStatus(period=0.001)
if not self.settings['quiet']:
@@ -170,26 +182,43 @@ class YarnRunner(cliapp.Application):
if self.settings['no-act']:
return True
- datadir = tempfile.mkdtemp()
+ if self.settings['tempdir']:
+ tempdir = self.settings['tempdir']
+ if not os.path.exists(tempdir):
+ os.mkdir(tempdir)
+ else:
+ tempdir = tempfile.mkdtemp()
+
+ os.mkdir(self.scenario_dir(tempdir, scenario))
+ datadir = self.datadir(tempdir, scenario)
+ os.mkdir(datadir)
cleanup = [s for s in scenario.steps if s.what == 'FINALLY']
normal = [s for s in scenario.steps if s not in cleanup]
ok = True
+ step_number = 0
for step in normal:
exit = self.run_step(datadir, scenario, step, shell_prelude)
+ step_number += 1
+ self.snapshot_datadir(
+ tempdir, datadir, scenario, step_number, step)
if exit != 0:
ok = False
break
for step in cleanup:
exit = self.run_step(datadir, scenario, step, shell_prelude)
+ step_number += 1
+ self.snapshot_datadir(
+ tempdir, datadir, scenario, step_number, step)
if exit != 0:
ok = False
break
- shutil.rmtree(datadir)
+ if not self.settings['snapshot']:
+ shutil.rmtree(tempdir)
return ok
@@ -232,6 +261,39 @@ class YarnRunner(cliapp.Application):
return exit
+ def scenario_dir(self, tempdir, scenario):
+ return os.path.join(tempdir, self.nice(scenario.name))
+
+ def datadir(self, tempdir, scenario):
+ sd = self.scenario_dir(tempdir, scenario)
+ return os.path.join(sd, 'datadir')
+
+ def snapshot_dir(self, tempdir, scenario, step, step_number):
+ sd = self.scenario_dir(tempdir, scenario)
+ base = '%03d-%s-%s' % (step_number, step.what, self.nice(step.text))
+ return os.path.join(sd, base)
+
+ def snapshot_datadir(self, tempdir, datadir, scenario, step_number, step):
+ # Use --reflink in case of CoW support, e.g., btrfs.
+ snapshot = self.snapshot_dir(tempdir, scenario, step, step_number)
+ cliapp.runcmd(
+ ['cp', '-a', '--reflink=auto', datadir, snapshot])
+
+ def nice(self, name):
+ # Quote a scenario or step name so it forms a nice filename.
+ nice_chars = "abcdefghijklmnopqrstuvwxyz"
+ nice_chars += nice_chars.upper()
+ nice_chars += "0123456789-."
+
+ nice = []
+ for c in name:
+ if c in nice_chars:
+ nice.append(c)
+ elif not nice or nice[-1] != '_':
+ nice.append('_')
+ nice = ''.join(nice)
+ return nice
+
def indent(self, s):
return ''.join(' %s\n' % line for line in s.splitlines())
diff --git a/yarn.tests/snapshot.script b/yarn.tests/snapshot.script
new file mode 100755
index 0000000..e8947ad
--- /dev/null
+++ b/yarn.tests/snapshot.script
@@ -0,0 +1,62 @@
+#!/bin/sh
+
+set -eu
+
+cat << EOF > "$DATADIR/foo.yarn"
+ SCENARIO foo
+ GIVEN foo
+ WHEN foo
+ THEN foo
+
+ SCENARIO bar
+ GIVEN bar
+ WHEN bar
+ THEN bar
+
+ IMPLEMENTS GIVEN (.*)
+ touch "\$DATADIR/\$MATCH_1.given"
+
+ IMPLEMENTS WHEN (.*)
+ touch "\$DATADIR/\$MATCH_1.when"
+
+ IMPLEMENTS THEN (.*)
+ touch "\$DATADIR/\$MATCH_1.then"
+EOF
+
+./yarn -q --snapshot --tempdir "$DATADIR/tmp" "$DATADIR/foo.yarn"
+
+test -e "$DATADIR/tmp/bar"
+test -e "$DATADIR/tmp/bar/datadir"
+test -e "$DATADIR/tmp/bar/datadir/bar.given"
+test -e "$DATADIR/tmp/bar/datadir/bar.when"
+test -e "$DATADIR/tmp/bar/datadir/bar.then"
+
+test -e "$DATADIR/tmp/bar/001-GIVEN-bar"
+test -e "$DATADIR/tmp/bar/001-GIVEN-bar/bar.given"
+! test -e "$DATADIR/tmp/bar/001-GIVEN-bar/bar.when"
+! test -e "$DATADIR/tmp/bar/001-GIVEN-bar/bar.then"
+
+test -e "$DATADIR/tmp/bar/002-WHEN-bar"
+test -e "$DATADIR/tmp/bar/002-WHEN-bar/bar.given"
+test -e "$DATADIR/tmp/bar/002-WHEN-bar/bar.when"
+! test -e "$DATADIR/tmp/bar/002-WHEN-bar/bar.then"
+
+test -e "$DATADIR/tmp/bar/003-THEN-bar"
+test -e "$DATADIR/tmp/bar/003-THEN-bar/bar.given"
+test -e "$DATADIR/tmp/bar/003-THEN-bar/bar.when"
+test -e "$DATADIR/tmp/bar/003-THEN-bar/bar.then"
+
+test -e "$DATADIR/tmp/foo/001-GIVEN-foo"
+test -e "$DATADIR/tmp/foo/001-GIVEN-foo/foo.given"
+! test -e "$DATADIR/tmp/foo/001-GIVEN-foo/foo.when"
+! test -e "$DATADIR/tmp/foo/001-GIVEN-foo/foo.then"
+
+test -e "$DATADIR/tmp/foo/002-WHEN-foo"
+test -e "$DATADIR/tmp/foo/002-WHEN-foo/foo.given"
+test -e "$DATADIR/tmp/foo/002-WHEN-foo/foo.when"
+! test -e "$DATADIR/tmp/foo/002-WHEN-foo/foo.then"
+
+test -e "$DATADIR/tmp/foo/003-THEN-foo"
+test -e "$DATADIR/tmp/foo/003-THEN-foo/foo.given"
+test -e "$DATADIR/tmp/foo/003-THEN-foo/foo.when"
+test -e "$DATADIR/tmp/foo/003-THEN-foo/foo.then"