add new pytest_handlecrashitem hook

allows handling and rescheduling crash tests

PR #651

Co-authored-by: xoviat <xoviat@users.noreply.github.com>
Co-authored-by: Bruno Oliveira <nicoddemus@gmail.com>
This commit is contained in:
xoviat
2021-04-27 07:07:49 -05:00
committed by GitHub
parent f5665436e9
commit f861f1667d
7 changed files with 77 additions and 0 deletions

View File

@@ -343,6 +343,12 @@ class DSession:
nodeid, (fspath, None, fspath), (), "failed", msg, "???"
)
rep.node = worker
self.config.hook.pytest_handlecrashitem(
crashitem=nodeid,
report=rep,
sched=self.sched,
)
self.config.hook.pytest_runtest_logreport(report=rep)

View File

@@ -64,3 +64,20 @@ def pytest_xdist_auto_num_workers(config):
.. versionadded:: 2.1
"""
@pytest.mark.firstresult
def pytest_handlecrashitem(crashitem, report, sched):
"""
Handle a crashitem, modifying the report if necessary.
The scheduler is provided as a parameter to reschedule the test if desired with
`sched.mark_test_pending`.
def pytest_handlecrashitem(crashitem, report, sched):
if should_rerun(crashitem):
sched.mark_test_pending(crashitem)
report.outcome = "rerun"
.. versionadded:: 2.2.1
"""

View File

@@ -101,6 +101,14 @@ class EachScheduling:
def mark_test_complete(self, node, item_index, duration=0):
self.node2pending[node].remove(item_index)
def mark_test_pending(self, item):
self.pending.insert(
0,
self.collection.index(item),
)
for node in self.node2pending:
self.check_schedule(node)
def remove_node(self, node):
# KeyError if we didn't get an add_node() yet
pending = self.node2pending.pop(node)

View File

@@ -151,6 +151,14 @@ class LoadScheduling:
self.node2pending[node].remove(item_index)
self.check_schedule(node, duration=duration)
def mark_test_pending(self, item):
self.pending.insert(
0,
self.collection.index(item),
)
for node in self.node2pending:
self.check_schedule(node)
def check_schedule(self, node, duration=0):
"""Maybe schedule new items on the node

View File

@@ -243,6 +243,9 @@ class LoadScopeScheduling:
self.assigned_work[node][scope][nodeid] = True
self._reschedule(node)
def mark_test_pending(self, item):
raise NotImplementedError()
def _assign_work_unit(self, node):
"""Assign a work unit to a node."""
assert self.workqueue