Backed out changeset 53bd5240052b (bug 1424287) for mozabase failures at testing/mozbase/mozlog/tests/test_formatters.py
authorCoroiu Cristina <ccoroiu@mozilla.com>
Tue, 19 Mar 2019 18:46:09 +0200
changeset 465065 9f03791063253f1d0b5992af1c37db0eb7894a8e
parent 465064 4a364b806b4a39823a7d2c107da53a5c2192e80e
child 465066 975c553ca01df60fdcf4e8173880f04702f66574
push id80872
push userccoroiu@mozilla.com
push dateTue, 19 Mar 2019 16:46:33 +0000
treeherderautoland@9f0379106325 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1424287
milestone68.0a1
backs out53bd5240052b91d99740750f9c36c997ec2df315
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out changeset 53bd5240052b (bug 1424287) for mozabase failures at testing/mozbase/mozlog/tests/test_formatters.py
testing/mozbase/mozlog/mozlog/formatters/machformatter.py
--- a/testing/mozbase/mozlog/mozlog/formatters/machformatter.py
+++ b/testing/mozbase/mozlog/mozlog/formatters/machformatter.py
@@ -1,87 +1,66 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 
 from __future__ import absolute_import
 
+import time
+
 from mozterm import Terminal
-import time
+
 from . import base
 from .process import strstatus
 from .tbplformatter import TbplFormatter
 from ..handlers import SummaryHandler
 import six
 from functools import reduce
 
-color_dict = {
-    'log_test_status_fail': 'yellow',
-    'log_process_output': 'blue',
-    'log_test_status_pass': 'green',
-    'log_test_status_unexpected_fail': 'red',
-    'time': 'cyan',
-    'action': 'yellow',
-    'pid': 'cyan',
-    'heading': 'bold_yellow',
-    'error': 'red',
-    'warning': 'yellow',
-    'bold': 'bold',
-    'grey': 'grey',
-    'normal': 'normal',
-    'dim': 'dim'
-}
-
 
 def format_seconds(total):
     """Format number of seconds to MM:SS.DD form."""
     minutes, seconds = divmod(total, 60)
     return '%2d:%05.2f' % (minutes, seconds)
 
 
-class TerminalColors(object):
-    def __init__(self, term, color_dict):
-        for key, value in color_dict.iteritems():
-            setattr(self, key, getattr(term, value))
-
-
 class MachFormatter(base.BaseFormatter):
 
     def __init__(self, start_time=None, write_interval=False, write_times=True,
                  terminal=None, disable_colors=False, summary_on_shutdown=False,
                  verbose=False, enable_screenshot=False, **kwargs):
         super(MachFormatter, self).__init__(**kwargs)
 
         if start_time is None:
             start_time = time.time()
         start_time = int(start_time * 1000)
         self.start_time = start_time
         self.write_interval = write_interval
         self.write_times = write_times
         self.status_buffer = {}
         self.has_unexpected = {}
         self.last_time = None
-        self.color_formatter = TerminalColors(
-            Terminal(disable_styling=disable_colors), color_dict)
+        self.term = Terminal(disable_styling=disable_colors)
         self.verbose = verbose
         self._known_pids = set()
         self.tbpl_formatter = None
         self.enable_screenshot = enable_screenshot
+
         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
 
-        time = self.color_formatter.time(format_seconds(self._time(data)))
+        time = self.term.dim_blue(format_seconds(self._time(data)))
         return "%s %s\n" % (time, s)
 
     def _get_test_id(self, data):
         test_id = data.get("test")
         if isinstance(test_id, list):
             test_id = tuple(test_id)
         return test_id
 
@@ -91,71 +70,64 @@ class MachFormatter(base.BaseFormatter):
 
         if isinstance(test_id, tuple):
             return "".join(test_id)
 
         assert False, "unexpected test_id"
 
     def suite_start(self, data):
         num_tests = reduce(lambda x, y: x + len(y), six.itervalues(data['tests']), 0)
-        action = self.color_formatter.action(data['action'].upper())
+        action = self.term.yellow(data['action'].upper())
         name = ""
         if 'name' in data:
             name = " %s -" % (data['name'],)
         return "%s:%s running %i tests" % (action, name, num_tests)
 
     def suite_end(self, data):
-        action = self.color_formatter.action(data['action'].upper())
+        action = self.term.yellow(data['action'].upper())
         rv = [action]
         if not self.summary_on_shutdown:
-            rv.append(
-                self._format_suite_summary(
-                    self.summary.current_suite,
-                    self.summary.current))
+            rv.append(self._format_suite_summary(self.summary.current_suite, self.summary.current))
         return "\n".join(rv)
 
     def _format_expected(self, status, expected):
         if status == expected:
-            color = self.color_formatter.log_test_status_pass
+            color = self.term.green
             if expected not in ("PASS", "OK"):
-                color = self.color_formatter.log_test_status_fail
+                color = self.term.yellow
                 status = "EXPECTED-%s" % status
         else:
-            color = self.color_formatter.log_test_status_pass
+            color = self.term.red
             if status in ("PASS", "OK"):
                 status = "UNEXPECTED-%s" % status
         return color(status)
 
     def _format_status(self, test, data):
         name = data.get("subtest", test)
         rv = "%s %s" % (self._format_expected(
             data["status"], data.get("expected", data["status"])), name)
         if "message" in data:
             rv += " - %s" % data["message"]
         if "stack" in data:
             rv += self._format_stack(data["stack"])
         return rv
 
     def _format_stack(self, stack):
-        return "\n%s\n" % self.color_formatter.dim(stack.strip("\n"))
+        return "\n%s\n" % self.term.dim(stack.strip("\n"))
 
     def _format_suite_summary(self, suite, summary):
         count = summary['counts']
         logs = summary['unexpected_logs']
 
-        rv = [
-            "",
-            self.color_formatter.log_test_status_fail(suite),
-            self.color_formatter.log_test_status_fail(
-                "~" * len(suite))]
+        rv = ["", self.term.yellow(suite), self.term.yellow("~" * len(suite))]
 
         # Format check counts
         checks = self.summary.aggregate('count', count)
-        rv.append("Ran {} checks ({})".format(sum(checks.values()), ', '.join(
-            ['{} {}s'.format(v, k) for k, v in sorted(checks.items()) if v])))
+        rv.append("Ran {} checks ({})".format(sum(checks.values()),
+                  ', '.join(['{} {}s'.format(v, k) for k, v in sorted(checks.items()) if v])))
 
         # Format expected counts
         checks = self.summary.aggregate('expected', count, include_skip=False)
         rv.append("Expected results: {}".format(sum(checks.values())))
 
         # Format skip counts
         skip_tests = count["test"]["expected"]["skip"]
         skip_subtests = count["subtest"]["expected"]["skip"]
@@ -175,39 +147,38 @@ class MachFormatter(base.BaseFormatter):
                     continue
                 status_str = ", ".join(["{} {}".format(n, s)
                                         for s, n in sorted(count[key]['unexpected'].items())])
                 rv.append("  {}: {} ({})".format(
                           key, sum(count[key]['unexpected'].values()), status_str))
 
         # Format status
         if not any(count[key]["unexpected"] for key in ('test', 'subtest', 'assert')):
-            rv.append(self.color_formatter.log_test_status_pass("OK"))
+            rv.append(self.term.green("OK"))
         else:
             heading = "Unexpected Results"
-            rv.extend(["", self.color_formatter.heading(heading),
-                       self.color_formatter.heading("-" * len(heading))])
+            rv.extend(["", self.term.yellow(heading), self.term.yellow("-" * len(heading))])
             if count['subtest']['count']:
                 for test_id, results in logs.items():
                     test = self._get_file_name(test_id)
-                    rv.append(self.color_formatter.bold(test))
+                    rv.append(self.term.bold(test))
                     for data in results:
                         rv.append("  %s" % self._format_status(test, data).rstrip())
             else:
                 for test_id, results in logs.items():
                     test = self._get_file_name(test_id)
                     assert len(results) == 1
                     data = results[0]
                     assert "subtest" not in data
                     rv.append(self._format_status(test, data).rstrip())
 
         return "\n".join(rv)
 
     def test_start(self, data):
-        action = self.color_formatter.action(data['action'].upper())
+        action = self.term.yellow(data['action'].upper())
         return "%s: %s" % (action, self._get_test_id(data))
 
     def test_end(self, data):
         subtests = self._get_subtest_data(data)
 
         if "expected" in data:
             parent_unexpected = True
             expected_str = ", expected %s" % data["expected"]
@@ -239,19 +210,19 @@ class MachFormatter(base.BaseFormatter):
                 if "stack" in data:
                     rv += self._format_stack(data["stack"])
             elif not self.verbose:
                 rv += "\n"
                 for d in unexpected:
                     rv += self._format_status(data['test'], d)
 
         if "expected" not in data and not bool(subtests['unexpected']):
-            color = self.color_formatter.log_test_status_pass
+            color = self.term.green
         else:
-            color = self.color_formatter.log_test_status_pass
+            color = self.term.red
 
         action = color(data['action'].upper())
         rv = "%s: %s" % (action, rv)
         if has_screenshots and self.enable_screenshot:
             if self.tbpl_formatter is None:
                 self.tbpl_formatter = TbplFormatter()
             # Create TBPL-like output that can be pasted into the reftest analyser
             rv = "\n".join((rv, self.tbpl_formatter.test_end(data)))
@@ -262,28 +233,28 @@ class MachFormatter(base.BaseFormatter):
         for line in data['secondary']:
             rv = rv + line + "\n"
 
         return rv
 
     def lsan_leak(self, data):
         allowed = data.get("allowed_match")
         if allowed:
-            prefix = self.color_formatter.log_test_status_fail("FAIL")
+            prefix = self.term.yellow("FAIL")
         else:
-            prefix = self.color_formatter.log_test_status_unexpected_fail("UNEXPECTED-FAIL")
+            prefix = self.term.red("UNEXPECTED-FAIL")
 
         return "%s LeakSanitizer: leak at %s" % (prefix, ", ".join(data["frames"]))
 
     def lsan_summary(self, data):
         allowed = data.get("allowed", False)
         if allowed:
-            prefix = self.color_formatter.warning("WARNING")
+            prefix = self.term.yellow("WARNING")
         else:
-            prefix = self.color_formatter.error("ERROR")
+            prefix = self.term.red("ERROR")
 
         return ("%s | LeakSanitizer | "
                 "SUMMARY: AddressSanitizer: %d byte(s) leaked in %d allocation(s)." %
                 (prefix, data["bytes"], data["allocations"]))
 
     def mozleak_object(self, data):
         data_log = data.copy()
         data_log["level"] = "INFO"
@@ -299,34 +270,31 @@ class MachFormatter(base.BaseFormatter):
                 data_log["level"] = "INFO"
                 data_log["message"] = ("leakcheck: %s deliberate crash and thus no leak log\n"
                                        % data["process"])
                 return self.log(data_log)
             if data.get("ignore_missing", False):
                 return ("%s ignoring missing output line for total leaks\n" %
                         data["process"])
 
-            status = self.color_formatter.log_test_status_pass("FAIL")
+            status = self.term.red("FAIL")
             return ("%s leakcheck: "
                     "%s missing output line for total leaks!\n" %
                     (status, data["process"]))
 
         if data["bytes"] == 0:
-            return (
-                "%s leakcheck: %s no leaks detected!\n" %
-                (self.color_formatter.log_test_status_pass("PASS"),
-                    data["process"]))
+            return ("%s leakcheck: %s no leaks detected!\n" %
+                    (self.term.green("PASS"), data["process"]))
 
         message = "leakcheck: %s %d bytes leaked\n" % (data["process"], data["bytes"])
 
         # data["bytes"] will include any expected leaks, so it can be off
         # by a few thousand bytes.
         failure = data["bytes"] > data["threshold"]
