Bug 1342954 - Improve ERROR handling in pytest_mozlog r=davehunt
Not all report objects are strings, tuples or have a .crashrepr
property. In particular some brokeness in wdspec test setup produced
an object with a .errorstring property. Handle that and the general
case of being passed a weird object more gracefully.
MozReview-Commit-ID: 8vfuNNmwjhC
--- a/testing/mozbase/mozlog/mozlog/pytest_mozlog/plugin.py
+++ b/testing/mozbase/mozlog/mozlog/pytest_mozlog/plugin.py
@@ -78,31 +78,36 @@ class MozLog(object):
message = stack = None
if hasattr(report, 'wasxfail'):
expected = 'FAIL'
if report.failed:
status = 'FAIL' if report.when == 'call' else 'ERROR'
if report.skipped:
status = 'SKIP' if not hasattr(report, 'wasxfail') else 'FAIL'
if report.longrepr is not None:
- if isinstance(report.longrepr, basestring):
+ longrepr = report.longrepr
+ if isinstance(longrepr, basestring):
# When using pytest-xdist, longrepr is serialised as a str
- message = stack = report.longrepr
- if report.longrepr.startswith('[XPASS(strict)]'):
+ message = stack = longrepr
+ if longrepr.startswith('[XPASS(strict)]'):
# Strict expected failures have an outcome of failed when
# they unexpectedly pass.
expected, status = ('FAIL', 'PASS')
+ elif hasattr(longrepr, "reprcrash"):
+ # For failures, longrepr is a ReprExceptionInfo
+ crash = longrepr.reprcrash
+ message = "{0} (line {1})".format(crash.message, crash.lineno)
+ stack = longrepr.reprtraceback
+ elif hasattr(longrepr, "errorstring"):
+ message = longrepr.errorstring
+ stack = longrepr.errorstring
+ elif hasattr(longrepr, "__getitem__") and len(longrepr) == 3:
+ # For skips, longrepr is a tuple of (file, lineno, reason)
+ message = report.longrepr[-1]
else:
- try:
- # For failures, longrepr is a ReprExceptionInfo
- crash = report.longrepr.reprcrash
- message = "{0} (line {1})".format(crash.message, crash.lineno)
- stack = report.longrepr.reprtraceback
- except AttributeError:
- # For skips, longrepr is a tuple of (file, lineno, reason)
- message = report.longrepr[-1]
+ raise ValueError, "Unable to convert longrepr to message:\ntype %s\nfields:" % (longrepr.__class__, dir(longrepr))
if status != expected or expected != 'PASS':
self.results[test] = (status, expected, message, stack)
if report.when == 'teardown':
defaults = ('PASS', 'PASS', None, None)
status, expected, message, stack = self.results.get(test, defaults)
self.logger.test_end(test=test, status=status, expected=expected,
message=message, stack=stack)