Bug 1068732 - Add action counts to mozlog status handler to account for crashes. r=jgraham

This commit is contained in:
Chris Manchester 2014-09-22 14:37:10 -04:00
parent 999a679fe9
commit 19dce7db4b
2 changed files with 28 additions and 84 deletions

View File

@ -2,9 +2,16 @@
# 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 collections import defaultdict
from collections import (
defaultdict,
namedtuple,
)
from mozlog.structured.structuredlog import log_levels
RunSummary = namedtuple("RunSummary",
("unexpected", "skipped", "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."""
@ -14,19 +21,18 @@ class StatusHandler(object):
self.unexpected = 0
# The count of skip results (includes tests and subtests)
self.skipped = 0
# The count of top level tests run (test_end messages)
self.test_count = 0
# The count of actions logged
self.action_counts = defaultdict(int)
# The count of messages logged at each log level
self.level_counts = defaultdict(int)
self.log_level_counts = defaultdict(int)
def __call__(self, data):
action = data['action']
if action == 'log':
self.level_counts[data['level']] += 1
self.action_counts[action] += 1
if action == 'test_end':
self.test_count += 1
if action == 'log':
self.log_level_counts[data['level']] += 1
if action in ('test_status', 'test_end'):
if 'expected' in data:
@ -35,25 +41,10 @@ class StatusHandler(object):
if data['status'] == 'SKIP':
self.skipped += 1
def evaluate(self):
status = 'OK'
if self.unexpected:
status = 'FAIL'
if not self.test_count:
status = 'ERROR'
for level in self.level_counts:
if log_levels[level] <= log_levels['ERROR']:
status = 'ERROR'
summary = {
'status': status,
'unexpected': self.unexpected,
'skipped': self.skipped,
'test_count': self.test_count,
'level_counts': dict(self.level_counts),
}
return summary
def summarize(self):
return RunSummary(
self.unexpected,
self.skipped,
dict(self.log_level_counts),
dict(self.action_counts),
)

View File

@ -62,27 +62,6 @@ class TestStatusHandler(BaseStructuredTest):
self.handler = handlers.StatusHandler()
self.logger.add_handler(self.handler)
def assertStatus(self, expected):
"""Assert every key present in expected matches the current
status."""
actual = self.handler.evaluate()
for k, v in expected.iteritems():
self.assertEquals(expected[k], actual[k])
def test_ok_run(self):
self.logger.suite_start([])
self.logger.test_start("test1")
self.logger.test_status("test1", "sub1", status='PASS')
self.logger.info("Info between sub1 and sub2")
self.logger.test_status("test1", "sub2", status='PASS')
self.logger.test_end("test1", status='OK')
self.logger.suite_end()
self.assertStatus({
"status": "OK",
"test_count": 1,
"level_counts": { "INFO": 1 },
})
def test_failure_run(self):
self.logger.suite_start([])
self.logger.test_start("test1")
@ -90,12 +69,10 @@ class TestStatusHandler(BaseStructuredTest):
self.logger.test_status("test1", "sub2", status='TIMEOUT')
self.logger.test_end("test1", status='OK')
self.logger.suite_end()
self.assertStatus({
"status": "FAIL",
"test_count": 1,
"unexpected": 1,
"level_counts": {},
})
summary = self.handler.summarize()
self.assertEqual(1, summary.unexpected)
self.assertEqual(2, summary.action_counts['test_status'])
self.assertEqual(1, summary.action_counts['test_end'])
def test_error_run(self):
self.logger.suite_start([])
@ -105,33 +82,9 @@ class TestStatusHandler(BaseStructuredTest):
self.logger.test_start("test2")
self.logger.test_end("test2", status='PASS')
self.logger.suite_end()
self.assertStatus({
"status": "ERROR",
"test_count": 2,
"level_counts": {'ERROR': 1},
})
def test_error_trumps_failure(self):
self.logger.suite_start([])
self.logger.test_start("test1")
self.logger.critical("ERRR!")
self.logger.test_status("test1", "sub1", status='FAIL')
self.logger.test_end("test1", status='OK')
self.logger.suite_end()
self.assertStatus({
"status": "ERROR",
"test_count": 1,
"level_counts": {'CRITICAL': 1},
})
def test_notrun_is_error(self):
self.logger.suite_start([])
self.logger.suite_end()
self.assertStatus({
"status": "ERROR",
"test_count": 0,
"level_counts": {},
})
summary = self.handler.summarize()
self.assertIn('ERROR', summary.log_level_counts)
self.assertEqual(1, summary.log_level_counts['ERROR'])
class TestStructuredLog(BaseStructuredTest):