Bug 1209463 - [mozlog] Print an overall summary from the tbplformatter, r?jgraham draft
authorAndrew Halberstadt <ahalberstadt@mozilla.com>
Thu, 30 Nov 2017 17:16:53 -0500
changeset 707174 c4765e815bc628aace4ae551d932ff9b1736f5f4
parent 707173 6e3cfe1e3c0e4063ac2d867942867b207f0dfcf7
child 742858 92c9fc94e59170d7093190227317f8a690a18d42
push id92023
push userahalberstadt@mozilla.com
push dateMon, 04 Dec 2017 21:11:24 +0000
reviewersjgraham
bugs1209463
milestone59.0a1
Bug 1209463 - [mozlog] Print an overall summary from the tbplformatter, r?jgraham When 'summary_on_shutdown' is True (which is the case for |mach test| and |mach mochitest|, the tbplformatter will now print an overall summary at the end of the log run. MozReview-Commit-ID: 9ieqJRcON8e
testing/mozbase/mozlog/mozlog/formatters/tbplformatter.py
--- a/testing/mozbase/mozlog/mozlog/formatters/tbplformatter.py
+++ b/testing/mozbase/mozlog/mozlog/formatters/tbplformatter.py
@@ -4,16 +4,17 @@
 
 from __future__ import absolute_import
 
 import functools
 from collections import deque
 
 from .base import BaseFormatter
 from .process import strstatus
+from ..handlers import SummaryHandler
 
 
 def output_subtests(func):
     @functools.wraps(func)
     def inner(self, data):
         if self.subtests_count:
             return self._format_subtests(data.get("component")) + func(self, data)
         else:
@@ -21,23 +22,32 @@ def output_subtests(func):
     return inner
 
 
 class TbplFormatter(BaseFormatter):
     """Formatter that formats logs in the legacy formatting format used by TBPL
     This is intended to be used to preserve backward compatibility with existing tools
     hand-parsing this format.
     """
-    def __init__(self, compact=False):
+    def __init__(self, compact=False, summary_on_shutdown=False, **kwargs):
+        super(TbplFormatter, self).__init__(**kwargs)
         self.suite_start_time = None
         self.test_start_times = {}
         self.buffer = None
         self.compact = compact
         self.subtests_count = 0
 
+        self.summary = SummaryHandler()
+        self.summary_on_shutdown = summary_on_shutdown
+
+    def __call__(self, data):
+        if self.summary_on_shutdown:
+            self.summary(data)
+        return super(TbplFormatter, self).__call__(data)
+
     @property
     def compact(self):
         return self._compact
 
     @compact.setter
     def compact(self, value):
         self._compact = value
         if value:
@@ -259,8 +269,32 @@ class TbplFormatter(BaseFormatter):
 
         return rv
 
     def lint(self, data):
         fmt = "TEST-UNEXPECTED-{level} | {path}:{lineno}{column} | {message} ({rule})"
         data["column"] = ":%s" % data["column"] if data["column"] else ""
         data['rule'] = data['rule'] or data['linter'] or ""
         return fmt.append(fmt.format(**data))
+
+    def _format_suite_summary(self, suite, summary):
+        counts = summary['counts']
+        logs = summary['unexpected_logs']
+
+        total = sum(self.summary.aggregate('count', counts).values())
+        expected = sum(self.summary.aggregate('expected', counts).values())
+        status_str = "{}/{}".format(expected, total)
+        rv = ["{}: {}".format(suite, status_str)]
+
+        for results in logs.values():
+            for data in results:
+                rv.append("  {}".format(self._format_status(data)))
+        return "\n".join(rv)
+
+    def shutdown(self, data):
+        if not self.summary_on_shutdown:
+            return
+
+        rv = ["", "Overall Summary"]
+        for suite, summary in self.summary:
+            rv.append(self._format_suite_summary(suite, summary))
+        rv.append("")
+        return "\n".join(rv)