Commits

holger krekel committed b92fb2f

fix issue 93 of pytest - avoid delayed teardowns

  • Participants
  • Parent commits 247b401

Comments (0)

Files changed (9)

+1.8
+-------------------------
+
+- fix pytest-issue93 - use the refined pytest-2.2.1 runtestprotocol 
+  interface to perform eager teardowns for test items.
+
 1.7
 -------------------------
 
 
 setup(
     name="pytest-xdist",
-    version='1.7',
+    version='1.8.dev1',
     description='py.test xdist plugin for distributed testing and loop-on-failing modes',
     long_description=open('README.txt').read(),
     license='GPLv2 or later',
     packages = ['xdist'],
     entry_points = {'pytest11': ['xdist = xdist.plugin'],},
     zip_safe=False,
-    install_requires = ['execnet>=1.0.8', 'pytest>=2.2.0'],
+    install_requires = ['execnet>=1.0.8', 'pytest>=2.2.1.dev1'],
     classifiers=[
     'Development Status :: 5 - Production/Stable',
     'Intended Audience :: Developers',

File testing/test_dsession.py

         assert sched.node2collection[node1] == collection
         assert sched.node2collection[node2] == collection
         sched.init_distribute()
-        assert not sched.tests_finished()
+        assert sched.tests_finished()
         assert node1.sent == ['ALL']
         assert node2.sent == ['ALL']
         sched.remove_item(node1, collection[0])
-        assert not sched.tests_finished()
+        assert sched.tests_finished()
         sched.remove_item(node2, collection[0])
         assert sched.tests_finished()
 
         assert sched.collection_is_completed
         assert sched.node2collection[node1] == collection
         sched.init_distribute()
-        assert not sched.tests_finished()
+        assert sched.tests_finished()
         crashitem = sched.remove_node(node1)
         assert crashitem
         assert sched.tests_finished()
         assert sched.node2collection[node1] == collection
         assert sched.node2collection[node2] == collection
         sched.init_distribute()
-        assert not sched.tests_finished()
+        assert sched.tests_finished()
         assert len(node1.sent) == 1
         assert len(node2.sent) == 1
         x = sorted(node1.sent + node2.sent)
         sched.addnode_collection(node1, col)
         sched.addnode_collection(node2, col)
         sched.init_distribute()
+        #assert not sched.tests_finished()
         sent1 = node1.sent
         sent2 = node2.sent
         chunkitems = col[:sched.ITEM_CHUNKSIZE]

File testing/test_remote.py

         ids = ev.kwargs['ids']
         assert len(ids) == 1
         slave.sendcommand("runtests", ids=ids)
+        slave.sendcommand("shutdown")
         ev = slave.popevent("testreport") # setup
         ev = slave.popevent("testreport")
         assert ev.name == "testreport"
         assert rep.nodeid.endswith("::test_func")
         assert rep.passed
         assert rep.when == "call"
-        slave.sendcommand("shutdown")
         ev = slave.popevent("slavefinished")
         assert 'slaveoutput' in ev.kwargs
 
 
 [pytest]
 addopts = -rsfxX
+;; hello

File xdist/__init__.py

 #
-__version__ = '1.7'
+__version__ = '1.8.dev1'

File xdist/dsession.py

     def tests_finished(self):
         if not self.collection_is_completed:
             return False
-        for items in self.node2pending.values():
-            if items:
-                return False
         return True
 
     def addnode_collection(self, node, collection):
     def tests_finished(self):
         if not self.collection_is_completed or self.pending:
             return False
-        for items in self.node2pending.values():
-            if items:
-                return False
+        #for items in self.node2pending.values():
+        #    if items:
+        #        return False
         return True
 
     def addnode_collection(self, node, collection):
             pending.append(item)
             self.item2nodes.setdefault(item, []).append(node)
             node.send_runtest(item)
-        #self.log("items waiting for node: %d" %(len(self.pending)))
+        self.log("items waiting for node: %d" %(len(self.pending)))
         #self.log("item2pending still executing: %s" %(self.item2nodes,))
         #self.log("node2pending: %s" %(self.node2pending,))
 

File xdist/remote.py

 
     def pytest_runtestloop(self, session):
         self.log("entering main loop")
+        torun = []
         while 1:
             name, kwargs = self.channel.receive()
             self.log("received command %s(**%s)" % (name, kwargs))
             if name == "runtests":
                 ids = kwargs['ids']
                 for nodeid in ids:
-                    item = self._id2item[nodeid]
-                    self.config.hook.pytest_runtest_protocol(item=item)
+                    torun.append(self._id2item[nodeid])
             elif name == "runtests_all":
-                for item in session.items:
-                    self.config.hook.pytest_runtest_protocol(item=item)
-            elif name == "shutdown":
+                torun.extend(session.items)
+            self.log("items to run: %s" %(len(torun)))
+            while len(torun) >= 2:
+                item = torun.pop(0)
+                nextitem = torun[0]
+                self.config.hook.pytest_runtest_protocol(item=item,
+                    nextitem=nextitem)
+            if name == "shutdown":
+                while torun:
+                    self.config.hook.pytest_runtest_protocol(
+                        item=torun.pop(0), nextitem=None)
                 break
         return True
 
     config.option.numprocesses = None
     config.args = args
     return config
-    
+
 
 if __name__ == '__channelexec__':
     slaveinput,args,option_dict = channel.receive()

File xdist/slavemanage.py

             raise ValueError("arg %s not relative to an rsync root" % (arg,))
         l.append(splitcode.join(parts))
     return l
-    
+
 class SlaveController(object):
     ENDMARK = -1
 
         self.sendcommand("runtests_all",)
 
     def shutdown(self):
-        if not self._down and not self.channel.isclosed():
-            self.sendcommand("shutdown")
+        if not self._down:
+            try:
+                self.sendcommand("shutdown")
+            except IOError:
+                pass
 
     def sendcommand(self, name, **kwargs):
         """ send a named parametrized command to the other side. """