Commits

holger krekel committed eca7ce1

fix an indefinite hang which would wait for events although no events
are pending - this happened if items arrive very quickly while
the "reschedule-event" tried unconditionally avoiding a busy-loop
and not schedule new work.

  • Participants
  • Parent commits cf4e0e0
  • Tags 1.1

Comments (0)

Files changed (5)

+1.1
+-------------------------
+
+- fix an indefinite hang which would wait for events although no events
+  are pending - this happened if items arrive very quickly while 
+  the "reschedule-event" tried unconditionally avoiding a busy-loop
+  and not schedule new work. 
+
 1.0
 -------------------------
 
 
 setup(
     name="pytest-xdist",
-    version="1.0",
+    version="1.1",
     description='py.test figleaf coverage plugin',
     long_description=__doc__,
     license='GPLv2 or later',
     packages = ['xdist'],
     entry_points = {'pytest11': ['xdist = xdist.plugin'],},
     zip_safe=False,
-    install_requires = ['execnet>=1.0.3', 'py>=1.2.0'],
+    install_requires = ['execnet>=1.0.4', 'py>=1.2.0'],
     classifiers=[
     'Development Status :: 4 - Beta',
     'Intended Audience :: Developers',

testing/test_dsession.py

         assert name == "pytest_rescheduleitems"
         assert kwargs['items'] == [item]
 
+    
     def test_keyboardinterrupt(self, testdir):
         item = testdir.getitem("def test_func(): pass")
         session = DSession(item.config)
         loopstate = session._initloopstate([])
         session.queueevent("pytest_rescheduleitems", items=[item])
         session.loop_once(loopstate)
-        # check that RescheduleEvents are not immediately
-        # rescheduled if there are no nodes
+        # we need to do work because nothing is pending / we would not wake up
+        assert loopstate.dowork == True
+
+        session.node2pending[node].append(item)
+        session.queueevent("pytest_rescheduleitems", items=[item])
+        session.loop_once(loopstate)
+        # now we want to not directly trigger work again to avoid busy-wait
         assert loopstate.dowork == False 
+        
         session.queueevent(None)
         session.loop_once(loopstate)
         session.queueevent(None)
         session.loop_once(loopstate)
-        assert node.sent == [item]
+        assert node.sent == [item, item]
+        session.queueevent("pytest_runtest_logreport", report=run(item, node))
+        session.loop_once(loopstate)
         session.queueevent("pytest_runtest_logreport", report=run(item, node))
         session.loop_once(loopstate)
         assert loopstate.shuttingdown 

xdist/__init__.py

 #
-__version__ = "1.0"
+__version__ = "1.1"
 

xdist/dsession.py

 
     def pytest_rescheduleitems(self, items):
         self.colitems[:] = items + self.colitems
-        self.dowork = False # avoid busywait
+        for pending in self.dsession.node2pending.values():
+            if pending:
+                self.dowork = False # avoid busywait, nodes still have work
 
 class ExitFirstInterrupt(KeyboardInterrupt):
     pass