# HG changeset patch -- Bitbucket.org # Project pytest-xdist # URL http://bitbucket.org/hpk42/pytest-xdist/overview # User holger krekel <hol...@merlinux.eu> # Date 1274799548 -7200 # Node ID 1392e029c5674cec9a5eede65c0d5c53f124b79e # Parent d3fc793b801dbf898cce33b301c125828cfe7926 adapt for py-trunk/1.3.1 changes wrt --exitfirst -> --maxfailures
--- a/testing/test_dsession.py +++ b/testing/test_dsession.py @@ -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 --- a/setup.py +++ b/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', --- a/xdist/dsession.py +++ b/xdist/dsession.py @@ -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 --- a/CHANGELOG +++ b/CHANGELOG @@ -4,6 +4,8 @@ 1.3 - 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 ------------------------- _______________________________________________ py-svn mailing list py-svn@codespeak.net http://codespeak.net/mailman/listinfo/py-svn