Created
July 14, 2011 18:00
-
-
Save npinto/1082998 to your computer and use it in GitHub Desktop.
nose_multiproces_patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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