mtest: create separate runners for multiple repeats

Reusing the runners for multiple repeats of the test run gets in the
way of the progress report, which stores runners in an OrderedSet.
Instead, create a separate SingleTestRunner object for each repeat.

While at it, fix the "duplicate suite" assertion as it can fire
with TAP tests and --repeat=N.

Fixes: #8405
0.57
Paolo Bonzini 4 years ago committed by Nirbheek Chauhan
parent 1fb414402d
commit d6a866c93a
  1. 39
      mesonbuild/mtest.py
  2. 6
      run_unittests.py

@ -774,7 +774,7 @@ class JunitBuilder(TestLogger):
# separately # separately
if test.results: if test.results:
suitename = '{}.{}'.format(test.project, test.name) suitename = '{}.{}'.format(test.project, test.name)
assert suitename not in self.suites, 'duplicate suite' assert suitename not in self.suites or harness.options.repeat > 1, 'duplicate suite'
suite = self.suites[suitename] = et.Element( suite = self.suites[suitename] = et.Element(
'testsuite', 'testsuite',
@ -1627,18 +1627,22 @@ class TestHarness:
# wrapper script. # wrapper script.
sys.exit(125) sys.exit(125)
self.test_count = len(tests)
self.name_max_len = max([uniwidth(self.get_pretty_suite(test)) for test in tests]) self.name_max_len = max([uniwidth(self.get_pretty_suite(test)) for test in tests])
startdir = os.getcwd() startdir = os.getcwd()
try: try:
if self.options.wd: if self.options.wd:
os.chdir(self.options.wd) os.chdir(self.options.wd)
runners = [self.get_test_runner(test) for test in tests] runners = [] # type: T.List[SingleTestRunner]
self.duration_max_len = max([len(str(int(runner.timeout or 99))) for i in range(self.options.repeat):
for runner in runners]) runners.extend((self.get_test_runner(test) for test in tests))
# Disable the progress report if it gets in the way if i == 0:
self.need_console = any((runner.console_mode is not ConsoleUser.LOGGER self.duration_max_len = max([len(str(int(runner.timeout or 99)))
for runner in runners)) for runner in runners])
# Disable the progress report if it gets in the way
self.need_console = any((runner.console_mode is not ConsoleUser.LOGGER
for runner in runners))
self.test_count = len(runners)
self.run_tests(runners) self.run_tests(runners)
finally: finally:
os.chdir(startdir) os.chdir(startdir)
@ -1860,16 +1864,15 @@ class TestHarness:
asyncio.get_event_loop().add_signal_handler(signal.SIGINT, sigint_handler) asyncio.get_event_loop().add_signal_handler(signal.SIGINT, sigint_handler)
asyncio.get_event_loop().add_signal_handler(signal.SIGTERM, sigterm_handler) asyncio.get_event_loop().add_signal_handler(signal.SIGTERM, sigterm_handler)
try: try:
for _ in range(self.options.repeat): for runner in runners:
for runner in runners: if not runner.is_parallel:
if not runner.is_parallel: await complete_all(futures)
await complete_all(futures) future = asyncio.ensure_future(run_test(runner))
future = asyncio.ensure_future(run_test(runner)) futures.append(future)
futures.append(future) running_tests[future] = runner.visible_name
running_tests[future] = runner.visible_name future.add_done_callback(test_done)
future.add_done_callback(test_done) if not runner.is_parallel:
if not runner.is_parallel: await complete(future)
await complete(future)
if self.options.repeat > 1 and self.fail_count: if self.options.repeat > 1 and self.fail_count:
break break

@ -2523,6 +2523,12 @@ class AllPlatformTests(BasePlatformTests):
self.assertNotRegex(out, r'WARNING: Overriding.*TEST_VAR_SET') self.assertNotRegex(out, r'WARNING: Overriding.*TEST_VAR_SET')
self.run_tests() self.run_tests()
def test_testrepeat(self):
testdir = os.path.join(self.common_test_dir, '207 tap tests')
self.init(testdir)
self.build()
self._run(self.mtest_command + ['--repeat=2'])
def test_testsetups(self): def test_testsetups(self):
if not shutil.which('valgrind'): if not shutil.which('valgrind'):
raise unittest.SkipTest('Valgrind not installed.') raise unittest.SkipTest('Valgrind not installed.')

Loading…
Cancel
Save