Updated serialize_report and unserialize_report to pass entire exception info using ReprExceptionInfo.

This addresses issue #130.
This commit is contained in:
thou
2017-06-15 15:15:54 -05:00
committed by Tim Hou
parent 2094157950
commit 4a1f1d879b
4 changed files with 80 additions and 4 deletions

1
changelog/133.bugfix Normal file
View File

@@ -0,0 +1 @@
Fix serialization and deserialization dropping longrepr details.

View File

@@ -79,6 +79,20 @@ def test_remoteinitconfig(testdir):
class TestReportSerialization:
def test_xdist_report_longrepr_reprcrash_130(self, testdir):
reprec = testdir.inline_runsource("""
import py
def test_fail(): assert False, 'Expected Message'
""")
reports = reprec.getreports("pytest_runtest_logreport")
assert len(reports) == 3
initial_failure_report = reports[1]
d = serialize_report(initial_failure_report)
check_marshallable(d)
processed_report = unserialize_report("testreport", d)
assert 'Expected Message' \
in processed_report.longrepr.reprcrash.message
def test_itemreport_outcomes(self, testdir):
reprec = testdir.inline_runsource("""
import py
@@ -108,7 +122,7 @@ class TestReportSerialization:
assert newrep.when == rep.when
assert newrep.keywords == rep.keywords
if rep.failed:
assert newrep.longrepr == str(rep.longrepr)
assert newrep.longreprtext == rep.longreprtext
def test_collectreport_passed(self, testdir):
reprec = testdir.inline_runsource("def test_func(): pass")

View File

@@ -98,9 +98,32 @@ class SlaveInteractor:
def serialize_report(rep):
def disassembled_report(rep):
reprtraceback = rep.longrepr.reprtraceback.__dict__
reprcrash = rep.longrepr.reprcrash.__dict__
new_entries = []
for entry in reprtraceback['reprentries']:
new_entry = entry.__dict__
for key, value in new_entry.items():
if hasattr(value, '__dict__'):
new_entry[key] = value.__dict__
new_entries.append(new_entry)
reprtraceback['reprentries'] = new_entries
return {
'reprcrash': reprcrash,
'reprtraceback': reprtraceback
}
import py
d = rep.__dict__.copy()
if hasattr(rep.longrepr, 'toterminal'):
if hasattr(rep.longrepr, 'reprtraceback') \
and hasattr(rep.longrepr, 'reprcrash'):
d['longrepr'] = disassembled_report(rep)
else:
d['longrepr'] = str(rep.longrepr)
else:
d['longrepr'] = rep.longrepr

View File

@@ -327,7 +327,45 @@ class SlaveController(object):
def unserialize_report(name, reportdict):
def assembled_report(reportdict):
from _pytest._code.code import (
ReprExceptionInfo,
ReprFileLocation,
ReprEntry,
ReprFuncArgs,
ReprTraceback
)
if reportdict['longrepr']:
if 'reprcrash' and 'reprtraceback' in reportdict['longrepr']:
reprtraceback = reportdict['longrepr']['reprtraceback']
reprcrash = reportdict['longrepr']['reprcrash']
unserialized_entries = []
for entry in reprtraceback['reprentries']:
reprfuncargs, reprfileloc = None, None
if entry['reprfuncargs']:
reprfuncargs = ReprFuncArgs(**entry['reprfuncargs'])
if entry['reprfileloc']:
reprfileloc = ReprFileLocation(**entry['reprfileloc'])
reprentry = ReprEntry(
lines=entry['lines'],
reprfuncargs=reprfuncargs,
reprlocals=entry['reprlocals'],
filelocrepr=reprfileloc,
style=entry['style']
)
unserialized_entries.append(reprentry)
reprtraceback['reprentries'] = unserialized_entries
reportdict['longrepr'] = ReprExceptionInfo(
reprtraceback=ReprTraceback(**reprtraceback),
reprcrash=ReprFileLocation(**reprcrash),
)
return reportdict
if name == "testreport":
return runner.TestReport(**reportdict)
return runner.TestReport(**assembled_report(reportdict))
elif name == "collectreport":
return runner.CollectReport(**reportdict)
return runner.CollectReport(**assembled_report(reportdict))