[py-svn] pytest-xdist commit 922c00c8c2fa: adapt to pytest changes, add looponfailingdirs ini-option

commits-noreply at bitbucket.org commits-noreply at bitbucket.org
Sat Nov 6 09:57:05 CET 2010


# HG changeset patch -- Bitbucket.org
# Project pytest-xdist
# URL http://bitbucket.org/hpk42/pytest-xdist/overview
# User holger krekel <holger at merlinux.eu>
# Date 1289033880 -3600
# Node ID 922c00c8c2fa0bebe693cab54301a01c43159e55
# Parent  724fe27731c76cf8a91472cf8cdacfb336365765
adapt to pytest changes, add looponfailingdirs ini-option

--- a/tox.ini
+++ b/tox.ini
@@ -16,5 +16,5 @@ deps=
     pytest
     pypi pexpect
 
-[pytest]
-addopts = -rf
+#[pytest]
+#addopts = -rf

--- a/xdist/dsession.py
+++ b/xdist/dsession.py
@@ -301,7 +301,7 @@ class DSession:
         runner = self.config.pluginmanager.getplugin("runner")
         fspath = nodeid.split("::")[0]
         msg = "Slave %r crashed while running %r" %(slave.gateway.id, nodeid)
-        rep = runner.TestReport(nodeid, (), fspath, (fspath, None, fspath), (),
+        rep = runner.TestReport(nodeid, (fspath, None, fspath), (),
             "failed", msg, "???")
         enrich_report_with_platform_data(rep, slave)
         self.config.hook.pytest_runtest_logreport(report=rep)
@@ -350,6 +350,6 @@ def enrich_report_with_platform_data(rep
         ver = "%s.%s.%s" % d['version_info'][:3]
         infoline = "[%s] %s -- Python %s %s" % (
             d['id'], d['sysplatform'], ver, d['executable'])
-        # XXX more structured longrepr? 
+        # XXX more structured longrepr?
         rep.longrepr = infoline + "\n\n" + str(rep.longrepr)
 

--- a/xdist/__init__.py
+++ b/xdist/__init__.py
@@ -1,2 +1,2 @@
 #
-__version__ = '1.5a4'
+__version__ = '1.5a5'

--- a/testing/test_slavemanage.py
+++ b/testing/test_slavemanage.py
@@ -11,7 +11,7 @@ def pytest_funcarg__hookrecorder(request
 
 def pytest_funcarg__hook(request):
     from xdist import newhooks
-    from pytest._core import HookRelay, PluginManager
+    from pytest.main import HookRelay, PluginManager
     from pytest import hookspec
     return HookRelay([hookspec, newhooks], PluginManager())
 

--- a/testing/test_remote.py
+++ b/testing/test_remote.py
@@ -156,6 +156,8 @@ class TestSlaveInteractor:
         assert not ev.kwargs
         ev = slave.popevent()
         assert ev.name == "collectreport"
+        ev = slave.popevent()
+        assert ev.name == "collectreport"
         rep = unserialize_report(ev.name, ev.kwargs['data'])
         assert rep.skipped
         ev = slave.popevent("collectionfinish")
@@ -168,6 +170,8 @@ class TestSlaveInteractor:
         assert not ev.kwargs
         ev = slave.popevent()
         assert ev.name == "collectreport"
+        ev = slave.popevent()
+        assert ev.name == "collectreport"
         rep = unserialize_report(ev.name, ev.kwargs['data'])
         assert rep.failed
         ev = slave.popevent("collectionfinish")

--- a/xdist/plugin.py
+++ b/xdist/plugin.py
@@ -142,7 +142,7 @@ where the configuration file was found.
 """
 
 import sys
-import py
+import py, pytest
 
 def pytest_addoption(parser):
     group = parser.getgroup("xdist", "distributed and subprocess testing")
@@ -178,6 +178,8 @@ def pytest_addoption(parser):
          ' remote distributed testing.', type="pathlist")
     parser.addini('rsyncignore', 'list of (relative) paths to be ignored '
          'for rsyncing.', type="pathlist")
+    parser.addini("looponfailroots", type="pathlist",
+        help="directories to check for changes", default=[py.path.local()])
 
 # -------------------------------------------------------------------------
 # distributed testing hooks
@@ -218,10 +220,10 @@ def check_options(config):
         usepdb = config.option.usepdb  # a core option
         if val("looponfail"):
             if usepdb:
-                raise config.Error("--pdb incompatible with --looponfail.")
+                raise pytest.UsageError("--pdb incompatible with --looponfail.")
         elif val("dist") != "no":
             if usepdb:
-                raise config.Error("--pdb incompatible with distributing tests.")
+                raise pytest.UsageError("--pdb incompatible with distributing tests.")
 
 
 def pytest_runtest_protocol(item):

--- a/xdist/looponfail.py
+++ b/xdist/looponfail.py
@@ -7,21 +7,22 @@
     the controlling process which should best never happen.
 """
 
-import py
+import py, pytest
 import sys
 import execnet
 
 def looponfail_main(config):
     remotecontrol = RemoteControl(config)
-    # XXX better configure rootdir
-    gettopdir = config.pluginmanager.getplugin("session").gettopdir
-    rootdirs = [gettopdir(config.args)]
+    rootdirs = config.getini("looponfailroots")
     statrecorder = StatRecorder(rootdirs)
     try:
         while 1:
             remotecontrol.loop_once()
             if not remotecontrol.failures and remotecontrol.wasfailing:
                 continue # the last failures passed, let's immediately rerun all
+            repr_pytest_looponfailinfo(
+                failreports=remotecontrol.failures,
+                rootdirs=rootdirs)
             statrecorder.waitonchange(checkinterval=2.0)
     except KeyboardInterrupt:
         print()
@@ -29,7 +30,6 @@ def looponfail_main(config):
 class RemoteControl(object):
     def __init__(self, config):
         self.config = config
-        self.remote_topdir = None
         self.failures = []
 
     def trace(self, *args):
@@ -70,8 +70,8 @@ class RemoteControl(object):
 
     def runsession(self):
         try:
-            self.trace("sending", (self.remote_topdir, self.failures))
-            self.channel.send((self.remote_topdir, self.failures))
+            self.trace("sending", self.failures)
+            self.channel.send(self.failures)
             try:
                 return self.channel.receive()
             except self.channel.RemoteError:
@@ -85,15 +85,11 @@ class RemoteControl(object):
         self.setup()
         self.wasfailing = self.failures and len(self.failures)
         result = self.runsession()
-        topdir, failures, reports, collection_failed = result
+        failures, reports, collection_failed = result
         if collection_failed:
             reports = ["Collection failed, keeping previous failure set"]
         else:
-            self.remote_topdir, self.failures = topdir, failures
-
-        repr_pytest_looponfailinfo(
-            failreports=reports,
-            rootdirs=[self.remote_topdir],)
+            self.failures = failures
 
 def repr_pytest_looponfailinfo(failreports, rootdirs):
     tr = py.io.TerminalWriter()
@@ -147,23 +143,29 @@ class SlaveFailSession:
 
     def pytest_collection(self, session):
         self.session = session
-        self.collection = session.collection
-        self.topdir, self.trails = self.current_command
-        if self.topdir and self.trails:
-            self.topdir = py.path.local(self.topdir)
-            self.collection.topdir = self.topdir
+        self.collection = collection = session.collection
+        self.trails = self.current_command
+        hook = self.collection.ihook
+        try:
+            items = collection.perform_collect(self.trails or None)
+        except pytest.UsageError:
+            items = collection.perform_collect(None)
+        hook.pytest_collection_modifyitems(config=session.config, items=items)
+        hook.pytest_collection_finish(collection=collection)
+        return True
+
+        if self.trails:
             col = self.collection
             items = []
             for trail in self.trails:
-                names = col._parsearg(trail, base=self.topdir)
+                names = col._parsearg(trail)
                 try:
                     for node in col.matchnodes([col._topcollector], names):
                         items.extend(col.genitems(node))
-                except self.config.Error:
+                except pytest.UsageError:
                     pass # ignore collect errors / vanished tests
             self.collection.items = items
             return True
-        self.topdir = session.collection.topdir
 
     def pytest_runtest_logreport(self, report):
         if report.failed:
@@ -189,8 +191,7 @@ class SlaveFailSession:
             loc = rep.longrepr
             loc = str(getattr(loc, 'reprcrash', loc))
             failreports.append(loc)
-        topdir = str(self.topdir)
-        self.channel.send((topdir, trails, failreports, self.collection_failed))
+        self.channel.send((trails, failreports, self.collection_failed))
 
 class StatRecorder:
     def __init__(self, rootdirlist):

--- a/xdist/remote.py
+++ b/xdist/remote.py
@@ -53,8 +53,8 @@ class SlaveInteractor:
             if name == "runtests":
                 ids = kwargs['ids']
                 for nodeid in ids:
-                    for item in self.collection.getbyid(nodeid):
-                        self.config.hook.pytest_runtest_protocol(item=item)
+                    item = self._id2item[nodeid]
+                    self.config.hook.pytest_runtest_protocol(item=item)
             elif name == "runtests_all":
                 for item in self.collection.items:
                     self.config.hook.pytest_runtest_protocol(item=item)
@@ -63,9 +63,13 @@ class SlaveInteractor:
         return True
 
     def pytest_collection_finish(self, collection):
-        ids = [collection.getid(item) for item in collection.items]
+        self._id2item = {}
+        ids = []
+        for item in collection.items:
+            self._id2item[item.nodeid] = item
+            ids.append(item.nodeid)
         self.sendevent("collectionfinish",
-            topdir=str(collection.topdir),
+            topdir=str(collection.fspath),
             ids=ids)
 
     #def pytest_runtest_logstart(self, nodeid, location, fspath):

--- a/setup.py
+++ b/setup.py
@@ -10,7 +10,7 @@ from setuptools import setup
 
 setup(
     name="pytest-xdist",
-    version='1.5a4',
+    version='1.5a5',
     description='py.test xdist plugin for distributed testing and loop-on-failing modes',
     long_description=__doc__,
     license='GPLv2 or later',



More information about the pytest-commit mailing list