diff options
-rw-r--r-- | NEWS | 6 | ||||
-rw-r--r-- | testrepository/testcommand.py | 18 | ||||
-rw-r--r-- | testrepository/tests/test_testcommand.py | 42 |
3 files changed, 62 insertions, 4 deletions
@@ -5,6 +5,12 @@ testrepository release notes NEXT (In development) +++++++++++++++++++++ +IMPROVEMENTS +------------ + +* It's now possible to configure ``test_run_concurrency`` in ``.testr.conf`` + to have concurrency defined by a callout. (Robert Collins) + 0.0.9 +++++ diff --git a/testrepository/testcommand.py b/testrepository/testcommand.py index 84fcf4c..eb06302 100644 --- a/testrepository/testcommand.py +++ b/testrepository/testcommand.py @@ -147,6 +147,8 @@ class TestListingFixture(Fixture): else: self.concurrency = self.ui.options.concurrency if not self.concurrency: + self.concurrency = self.callout_concurrency() + if not self.concurrency: self.concurrency = self.local_concurrency() if not self.concurrency: self.concurrency = 1 @@ -286,6 +288,22 @@ class TestListingFixture(Fixture): partition.append(test_id) return partitions + def callout_concurrency(self): + """Callout for user defined concurrency.""" + try: + concurrency_cmd = self._parser.get( + 'DEFAULT', 'test_run_concurrency', None) + except ConfigParser.NoOptionError: + return None + run_proc = self.ui.subprocess_Popen(concurrency_cmd, shell=True, + stdout=subprocess.PIPE, stdin=subprocess.PIPE) + out, err = run_proc.communicate() + if run_proc.returncode: + raise ValueError( + "test_run_concurrency failed: exit code %d, stderr=%r" % ( + run_proc.returncode, err)) + return int(out.strip()) + def local_concurrency(self): if sys.platform == 'linux2': concurrency = None diff --git a/testrepository/tests/test_testcommand.py b/testrepository/tests/test_testcommand.py index 2b66997..ecdc012 100644 --- a/testrepository/tests/test_testcommand.py +++ b/testrepository/tests/test_testcommand.py @@ -18,7 +18,7 @@ import os.path import optparse import re -from testtools.matchers import MatchesException, Raises +from testtools.matchers import MatchesException, raises from testtools.testresult.doubles import ExtendedTestResult from testrepository.commands import run @@ -78,14 +78,14 @@ class TestTestCommand(ResourcedTestCase): def test_get_run_command_no_config_file_errors(self): ui, command = self.get_test_ui_and_cmd() self.assertThat(command.get_run_command, - Raises(MatchesException(ValueError('No .testr.conf config file')))) + raises(ValueError('No .testr.conf config file'))) def test_get_run_command_no_config_settings_errors(self): ui, command = self.get_test_ui_and_cmd() self.set_config('') self.assertThat(command.get_run_command, - Raises(MatchesException(ValueError( - 'No test_command option present in .testr.conf')))) + raises(ValueError( + 'No test_command option present in .testr.conf'))) def test_get_run_command_returns_fixture_makes_IDFILE(self): ui, command = self.get_test_ui_and_cmd() @@ -244,6 +244,40 @@ class TestTestCommand(ResourcedTestCase): self.set_config('[DEFAULT]\nfilter_tags=foo bar\n') self.assertEqual(set(['foo', 'bar']), command.get_filter_tags()) + def test_callout_concurrency(self): + ui, command = self.get_test_ui_and_cmd() + ui.proc_outputs = ['4'] + self.set_config( + '[DEFAULT]\ntest_run_concurrency=probe\n' + 'test_command=foo\n') + fixture = self.useFixture(command.get_run_command()) + self.assertEqual(4, fixture.callout_concurrency()) + self.assertEqual([ + ('popen', ('probe',), {'shell': True, 'stdin': -1, 'stdout': -1}), + ('communicate',)], ui.outputs) + + def test_callout_concurrency_failed(self): + ui, command = self.get_test_ui_and_cmd() + ui.proc_results = [1] + self.set_config( + '[DEFAULT]\ntest_run_concurrency=probe\n' + 'test_command=foo\n') + fixture = self.useFixture(command.get_run_command()) + self.assertThat(lambda:fixture.callout_concurrency(), raises( + ValueError("test_run_concurrency failed: exit code 1, stderr=''"))) + self.assertEqual([ + ('popen', ('probe',), {'shell': True, 'stdin': -1, 'stdout': -1}), + ('communicate',)], ui.outputs) + + def test_callout_concurrency_not_set(self): + ui, command = self.get_test_ui_and_cmd() + self.set_config( + '[DEFAULT]\n' + 'test_command=foo\n') + fixture = self.useFixture(command.get_run_command()) + self.assertEqual(None, fixture.callout_concurrency()) + self.assertEqual([], ui.outputs) + def test_make_result(self): # Just a simple 'the dots are joined' test. More later. ui, command = self.get_test_ui_and_cmd() |