diff options
Diffstat (limited to '')
-rw-r--r-- | testing/mozbase/mozlog/mozlog/handlers/statushandler.py | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/testing/mozbase/mozlog/mozlog/handlers/statushandler.py b/testing/mozbase/mozlog/mozlog/handlers/statushandler.py new file mode 100644 index 0000000000..5093c934fe --- /dev/null +++ b/testing/mozbase/mozlog/mozlog/handlers/statushandler.py @@ -0,0 +1,93 @@ +# 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 + +from collections import ( + defaultdict, + namedtuple, +) + + +RunSummary = namedtuple( + "RunSummary", + ( + "unexpected_statuses", + "expected_statuses", + "known_intermittent_statuses", + "log_level_counts", + "action_counts", + ), +) + + +class StatusHandler(object): + """A handler used to determine an overall status for a test run according + to a sequence of log messages.""" + + def __init__(self): + # The count of each type of unexpected result status (includes tests and subtests) + self.unexpected_statuses = defaultdict(int) + # The count of each type of expected result status (includes tests and subtests) + self.expected_statuses = defaultdict(int) + # The count of known intermittent result statuses (includes tests and subtests) + self.known_intermittent_statuses = defaultdict(int) + # The count of actions logged + self.action_counts = defaultdict(int) + # The count of messages logged at each log level + self.log_level_counts = defaultdict(int) + # The count of "No tests run" error messages seen + self.no_tests_run_count = 0 + + def __call__(self, data): + action = data["action"] + known_intermittent = data.get("known_intermittent", []) + self.action_counts[action] += 1 + + if action == "log": + if data["level"] == "ERROR" and data["message"] == "No tests ran": + self.no_tests_run_count += 1 + self.log_level_counts[data["level"]] += 1 + + if action in ("test_status", "test_end"): + status = data["status"] + # Don't count known_intermittent status as unexpected + if "expected" in data and status not in known_intermittent: + self.unexpected_statuses[status] += 1 + else: + self.expected_statuses[status] += 1 + # Count known_intermittent as expected and intermittent. + if status in known_intermittent: + self.known_intermittent_statuses[status] += 1 + + if action == "assertion_count": + if data["count"] < data["min_expected"]: + self.unexpected_statuses["PASS"] += 1 + elif data["count"] > data["max_expected"]: + self.unexpected_statuses["FAIL"] += 1 + elif data["count"]: + self.expected_statuses["FAIL"] += 1 + else: + self.expected_statuses["PASS"] += 1 + + if action == "lsan_leak": + if not data.get("allowed_match"): + self.unexpected_statuses["FAIL"] += 1 + + if action == "lsan_summary": + if not data.get("allowed", False): + self.unexpected_statuses["FAIL"] += 1 + + if action == "mozleak_total": + if data["bytes"] is not None and data["bytes"] > data.get("threshold", 0): + self.unexpected_statuses["FAIL"] += 1 + + def summarize(self): + return RunSummary( + dict(self.unexpected_statuses), + dict(self.expected_statuses), + dict(self.known_intermittent_statuses), + dict(self.log_level_counts), + dict(self.action_counts), + ) |