adapt for py-trunk/1.3.1 changes wrt --exitfirst -> --maxfailures
This commit is contained in:
@@ -4,6 +4,8 @@
|
||||
- fix --looponfailing - it would not actually run against the fully changed
|
||||
source tree when initial conftest files load application state.
|
||||
|
||||
- adapt for py-1.3.1's new --maxfailure option
|
||||
|
||||
1.2
|
||||
-------------------------
|
||||
|
||||
|
||||
2
setup.py
2
setup.py
@@ -22,7 +22,7 @@ setup(
|
||||
packages = ['xdist'],
|
||||
entry_points = {'pytest11': ['xdist = xdist.plugin'],},
|
||||
zip_safe=False,
|
||||
install_requires = ['execnet>=1.0.6', 'py>=1.3.0'],
|
||||
install_requires = ['execnet>=1.0.6', 'py>=1.3.1'],
|
||||
classifiers=[
|
||||
'Development Status :: 4 - Beta',
|
||||
'Intended Audience :: Developers',
|
||||
|
||||
@@ -259,7 +259,7 @@ class TestDSession:
|
||||
def test_pass():
|
||||
pass
|
||||
""")
|
||||
modcol.config.option.exitfirst = True
|
||||
modcol.config.option.maxfail = 1
|
||||
session = DSession(modcol.config)
|
||||
node = MockNode()
|
||||
session.addnode(node)
|
||||
@@ -271,12 +271,44 @@ class TestDSession:
|
||||
# run tests ourselves and produce reports
|
||||
ev1 = run(items[0], node, "fail")
|
||||
ev2 = run(items[1], node, None)
|
||||
session.queueevent("pytest_runtest_logreport", report=ev1)
|
||||
session.queueevent("pytest_runtest_logreport", report=ev2)
|
||||
# now call the loop
|
||||
loopstate = session._initloopstate(items)
|
||||
py.test.raises(session.Interrupted, "session.loop_once(loopstate)")
|
||||
assert loopstate.testsfailed
|
||||
#assert loopstate.shuttingdown
|
||||
|
||||
def test_maxfail(self, testdir):
|
||||
modcol = testdir.getmodulecol("""
|
||||
def test_fail1():
|
||||
assert 0
|
||||
def test_fail2():
|
||||
assert 0
|
||||
def test_pass():
|
||||
pass
|
||||
""")
|
||||
modcol.config.option.maxfail = 2
|
||||
session = DSession(modcol.config)
|
||||
node = MockNode()
|
||||
session.addnode(node)
|
||||
items = modcol.config.hook.pytest_make_collect_report(collector=modcol).result
|
||||
|
||||
# trigger testing - this sends tests to the node
|
||||
session.triggertesting(items)
|
||||
|
||||
# run tests ourselves and produce reports
|
||||
ev1 = run(items[0], node, "fail")
|
||||
ev2 = run(items[1], node, "fail")
|
||||
session.queueevent("pytest_runtest_logreport", report=ev1) # a failing one
|
||||
session.queueevent("pytest_runtest_logreport", report=ev2)
|
||||
# now call the loop
|
||||
loopstate = session._initloopstate(items)
|
||||
from xdist.dsession import ExitFirstInterrupt
|
||||
py.test.raises(ExitFirstInterrupt, "session.loop_once(loopstate)")
|
||||
try:
|
||||
session.loop_once(loopstate)
|
||||
except session.Interrupted:
|
||||
py.test.fail("raised Interrupted but shouildn't")
|
||||
py.test.raises(session.Interrupted, "session.loop_once(loopstate)")
|
||||
assert loopstate.testsfailed
|
||||
#assert loopstate.shuttingdown
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ class LoopState(object):
|
||||
# waiting for a host to become ready.
|
||||
self.dowork = True
|
||||
self.shuttingdown = False
|
||||
self.testsfailed = False
|
||||
self.testsfailed = 0
|
||||
|
||||
def __repr__(self):
|
||||
return "<LoopState exitstatus=%r shuttingdown=%r len(colitems)=%d>" % (
|
||||
@@ -31,7 +31,7 @@ class LoopState(object):
|
||||
if report.when != "teardown": # otherwise we already managed it
|
||||
self.dsession.removeitem(report.item, report.node)
|
||||
if report.failed:
|
||||
self.testsfailed = True
|
||||
self.testsfailed += 1
|
||||
|
||||
def pytest_collectreport(self, report):
|
||||
if report.passed:
|
||||
@@ -58,9 +58,6 @@ class LoopState(object):
|
||||
if pending:
|
||||
self.dowork = False # avoid busywait, nodes still have work
|
||||
|
||||
class ExitFirstInterrupt(KeyboardInterrupt):
|
||||
pass
|
||||
|
||||
class DSession(session.Session):
|
||||
"""
|
||||
Session drives the collection and running of tests
|
||||
@@ -131,11 +128,14 @@ class DSession(session.Session):
|
||||
call(**kwargs)
|
||||
|
||||
# termination conditions
|
||||
maxfail = self.config.getvalue("maxfail")
|
||||
if (not self.node2pending or
|
||||
(loopstate.testsfailed and self.config.option.exitfirst) or
|
||||
(loopstate.testsfailed and maxfail and
|
||||
loopstate.testsfailed >= maxfail) or
|
||||
(not self.item2nodes and not colitems and not self.queue.qsize())):
|
||||
if self.config.option.exitfirst:
|
||||
raise ExitFirstInterrupt()
|
||||
if maxfail and loopstate.testsfailed >= maxfail:
|
||||
raise self.Interrupted("stopping after %d failures" % (
|
||||
loopstate.testsfailed))
|
||||
self.triggershutdown()
|
||||
loopstate.shuttingdown = True
|
||||
if not self.node2pending:
|
||||
@@ -181,11 +181,8 @@ class DSession(session.Session):
|
||||
break
|
||||
except KeyboardInterrupt:
|
||||
excinfo = py.code.ExceptionInfo()
|
||||
if excinfo.errisinstance(ExitFirstInterrupt):
|
||||
exitstatus = session.EXIT_TESTSFAILED
|
||||
else:
|
||||
self.config.hook.pytest_keyboard_interrupt(excinfo=excinfo)
|
||||
exitstatus = session.EXIT_INTERRUPTED
|
||||
self.config.hook.pytest_keyboard_interrupt(excinfo=excinfo)
|
||||
exitstatus = session.EXIT_INTERRUPTED
|
||||
except:
|
||||
self.config.pluginmanager.notify_exception()
|
||||
exitstatus = session.EXIT_INTERNALERROR
|
||||
|
||||
Reference in New Issue
Block a user