summaryrefslogtreecommitdiff
path: root/testrepository
diff options
context:
space:
mode:
authorRobert Collins <robertc@robertcollins.net>2013-11-04 09:02:01 +1300
committerRobert Collins <robertc@robertcollins.net>2013-11-04 09:02:01 +1300
commit099e622dc5559cced775e9694deec6c798f590f3 (patch)
tree33c4b5773e5699d5703fbb96c288096969cb1634 /testrepository
parent2b86d6ae04620c09b47d29a1aed65888ac2e6e81 (diff)
downloadtestrepository-099e622dc5559cced775e9694deec6c798f590f3.tar.gz
* ``run`` now accepts ``--isolated`` as a parameter, which will cause each
selected test to be run independently. This can be useful to both workaround isolation bugs and detect tests that can not be run independently. (Robert Collins)
Diffstat (limited to 'testrepository')
-rw-r--r--testrepository/commands/run.py23
-rw-r--r--testrepository/tests/commands/test_run.py29
2 files changed, 50 insertions, 2 deletions
diff --git a/testrepository/commands/run.py b/testrepository/commands/run.py
index a18c235..7b6cd40 100644
--- a/testrepository/commands/run.py
+++ b/testrepository/commands/run.py
@@ -143,6 +143,9 @@ class run(Command):
optparse.Option("--analyze-isolation", action="store_true",
default=False,
help="Search the last test run for 2-test test isolation interactions."),
+ optparse.Option("--isolated", action="store_true",
+ default=False,
+ help="Run each test id in a separate test runner."),
]
args = [StringArgument('testfilters', 0, None), DoubledashArgument(),
StringArgument('testargs', 0, None)]
@@ -192,7 +195,22 @@ class run(Command):
if not self.ui.options.analyze_isolation:
cmd = testcommand.get_run_command(ids, self.ui.arguments['testargs'],
test_filters = filters)
- return self._run_tests(cmd)
+ if self.ui.options.isolated:
+ result = 0
+ cmd.setUp()
+ try:
+ ids = cmd.list_tests()
+ finally:
+ cmd.cleanUp()
+ for test_id in ids:
+ cmd = testcommand.get_run_command([test_id],
+ self.ui.arguments['testargs'], test_filters=filters)
+ run_result = self._run_tests(cmd)
+ if run_result > result:
+ result = run_result
+ return result
+ else:
+ return self._run_tests(cmd)
else:
# Where do we source data about the cause of conflicts.
# XXX: Should instead capture the run id in with the failing test
@@ -329,7 +347,8 @@ class run(Command):
def run_tests():
run_procs = [('subunit', ReturnCodeToSubunit(proc)) for proc in cmd.run_tests()]
options = {}
- if self.ui.options.failing or self.ui.options.analyze_isolation:
+ if (self.ui.options.failing or self.ui.options.analyze_isolation
+ or self.ui.options.isolated):
options['partial'] = True
load_ui = decorator.UI(input_streams=run_procs, options=options,
decorated=self.ui)
diff --git a/testrepository/tests/commands/test_run.py b/testrepository/tests/commands/test_run.py
index 3168e94..da94ca2 100644
--- a/testrepository/tests/commands/test_run.py
+++ b/testrepository/tests/commands/test_run.py
@@ -446,6 +446,35 @@ class TestCommand(ResourcedTestCase):
], ui.outputs)
self.assertEqual(0, result)
+ def test_isolated_runs_multiple_processes(self):
+ ui, cmd = self.get_test_ui_and_cmd(options=[('isolated', True)])
+ cmd.repository_factory = memory.RepositoryFactory()
+ self.setup_repo(cmd, ui)
+ self.set_config(
+ '[DEFAULT]\ntest_command=foo $IDLIST $LISTOPT\n'
+ 'test_id_option=--load-list $IDFILE\n'
+ 'test_list_option=--list\n')
+ params, capture_ids = self.capture_ids(list_result=['ab', 'cd', 'ef'])
+ self.useFixture(MonkeyPatch(
+ 'testrepository.testcommand.TestCommand.get_run_command',
+ capture_ids))
+ cmd_result = cmd.execute()
+ self.assertEqual([
+ ('results', Wildcard),
+ ('summary', True, 0, -3, None, None, [('id', 1, None)]),
+ ('results', Wildcard),
+ ('summary', True, 0, 0, None, None, [('id', 2, None)]),
+ ('results', Wildcard),
+ ('summary', True, 0, 0, None, None, [('id', 3, None)]),
+ ], ui.outputs)
+ self.assertEqual(0, cmd_result)
+ # once to list, then 3 each executing one test.
+ self.assertThat(params, HasLength(4))
+ self.assertThat(params[0][1], Equals(None))
+ self.assertThat(params[1][1], Equals(['ab']))
+ self.assertThat(params[2][1], Equals(['cd']))
+ self.assertThat(params[3][1], Equals(['ef']))
+
def read_all(stream):
return stream.read()