aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2020-11-19 10:44:41 +0100
committerPaolo Bonzini <pbonzini@redhat.com>2020-12-27 13:55:33 +0100
commitfb02b5e8588fa5543dead80f70cded44fcd7047f (patch)
tree79fc2209a12d32e9e1bef32a8a4dbc65687ca9bc
parenta166df1f96d09d0785ec7b170e2fcac8d7b97b9a (diff)
downloadmeson-fb02b5e8588fa5543dead80f70cded44fcd7047f.zip
meson-fb02b5e8588fa5543dead80f70cded44fcd7047f.tar.gz
meson-fb02b5e8588fa5543dead80f70cded44fcd7047f.tar.bz2
mtest: introduce TestLogger
The TestLogger class lets us move the code for all those log files out of TestHarness. The interface is based on JunitBuilder, which is converted already in this commit. Over the next commits, we will also convert JSON, text and console output. The main difference with JunitBuilder is that the completion method is asynchronous. This can be useful if the logger needs to clean up after itself and wait for asyncio tasks. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--mesonbuild/mtest.py38
1 files changed, 28 insertions, 10 deletions
diff --git a/mesonbuild/mtest.py b/mesonbuild/mtest.py
index 8956dd8..565f64f 100644
--- a/mesonbuild/mtest.py
+++ b/mesonbuild/mtest.py
@@ -354,7 +354,21 @@ class TAPParser:
yield self.Error('Too many tests run (expected {}, got {})'.format(plan.count, num_tests))
-class JunitBuilder:
+class TestLogger:
+ def start(self, harness: 'TestHarness') -> None:
+ pass
+
+ def log(self, harness: 'TestHarness', result: 'TestRun') -> None:
+ pass
+
+ async def finish(self, harness: 'TestHarness') -> None:
+ pass
+
+ def close(self) -> None:
+ pass
+
+
+class JunitBuilder(TestLogger):
"""Builder for Junit test results.
@@ -377,7 +391,7 @@ class JunitBuilder:
'testsuites', tests='0', errors='0', failures='0')
self.suites = {} # type: T.Dict[str, et.Element]
- def log(self, test: 'TestRun') -> None:
+ def log(self, harness: 'TestHarness', test: 'TestRun') -> None:
"""Log a single test case."""
if test.junit is not None:
for suite in test.junit.findall('.//testsuite'):
@@ -461,7 +475,7 @@ class JunitBuilder:
err = et.SubElement(testcase, 'system-err')
err.text = test.stde.rstrip()
- def write(self) -> None:
+ async def finish(self, harness: 'TestHarness') -> None:
"""Calculate total test counts and write out the xml result."""
for suite in self.suites.values():
self.root.append(suite)
@@ -911,7 +925,7 @@ class TestHarness:
self.logfilename = None # type: T.Optional[str]
self.logfile = None # type: T.Optional[T.TextIO]
self.jsonlogfile = None # type: T.Optional[T.TextIO]
- self.junit = None # type: T.Optional[JunitBuilder]
+ self.loggers = [] # type: T.List[TestLogger]
if self.options.benchmark:
self.tests = load_benchmarks(options.wd)
@@ -935,6 +949,8 @@ class TestHarness:
if lfile:
lfile.close()
setattr(self, f, None)
+ for l in self.loggers:
+ l.close()
def merge_suite_options(self, options: argparse.Namespace, test: TestSerialisation) -> T.Dict[str, str]:
if ':' in options.setup:
@@ -1014,8 +1030,8 @@ class TestHarness:
self.logfile.write("\n\n" + result.get_log() + "\n")
if self.jsonlogfile:
write_json_log(self.jsonlogfile, result)
- if self.junit:
- self.junit.log(result)
+ for l in self.loggers:
+ l.log(self, result)
def print_summary(self) -> None:
# Prepend a list of failures
@@ -1042,9 +1058,6 @@ class TestHarness:
if self.logfile:
self.logfile.write(msg)
- if self.junit:
- self.junit.write()
-
def print_collected_logs(self) -> None:
if self.collected_failures:
if len(self.collected_failures) > 10:
@@ -1185,7 +1198,7 @@ class TestHarness:
if namebase:
logfile_base += '-' + namebase.replace(' ', '_')
- self.junit = JunitBuilder(logfile_base + '.junit.xml')
+ self.loggers.append(JunitBuilder(logfile_base + '.junit.xml'))
self.logfilename = logfile_base + '.txt'
self.jsonlogfilename = logfile_base + '.json'
@@ -1285,6 +1298,9 @@ class TestHarness:
mlog.warning('CTRL-C detected, exiting')
interrupted = True
+ for l in self.loggers:
+ l.start(self)
+
if sys.platform != 'win32':
asyncio.get_event_loop().add_signal_handler(signal.SIGINT, sigint_handler)
asyncio.get_event_loop().add_signal_handler(signal.SIGTERM, sigterm_handler)
@@ -1316,6 +1332,8 @@ class TestHarness:
if sys.platform != 'win32':
asyncio.get_event_loop().remove_signal_handler(signal.SIGINT)
asyncio.get_event_loop().remove_signal_handler(signal.SIGTERM)
+ for l in self.loggers:
+ await l.finish(self)
os.chdir(startdir)
def list_tests(th: TestHarness) -> bool: