From fb02b5e8588fa5543dead80f70cded44fcd7047f Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 19 Nov 2020 10:44:41 +0100 Subject: 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 --- mesonbuild/mtest.py | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) (limited to 'mesonbuild/mtest.py') 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: -- cgit v1.1