parent
68c6aaa355
commit
2dd3ea7041
|
@ -44,7 +44,7 @@ class LoopState(object):
|
||||||
self.dsession.handle_crashitem(crashitem, node)
|
self.dsession.handle_crashitem(crashitem, node)
|
||||||
self.colitems.extend(pending[1:])
|
self.colitems.extend(pending[1:])
|
||||||
|
|
||||||
def pyevent__rescheduleitems(self, items):
|
def pytest_rescheduleitems(self, items):
|
||||||
self.colitems.extend(items)
|
self.colitems.extend(items)
|
||||||
self.dowork = False # avoid busywait
|
self.dowork = False # avoid busywait
|
||||||
|
|
||||||
|
@ -204,7 +204,7 @@ class DSession(Session):
|
||||||
tosend[:] = tosend[room:] # update inplace
|
tosend[:] = tosend[room:] # update inplace
|
||||||
if tosend:
|
if tosend:
|
||||||
# we have some left, give it to the main loop
|
# we have some left, give it to the main loop
|
||||||
self.queueevent("rescheduleitems", tosend)
|
self.queueevent(pytest_rescheduleitems, tosend)
|
||||||
|
|
||||||
def senditems_load(self, tosend):
|
def senditems_load(self, tosend):
|
||||||
if not tosend:
|
if not tosend:
|
||||||
|
@ -226,7 +226,7 @@ class DSession(Session):
|
||||||
break
|
break
|
||||||
if tosend:
|
if tosend:
|
||||||
# we have some left, give it to the main loop
|
# we have some left, give it to the main loop
|
||||||
self.queueevent("rescheduleitems", tosend)
|
self.queueevent("pytest_rescheduleitems", items=tosend)
|
||||||
|
|
||||||
def removeitem(self, item, node):
|
def removeitem(self, item, node):
|
||||||
if item not in self.item2nodes:
|
if item not in self.item2nodes:
|
||||||
|
|
|
@ -99,9 +99,8 @@ class TestDSession:
|
||||||
assert session.node2pending[node1] == sent1
|
assert session.node2pending[node1] == sent1
|
||||||
assert session.node2pending[node2] == sent2
|
assert session.node2pending[node2] == sent2
|
||||||
name, args, kwargs = session.queue.get(block=False)
|
name, args, kwargs = session.queue.get(block=False)
|
||||||
assert name == "rescheduleitems"
|
assert name == "pytest_rescheduleitems"
|
||||||
items, = args
|
assert kwargs['items'] == [item]
|
||||||
assert items == [item]
|
|
||||||
|
|
||||||
def test_keyboardinterrupt(self, testdir):
|
def test_keyboardinterrupt(self, testdir):
|
||||||
item = testdir.getitem("def test_func(): pass")
|
item = testdir.getitem("def test_func(): pass")
|
||||||
|
@ -125,7 +124,7 @@ class TestDSession:
|
||||||
node = MockNode()
|
node = MockNode()
|
||||||
session.addnode(node)
|
session.addnode(node)
|
||||||
loopstate = session._initloopstate([])
|
loopstate = session._initloopstate([])
|
||||||
session.queueevent("rescheduleitems", [item])
|
session.queueevent("pytest_rescheduleitems", items=[item])
|
||||||
session.loop_once(loopstate)
|
session.loop_once(loopstate)
|
||||||
# check that RescheduleEvents are not immediately
|
# check that RescheduleEvents are not immediately
|
||||||
# rescheduled if there are no nodes
|
# rescheduled if there are no nodes
|
||||||
|
@ -292,18 +291,18 @@ class TestDSession:
|
||||||
dsel = session.filteritems([modcol])
|
dsel = session.filteritems([modcol])
|
||||||
assert dsel == [modcol]
|
assert dsel == [modcol]
|
||||||
items = modcol.collect()
|
items = modcol.collect()
|
||||||
evrec = testdir.geteventrecorder(session.bus)
|
callrecorder = testdir.geteventrecorder(session.bus).callrecorder
|
||||||
remaining = session.filteritems(items)
|
remaining = session.filteritems(items)
|
||||||
assert remaining == []
|
assert remaining == []
|
||||||
|
|
||||||
event = evrec.getcalls("deselected")[-1]
|
event = callrecorder.getcalls("pytest_deselected")[-1]
|
||||||
assert event.items == items
|
assert event.items == items
|
||||||
|
|
||||||
modcol.config.option.keyword = "test_fail"
|
modcol.config.option.keyword = "test_fail"
|
||||||
remaining = session.filteritems(items)
|
remaining = session.filteritems(items)
|
||||||
assert remaining == [items[0]]
|
assert remaining == [items[0]]
|
||||||
|
|
||||||
event = evrec.getcalls("deselected")[-1]
|
event = callrecorder.getcalls("pytest_deselected")[-1]
|
||||||
assert event.items == [items[1]]
|
assert event.items == [items[1]]
|
||||||
|
|
||||||
def test_testnodedown_shutdown_after_completion(self, testdir):
|
def test_testnodedown_shutdown_after_completion(self, testdir):
|
||||||
|
|
|
@ -147,7 +147,7 @@ def slave_runsession(channel, config, fullwidth, hasmarkup):
|
||||||
|
|
||||||
DEBUG("SLAVE: starting session.main()")
|
DEBUG("SLAVE: starting session.main()")
|
||||||
session.main(colitems)
|
session.main(colitems)
|
||||||
session.bus.notify("looponfailinfo",
|
session.config.api.pytest_looponfailinfo(
|
||||||
failreports=list(failreports),
|
failreports=list(failreports),
|
||||||
rootdirs=[config.topdir])
|
rootdirs=[config.topdir])
|
||||||
channel.send([x.colitem._totrail() for x in failreports])
|
channel.send([x.colitem._totrail() for x in failreports])
|
||||||
|
|
|
@ -104,6 +104,14 @@ class PluginHooks:
|
||||||
def pytest_testrunfinish(self, exitstatus, excrepr=None):
|
def pytest_testrunfinish(self, exitstatus, excrepr=None):
|
||||||
""" whole test run finishes. """
|
""" whole test run finishes. """
|
||||||
|
|
||||||
|
def pytest_deselected(self, items):
|
||||||
|
""" collected items that were deselected (by keyword). """
|
||||||
|
|
||||||
|
def pytest_rescheduleitems(self, items):
|
||||||
|
""" reschedule Items from a node that went down. """
|
||||||
|
|
||||||
|
def pytest_looponfailinfo(self, failreports, rootdirs):
|
||||||
|
""" info for repeating failing tests. """
|
||||||
|
|
||||||
|
|
||||||
class Events:
|
class Events:
|
||||||
|
@ -120,13 +128,4 @@ class Events:
|
||||||
def pyevent__internalerror(self, excrepr):
|
def pyevent__internalerror(self, excrepr):
|
||||||
""" called for internal errors. """
|
""" called for internal errors. """
|
||||||
|
|
||||||
def pyevent__deselected(self, items):
|
|
||||||
""" collected items that were deselected (by keyword). """
|
|
||||||
|
|
||||||
def pytest_rescheduleitems(self, items):
|
|
||||||
""" reschedule Items from a node that went down. """
|
|
||||||
|
|
||||||
def pyevent__looponfailinfo(self, failreports, rootdirs):
|
|
||||||
""" info for repeating failing tests. """
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -158,7 +158,7 @@ class TerminalReporter:
|
||||||
if self.config.option.debug:
|
if self.config.option.debug:
|
||||||
self.write_sep("!", "RESCHEDULING %s " %(items,))
|
self.write_sep("!", "RESCHEDULING %s " %(items,))
|
||||||
|
|
||||||
def pyevent__deselected(self, items):
|
def pytest_deselected(self, items):
|
||||||
self.stats.setdefault('deselected', []).append(items)
|
self.stats.setdefault('deselected', []).append(items)
|
||||||
|
|
||||||
def pytest_itemtestreport(self, rep):
|
def pytest_itemtestreport(self, rep):
|
||||||
|
@ -232,7 +232,7 @@ class TerminalReporter:
|
||||||
self.summary_deselected()
|
self.summary_deselected()
|
||||||
self.summary_stats()
|
self.summary_stats()
|
||||||
|
|
||||||
def pyevent__looponfailinfo(self, failreports, rootdirs):
|
def pytest_looponfailinfo(self, failreports, rootdirs):
|
||||||
if failreports:
|
if failreports:
|
||||||
self.write_sep("#", "LOOPONFAILING", red=True)
|
self.write_sep("#", "LOOPONFAILING", red=True)
|
||||||
for report in failreports:
|
for report in failreports:
|
||||||
|
@ -495,7 +495,7 @@ class TestTerminal:
|
||||||
""")
|
""")
|
||||||
rep = TerminalReporter(modcol.config, file=linecomp.stringio)
|
rep = TerminalReporter(modcol.config, file=linecomp.stringio)
|
||||||
reports = [runner.basic_run_report(x) for x in modcol.collect()]
|
reports = [runner.basic_run_report(x) for x in modcol.collect()]
|
||||||
rep.pyevent__looponfailinfo(reports, [modcol.config.topdir])
|
rep.pytest_looponfailinfo(reports, [modcol.config.topdir])
|
||||||
linecomp.assert_contains_lines([
|
linecomp.assert_contains_lines([
|
||||||
"*test_looponfailreport.py:2: assert 0",
|
"*test_looponfailreport.py:2: assert 0",
|
||||||
"*test_looponfailreport.py:4: ValueError*",
|
"*test_looponfailreport.py:4: ValueError*",
|
||||||
|
|
|
@ -66,7 +66,7 @@ class Session(object):
|
||||||
continue
|
continue
|
||||||
remaining.append(colitem)
|
remaining.append(colitem)
|
||||||
if deselected:
|
if deselected:
|
||||||
self.bus.notify("deselected", deselected)
|
self.config.api.pytest_deselected(items=deselected)
|
||||||
if self.config.option.keyword.endswith(":"):
|
if self.config.option.keyword.endswith(":"):
|
||||||
self._nomatch = True
|
self._nomatch = True
|
||||||
return remaining
|
return remaining
|
||||||
|
|
|
@ -102,7 +102,7 @@ class TestKeywordSelection:
|
||||||
passed, skipped, failed = sorter.listoutcomes()
|
passed, skipped, failed = sorter.listoutcomes()
|
||||||
assert len(passed) == 1
|
assert len(passed) == 1
|
||||||
assert passed[0].colitem.name == "test_2"
|
assert passed[0].colitem.name == "test_2"
|
||||||
dlist = sorter.getcalls("deselected")
|
dlist = sorter.getcalls("pytest_deselected")
|
||||||
assert len(dlist) == 1
|
assert len(dlist) == 1
|
||||||
assert dlist[0].items[0].name == 'test_1'
|
assert dlist[0].items[0].name == 'test_1'
|
||||||
|
|
||||||
|
@ -116,7 +116,7 @@ class TestKeywordSelection:
|
||||||
passed, skipped, failed = sorter.listoutcomes()
|
passed, skipped, failed = sorter.listoutcomes()
|
||||||
assert len(passed) == 2
|
assert len(passed) == 2
|
||||||
assert not failed
|
assert not failed
|
||||||
dlist = sorter.getcalls("deselected")
|
dlist = sorter.getcalls("pytest_deselected")
|
||||||
assert len(dlist) == 1
|
assert len(dlist) == 1
|
||||||
item = dlist[0].items[0]
|
item = dlist[0].items[0]
|
||||||
assert item.name == "test_one"
|
assert item.name == "test_one"
|
||||||
|
|
Loading…
Reference in New Issue