summaryrefslogtreecommitdiff
path: root/django/test
diff options
context:
space:
mode:
authorJacob Walls <jacobtylerwalls@gmail.com>2025-11-26 10:00:38 -0500
committerJacob Walls <jacobtylerwalls@gmail.com>2025-12-03 16:04:22 -0500
commitbd4a562a8849147d4aa4bd42f7fdb1b51f89bb84 (patch)
treec68ca990737cbe8c17b4954efc62414ceb7fc10b /django/test
parent93540b34d4ef46f68df2c8bfe90447d0f649a852 (diff)
Closed pool when parallel test runner encounters unpicklable exceptions.
Diffstat (limited to 'django/test')
-rw-r--r--django/test/runner.py55
1 files changed, 27 insertions, 28 deletions
diff --git a/django/test/runner.py b/django/test/runner.py
index ecae164d7f..5cd72119f5 100644
--- a/django/test/runner.py
+++ b/django/test/runner.py
@@ -567,7 +567,14 @@ class ParallelTestSuite(unittest.TestSuite):
"""
self.initialize_suite()
counter = multiprocessing.Value(ctypes.c_int, 0)
- pool = multiprocessing.Pool(
+ args = [
+ (self.runner_class, index, subsuite, self.failfast, self.buffer)
+ for index, subsuite in enumerate(self.subsuites)
+ ]
+ # Don't buffer in the main process to avoid error propagation issues.
+ result.buffer = False
+
+ with multiprocessing.Pool(
processes=self.processes,
initializer=functools.partial(_safe_init_worker, self.init_worker.__func__),
initargs=[
@@ -579,38 +586,30 @@ class ParallelTestSuite(unittest.TestSuite):
self.debug_mode,
self.used_aliases,
],
- )
- args = [
- (self.runner_class, index, subsuite, self.failfast, self.buffer)
- for index, subsuite in enumerate(self.subsuites)
- ]
- # Don't buffer in the main process to avoid error propagation issues.
- result.buffer = False
+ ) as pool:
+ test_results = pool.imap_unordered(self.run_subsuite.__func__, args)
- test_results = pool.imap_unordered(self.run_subsuite.__func__, args)
+ while True:
+ if result.shouldStop:
+ pool.terminate()
+ break
- while True:
- if result.shouldStop:
- pool.terminate()
- break
-
- try:
- subsuite_index, events = test_results.next(timeout=0.1)
- except multiprocessing.TimeoutError as err:
- if counter.value < 0:
- err.add_note("ERROR: _init_worker failed, see prior traceback")
+ try:
+ subsuite_index, events = test_results.next(timeout=0.1)
+ except multiprocessing.TimeoutError as err:
+ if counter.value < 0:
+ err.add_note("ERROR: _init_worker failed, see prior traceback")
+ raise
+ continue
+ except StopIteration:
pool.close()
- raise
- continue
- except StopIteration:
- pool.close()
- break
+ break
- tests = list(self.subsuites[subsuite_index])
- for event in events:
- self.handle_event(result, tests, event)
+ tests = list(self.subsuites[subsuite_index])
+ for event in events:
+ self.handle_event(result, tests, event)
- pool.join()
+ pool.join()
return result