-        status = self.color_formatter.log_test_status_pass(
-            "UNEXPECTED-FAIL") if failure else self.color_formatter.log_test_status_fail("FAIL")
+        status = self.term.red("UNEXPECTED-FAIL") if failure else self.term.yellow("FAIL")
         return "%s %s\n" % (status, message)
 
     def test_status(self, data):
         test = self._get_test_id(data)
         if test not in self.status_buffer:
             self.status_buffer[test] = {"count": 0, "unexpected": 0, "pass": 0}
         self.status_buffer[test]["count"] += 1
 
@@ -343,27 +311,27 @@ class MachFormatter(base.BaseFormatter):
             return
 
         if data["min_expected"] != data["max_expected"]:
             expected = "%i to %i" % (data["min_expected"],
                                      data["max_expected"])
         else:
             expected = "%i" % data["min_expected"]
 
-        action = self.color_formatter.log_test_status_pass("ASSERT")
+        action = self.term.red("ASSERT")
         return "%s: Assertion count %i, expected %s assertions\n" % (
-            action, data["count"], expected)
+                action, data["count"], expected)
 
     def process_output(self, data):
         rv = []
 
         pid = data['process']
         if pid.isdigit():
             pid = 'pid:%s' % pid
-        pid = self.color_formatter.pid(pid)
+        pid = self.term.dim_cyan(pid)
 
         if "command" in data and data["process"] not in self._known_pids:
             self._known_pids.add(data["process"])
             rv.append('%s Full command: %s' % (pid, data["command"]))
 
         rv.append('%s %s' % (pid, data["data"]))
         return "\n".join(rv)
 
@@ -393,76 +361,73 @@ class MachFormatter(base.BaseFormatter):
 
         if data.get("stackwalk_errors"):
             rv.extend(data.get("stackwalk_errors"))
 
         rv = "\n".join(rv)
         if not rv[-1] == "\n":
             rv += "\n"
 
-        action = self.color_formatter.action(data['action'].upper())
+        action = self.term.red(data['action'].upper())
         return "%s: %s" % (action, rv)
 
     def process_start(self, data):
         rv = "Started process `%s`" % data['process']
         desc = data.get('command')
         if desc:
             rv = '%s (%s)' % (rv, desc)
         return rv
 
     def process_exit(self, data):
         return "%s: %s" % (data['process'], strstatus(data['exitcode']))
 
     def log(self, data):
         level = data.get("level").upper()
 
         if level in ("CRITICAL", "ERROR"):
-            level = self.color_formatter.error(level)
+            level = self.term.red(level)
         elif level == "WARNING":
-            level = self.color_formatter.warning(level)
+            level = self.term.yellow(level)
         elif level == "INFO":
-            level = self.color_formatter.log_process_output(level)
+            level = self.term.blue(level)
 
         if data.get('component'):
             rv = " ".join([data["component"], level, data["message"]])
         else:
             rv = "%s %s" % (level, data["message"])
 
         if "stack" in data:
             rv += "\n%s" % data["stack"]
 
         return rv
 
     def lint(self, data):
         fmt = "{path}  {c1}{lineno}{column}  {c2}{level}{normal}  {message}" \
               "  {c1}{rule}({linter}){normal}"
         message = fmt.format(
             path=data["path"],
-            normal=self.color_formatter.normal,
-            c1=self.color_formatter.grey,
-            c2=self.color_formatter.error if data["level"] == 'error' else (
-                self.color_formatter.log_test_status_fail),
+            normal=self.term.normal,
+            c1=self.term.grey,
+            c2=self.term.red if data["level"] == 'error' else self.term.yellow,
             lineno=str(data["lineno"]),
             column=(":" + str(data["column"])) if data.get("column") else "",
             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 = [
-            "", self.color_formatter.heading(heading), self.color_formatter.heading(
-                "=" * len(heading))]
+        rv = ["", self.term.bold_yellow(heading), self.term.bold_yellow("=" * 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})