summaryrefslogtreecommitdiff
path: root/yarnlib/scenario_runner.py
diff options
context:
space:
mode:
Diffstat (limited to 'yarnlib/scenario_runner.py')
-rw-r--r--yarnlib/scenario_runner.py82
1 files changed, 72 insertions, 10 deletions
diff --git a/yarnlib/scenario_runner.py b/yarnlib/scenario_runner.py
index e0cdf62..cbe2fad 100644
--- a/yarnlib/scenario_runner.py
+++ b/yarnlib/scenario_runner.py
@@ -101,26 +101,54 @@ class ScenarioRunner(object):
def __init__(self, shell_prelude, srcdir, extra_env=(),
pre_step_cb=default_pre_step, post_step_cb=default_post_step,
- cmdrunner=cliapp.runcmd_unchecked):
+ pre_scenario_cb=lambda *x: None,
+ post_scenario_cb=lambda *x: None,
+ cmdrunner=cliapp.runcmd_unchecked, testdir=None):
self.shell_prelude = shell_prelude
self.srcdir = srcdir
self.env = self.clean_env(extra_env, SRCDIR=srcdir)
self.pre_step_cb = pre_step_cb
self.post_step_cb = post_step_cb
+ self.pre_scenario_cb = pre_scenario_cb
+ self.post_scenario_cb = post_scenario_cb
self.cmdrunner = cmdrunner
+ self.testdir = testdir
+
+ def setup_scenario(self, scenario): # pragma: no cover
+ scenario_dir = self.scenario_dir(self.testdir, scenario)
+ os.mkdir(scenario_dir)
+ datadir = self.datadir(scenario_dir)
+ os.mkdir(datadir)
+ homedir = self.homedir(datadir)
+ os.mkdir(homedir)
+
+ ud = self.pre_scenario_cb(scenario, datadir, homedir)
+ return scenario_dir, datadir, homedir, ud
+
+ def run_scenarios(self, scenarios): # pragma: no cover
+ failed = []
+ for scenario in scenarios:
+ scenario_dir, datadir, homedir, ud = self.setup_scenario(scenario)
+ if not self.run_scenario(scenario, datadir, homedir):
+ failed.append(scenario)
+ self.post_scenario_cb(scenario, datadir, homedir, ud)
+ return failed
- def run_scenario(self, scenario, datadir, homedir):
+ @staticmethod
+ def partition_steps(scenario):
assuming = [s for s in scenario.steps if s.what == 'ASSUMING']
cleanup = [s for s in scenario.steps if s.what == 'FINALLY']
- normal = [s for s in scenario.steps if s not in assuming + cleanup]
+ normal = [s for s in scenario.steps
+ if s.what not in ('ASSUMING', 'FINALLY')]
+ return assuming, cleanup, normal
+
+ def run_scenario(self, scenario, datadir, homedir):
+ assuming, cleanup, normal = self.partition_steps(scenario)
+ scenario_env = dict(self.env, HOME=homedir, DATADIR=datadir)
ok = True
step_number = 1
- scenario_env = dict(self.env)
- scenario_env['HOME'] = homedir
- scenario_env['DATADIR'] = datadir
-
for step in assuming:
exit = self.run_step(scenario, step, scenario_env, step_number)
step_number += 1
@@ -143,12 +171,12 @@ class ScenarioRunner(object):
return ok
- def run_step(self, scenario, step, scenario_env, step_number):
+ def setup_step(self, step, scenario_env, scenario, step_number):
m = yarnlib.implements_matches_step(step.implementation, step)
assert m is not None
step_env = dict(scenario_env)
- for i, match in enumerate(m.groups('')):
- step_env['MATCH_%d' % (i+1)] = match
+ step_env.update(('MATCH_%d' % i, match) for (i, match)
+ in enumerate(m.groups(''), 1))
# All parameters passed as keyword-arguments, so that the callback
# may declare parameters in any order, and ignore any parameters
@@ -159,6 +187,12 @@ class ScenarioRunner(object):
shell_script = '%s\n\n%s\n' % (
self.shell_prelude, step.implementation.shell)
+ return step_env, pre_step_userdata, shell_script
+
+ def run_step(self, scenario, step, scenario_env, step_number):
+ step_env, pre_step_userdata, shell_script = self.setup_step(
+ step=step, scenario_env=scenario_env,
+ scenario=scenario, step_number=step_number)
exit, stdout, stderr = self.cmdrunner(
['sh', '-xeuc', shell_script], env=step_env, cwd=self.srcdir)
@@ -200,3 +234,31 @@ class ScenarioRunner(object):
env.update(kwarg_env)
return env
+
+ @classmethod
+ def scenario_dir(cls, testdir, scenario): # pragma: no cover
+ return os.path.join(testdir, cls.nice(scenario.name))
+
+ @staticmethod
+ def datadir(scenario_dir): # pragma: no cover
+ return os.path.join(scenario_dir, 'datadir')
+
+ @staticmethod
+ def homedir(datadir): # pragma: no cover
+ return os.path.join(datadir, 'HOME')
+
+ @staticmethod
+ def nice(name): # pragma: no cover
+ # 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