adapt for py-trunk/1.3.1 changes wrt --exitfirst -> --maxfailures

This commit is contained in:
holger krekel
2010-05-25 16:59:08 +02:00
parent 7b19de5450
commit f7be994848
4 changed files with 48 additions and 17 deletions

View File

@@ -4,6 +4,8 @@
- fix --looponfailing - it would not actually run against the fully changed - fix --looponfailing - it would not actually run against the fully changed
source tree when initial conftest files load application state. source tree when initial conftest files load application state.
- adapt for py-1.3.1's new --maxfailure option
1.2 1.2
------------------------- -------------------------

View File

@@ -22,7 +22,7 @@ setup(
packages = ['xdist'], packages = ['xdist'],
entry_points = {'pytest11': ['xdist = xdist.plugin'],}, entry_points = {'pytest11': ['xdist = xdist.plugin'],},
zip_safe=False, zip_safe=False,
install_requires = ['execnet>=1.0.6', 'py>=1.3.0'], install_requires = ['execnet>=1.0.6', 'py>=1.3.1'],
classifiers=[ classifiers=[
'Development Status :: 4 - Beta', 'Development Status :: 4 - Beta',
'Intended Audience :: Developers', 'Intended Audience :: Developers',

View File

@@ -259,7 +259,7 @@ class TestDSession:
def test_pass(): def test_pass():
pass pass
""") """)
modcol.config.option.exitfirst = True modcol.config.option.maxfail = 1
session = DSession(modcol.config) session = DSession(modcol.config)
node = MockNode() node = MockNode()
session.addnode(node) session.addnode(node)
@@ -271,12 +271,44 @@ class TestDSession:
# run tests ourselves and produce reports # run tests ourselves and produce reports
ev1 = run(items[0], node, "fail") ev1 = run(items[0], node, "fail")
ev2 = run(items[1], node, None) 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=ev1) # a failing one
session.queueevent("pytest_runtest_logreport", report=ev2) session.queueevent("pytest_runtest_logreport", report=ev2)
# now call the loop # now call the loop
loopstate = session._initloopstate(items) loopstate = session._initloopstate(items)
from xdist.dsession import ExitFirstInterrupt try:
py.test.raises(ExitFirstInterrupt, "session.loop_once(loopstate)") 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.testsfailed
#assert loopstate.shuttingdown #assert loopstate.shuttingdown

View File

@@ -20,7 +20,7 @@ class LoopState(object):
# waiting for a host to become ready. # waiting for a host to become ready.
self.dowork = True self.dowork = True
self.shuttingdown = False self.shuttingdown = False
self.testsfailed = False self.testsfailed = 0
def __repr__(self): def __repr__(self):
return "<LoopState exitstatus=%r shuttingdown=%r len(colitems)=%d>" % ( 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 if report.when != "teardown": # otherwise we already managed it
self.dsession.removeitem(report.item, report.node) self.dsession.removeitem(report.item, report.node)
if report.failed: if report.failed:
self.testsfailed = True self.testsfailed += 1
def pytest_collectreport(self, report): def pytest_collectreport(self, report):
if report.passed: if report.passed:
@@ -58,9 +58,6 @@ class LoopState(object):
if pending: if pending:
self.dowork = False # avoid busywait, nodes still have work self.dowork = False # avoid busywait, nodes still have work
class ExitFirstInterrupt(KeyboardInterrupt):
pass
class DSession(session.Session): class DSession(session.Session):
""" """
Session drives the collection and running of tests Session drives the collection and running of tests
@@ -131,11 +128,14 @@ class DSession(session.Session):
call(**kwargs) call(**kwargs)
# termination conditions # termination conditions
maxfail = self.config.getvalue("maxfail")
if (not self.node2pending or 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())): (not self.item2nodes and not colitems and not self.queue.qsize())):
if self.config.option.exitfirst: if maxfail and loopstate.testsfailed >= maxfail:
raise ExitFirstInterrupt() raise self.Interrupted("stopping after %d failures" % (
loopstate.testsfailed))
self.triggershutdown() self.triggershutdown()
loopstate.shuttingdown = True loopstate.shuttingdown = True
if not self.node2pending: if not self.node2pending:
@@ -181,9 +181,6 @@ class DSession(session.Session):
break break
except KeyboardInterrupt: except KeyboardInterrupt:
excinfo = py.code.ExceptionInfo() excinfo = py.code.ExceptionInfo()
if excinfo.errisinstance(ExitFirstInterrupt):
exitstatus = session.EXIT_TESTSFAILED
else:
self.config.hook.pytest_keyboard_interrupt(excinfo=excinfo) self.config.hook.pytest_keyboard_interrupt(excinfo=excinfo)
exitstatus = session.EXIT_INTERRUPTED exitstatus = session.EXIT_INTERRUPTED
except: except: