Skip to content

Instantly share code, notes, and snippets.

@npinto
Created July 14, 2011 18:00
Show Gist options
  • Save npinto/1082998 to your computer and use it in GitHub Desktop.
Save npinto/1082998 to your computer and use it in GitHub Desktop.
nose_multiproces_patch
diff -r 274adce935a2 nose/plugins/multiprocess.py
--- a/nose/plugins/multiprocess.py Thu Jul 14 11:01:35 2011 -0500
+++ b/nose/plugins/multiprocess.py Thu Jul 14 21:21:21 2011 -0400
@@ -33,9 +33,13 @@
Controlling distribution
^^^^^^^^^^^^^^^^^^^^^^^^
-There are two context-level variables that you can use to control this default
+There are three context-level variables that you can use to control this default
behavior.
+If a context is not safe for multiprocess execution (i.e. part of your test
+suite is not safe for concurrency), set ``_multiprocess_ = False`` in the
+context, and the plugin will execute tests bound to that context serially.
+
If a context's fixtures are re-entrant, set ``_multiprocess_can_split_ = True``
in the context, and the plugin will dispatch tests in suites bound to that
context as if the context had no fixtures. This means that the fixtures will
@@ -122,7 +126,7 @@
except ImportError:
import StringIO
-# this is a list of plugin classes that will be checked for and created inside
+# this is a list of plugin classes that will be checked for and created inside
# each worker process
_instantiate_plugins = None
@@ -130,6 +134,7 @@
Process = Queue = Pool = Event = Value = Array = None
+
class TimedOutException(Exception):
def __init__(self, value = "Timed Out"):
self.value = value
@@ -292,6 +297,12 @@
log.debug("Case is a Failure")
case(result) # run here to capture the failure
continue
+ # handle tests that are not safe for multiprocess execution
+ if hasattr(case, 'context'):
+ if not getattr(test.context, '_multiprocess_', True):
+ log.debug("Case is a not multiprocess safe")
+ case(result) # run here
+ continue
# handle shared fixtures
if isinstance(case, ContextSuite) and case.context is failure.Failure:
log.debug("Case is a Failure")
@@ -542,11 +553,6 @@
address = staticmethod(address)
def nextBatch(self, test):
- # allows tests or suites to mark themselves as not safe
- # for multiprocess execution
- if hasattr(test, 'context'):
- if not getattr(test.context, '_multiprocess_', True):
- return
if ((isinstance(test, ContextSuite)
and test.hasFixtures(self.checkCanSplit))
diff -r 274adce935a2 unit_tests/test_multiprocess.py
--- a/unit_tests/test_multiprocess.py Thu Jul 14 11:01:35 2011 -0500
+++ b/unit_tests/test_multiprocess.py Thu Jul 14 21:21:21 2011 -0400
@@ -31,20 +31,21 @@
def is_alive(self):
return False
-
+
def setup(mod):
multiprocess._import_mp()
if not multiprocess.Process:
raise SkipTest("multiprocessing not available")
mod.Process = multiprocess.Process
multiprocess.Process = ArgChecker
-
+
class T(unittest.TestCase):
__test__ = False
def runTest(self):
pass
+
def test_mp_process_args_pickleable():
# TODO(Kumar) this test needs to be more succint.
# If you start seeing it timeout then perhaps we need to skip it again.
@@ -59,4 +60,3 @@
loaderClass=TestLoader,
config=config)
runner.run(test)
-
diff -r 274adce935a2 unit_tests/test_multiprocess_runner.py
--- a/unit_tests/test_multiprocess_runner.py Thu Jul 14 11:01:35 2011 -0500
+++ b/unit_tests/test_multiprocess_runner.py Thu Jul 14 21:21:21 2011 -0400
@@ -14,7 +14,7 @@
pass
def test_b(self):
pass
-
+
class T:
def test_a(self):
pass
@@ -114,7 +114,23 @@
tests = list(r.nextBatch(l.loadTestsFromModule(mod_with_fixt2)))
print tests
self.assertEqual(len(tests), 3)
-
-
+
+ def test_multiprocess_unsafe(self):
+ mod_unsafe = imp.new_module('mod_unsafe')
+ sys.modules['mod_unsafe'] = mod_unsafe
+
+ class Test(T):
+ pass
+
+ mod_unsafe._multiprocess_ = False
+ mod_unsafe.Test = Test
+ Test.__module__ = 'mod_unsafe'
+
+ r = multiprocess.MultiProcessTestRunner()
+ l = TestLoader()
+ tests = list(r.nextBatch(l.loadTestsFromModule(mod_unsafe)))
+ print tests
+ self.assertEqual(len(tests), 2)
+
if __name__ == '__main__':
unittest.main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment