Bug 1209463 - [mozlog] Add a 'summary_on_shutdown' attribute to MachFormatter, r?jgraham
When 'summary_on_shutdown' is True (which is the case for |mach test| and |mach
mochitest|), BaseSummaryFormatters will save the summary information until the
'shutdown' action is received at the end of the logger's lifetime.
Summary information will no longer be dumped on 'suite_end'.
MozReview-Commit-ID: HKtVr5PxfOy
--- a/testing/mach_commands.py
+++ b/testing/mach_commands.py
@@ -111,16 +111,17 @@ class Test(MachCommandBase):
run_suites, run_tests = resolver.resolve_metadata(what)
if not run_suites and not run_tests:
print(UNKNOWN_TEST)
return 1
# Create shared logger
formatter = log_formatters[self._mach_context.settings['test']['format']][0]()
+ formatter.summary_on_shutdown = True
level = self._mach_context.settings['test']['level']
log = StructuredLogger('mach-test')
log.add_handler(StreamHandler(sys.stdout, LogLevelFilter(formatter, level)))
status = None
for suite_name in run_suites:
suite = TEST_SUITES[suite_name]
--- a/testing/mochitest/mach_commands.py
+++ b/testing/mochitest/mach_commands.py
@@ -305,16 +305,18 @@ class MachCommands(MachCommandBase):
flavors = [fname]
break
else:
flavors = [f for f, v in ALL_FLAVORS.iteritems() if buildapp in v['enabled_apps']]
if not kwargs.get('log'):
# Create shared logger
formatter = log_formatters[self._mach_context.settings['test']['format']][0]()
+ formatter.summary_on_shutdown = True
+
level = self._mach_context.settings['test']['level']
kwargs['log'] = StructuredLogger('mach-mochitest')
kwargs['log'].add_handler(StreamHandler(sys.stdout, LogLevelFilter(formatter, level)))
from mozbuild.controller.building import BuildDriver
self._ensure_state_subdir_exists('.')
test_paths = kwargs['test_paths']
--- a/testing/mozbase/mozlog/mozlog/formatters/machformatter.py
+++ b/testing/mozbase/mozlog/mozlog/formatters/machformatter.py
@@ -30,17 +30,17 @@ class NullTerminal(object):
def _id(self, value):
return value
class MachFormatter(base.BaseFormatter):
def __init__(self, start_time=None, write_interval=False, write_times=True,
- terminal=None, disable_colors=False, **kwargs):
+ terminal=None, disable_colors=False, summary_on_shutdown=False, **kwargs):
super(MachFormatter, self).__init__(**kwargs)
if disable_colors:
terminal = None
elif terminal is None and blessings is not None:
terminal = blessings.Terminal()
if start_time is None:
@@ -52,16 +52,17 @@ class MachFormatter(base.BaseFormatter):
self.status_buffer = {}
self.has_unexpected = {}
self.last_time = None
self.terminal = terminal
self.verbose = False
self._known_pids = set()
self.summary = SummaryHandler()
+ self.summary_on_shutdown = summary_on_shutdown
def __call__(self, data):
self.summary(data)
s = super(MachFormatter, self).__call__(data)
if s is None:
return
@@ -113,17 +114,18 @@ class MachFormatter(base.BaseFormatter):
assert False, "unexpected test_id"
def suite_start(self, data):
num_tests = reduce(lambda x, y: x + len(y), data['tests'].itervalues(), 0)
return "%i" % num_tests
def suite_end(self, data):
- return self._format_suite_summary(self.summary.current_suite, self.summary.current)
+ if not self.summary_on_shutdown:
+ return self._format_suite_summary(self.summary.current_suite, self.summary.current)
def _format_expected(self, status, expected):
term = self.terminal if self.terminal is not None else NullTerminal()
if status == "ERROR":
color = term.red
else:
color = term.yellow
@@ -382,16 +384,26 @@ class MachFormatter(base.BaseFormatter):
level=data["level"],
message=data["message"],
rule='{} '.format(data["rule"]) if data.get("rule") else "",
linter=data["linter"].lower() if data.get("linter") else "",
)
return message
+ def shutdown(self, data):
+ if not self.summary_on_shutdown:
+ return
+
+ heading = "Overall Summary"
+ rv = ["", heading, "=" * len(heading)]
+ for suite, summary in self.summary:
+ rv.append(self._format_suite_summary(suite, summary))
+ return "\n".join(rv)
+
def _get_subtest_data(self, data):
test = self._get_test_id(data)
return self.status_buffer.get(test, {"count": 0, "unexpected": 0, "pass": 0})
def _time(self, data):
entry_time = data["time"]
if self.write_interval and self.last_time is not None:
t = entry_time - self.last_time