diff options
| author | Chris Jerdonek <chris.jerdonek@gmail.com> | 2016-08-11 03:47:12 -0700 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2016-08-26 14:24:27 -0400 |
| commit | 42dcceba614081966dfb5f236ae1b6fe78f31683 (patch) | |
| tree | e928f493f89befd48da83178fa3b1cf6ad86d209 /django/test | |
| parent | a02b5848ae6025ad3ef12cf6646ffd3e82a66067 (diff) | |
Fixed #26942 -- Added support for subtests during parallel testing.
Diffstat (limited to 'django/test')
| -rw-r--r-- | django/test/runner.py | 39 |
1 files changed, 35 insertions, 4 deletions
diff --git a/django/test/runner.py b/django/test/runner.py index 02a4c826ac..0610d303f8 100644 --- a/django/test/runner.py +++ b/django/test/runner.py @@ -77,6 +77,9 @@ class RemoteTestResult(object): """ def __init__(self): + if tblib is not None: + tblib.pickling_support.install() + self.events = [] self.failfast = False self.shouldStop = False @@ -86,6 +89,22 @@ class RemoteTestResult(object): def test_index(self): return self.testsRun - 1 + def _print_unpicklable_subtest(self, test, subtest, pickle_exc): + print(""" +Subtest failed: + + test: {} + subtest: {} + +Unfortunately, the subtest that failed cannot be pickled, so the parallel +test runner cannot handle it cleanly. Here is the pickling error: + +> {} + +You should re-run this test with --parallel=1 to reproduce the failure +with a cleaner failure message. +""".format(test, subtest, pickle_exc)) + def check_picklable(self, test, err): # Ensure that sys.exc_info() tuples are picklable. This displays a # clear multiprocessing.pool.RemoteTraceback generated in the child @@ -133,6 +152,13 @@ failure and get a correct traceback. """.format(test, original_exc_txt, pickle_exc_txt)) raise + def check_subtest_picklable(self, test, subtest): + try: + pickle.dumps(subtest) + except Exception as exc: + self._print_unpicklable_subtest(test, subtest, exc) + raise + def stop_if_failfast(self): if self.failfast: self.stop() @@ -164,7 +190,15 @@ failure and get a correct traceback. self.stop_if_failfast() def addSubTest(self, test, subtest, err): - raise NotImplementedError("subtests aren't supported at this time") + # Follow Python 3.5's implementation of unittest.TestResult.addSubTest() + # by not doing anything when a subtest is successful. + if err is not None: + # Call check_picklable() before check_subtest_picklable() since + # check_picklable() performs the tblib check. + self.check_picklable(test, err) + self.check_subtest_picklable(test, subtest) + self.events.append(('addSubTest', self.test_index, subtest, err)) + self.stop_if_failfast() def addSuccess(self, test): self.events.append(('addSuccess', self.test_index)) @@ -307,9 +341,6 @@ class ParallelTestSuite(unittest.TestSuite): Even with tblib, errors may still occur for dynamically created exception classes such Model.DoesNotExist which cannot be unpickled. """ - if tblib is not None: - tblib.pickling_support.install() - counter = multiprocessing.Value(ctypes.c_int, 0) pool = multiprocessing.Pool( processes=self.processes, |
