Refs #31169 -- Prevented infinite loop in parallel tests with custom test runner when using spawn.

Regression in 3b3f38b3b0.

Co-Authored-By: Mariusz Felisiak <felisiak.mariusz@gmail.com>
This commit is contained in:
David Smith 2022-03-16 20:47:58 +00:00 committed by Mariusz Felisiak
parent 4f92cf87b0
commit ba298a32b3
2 changed files with 46 additions and 2 deletions

View File

@ -492,6 +492,7 @@ class ParallelTestSuite(unittest.TestSuite):
Even with tblib, errors may still occur for dynamically created
exception classes which cannot be unpickled.
"""
self.initialize_suite()
counter = multiprocessing.Value(ctypes.c_int, 0)
pool = multiprocessing.Pool(
processes=self.processes,
@ -962,8 +963,6 @@ class DiscoverRunner:
def run_suite(self, suite, **kwargs):
kwargs = self.get_test_runner_kwargs()
runner = self.test_runner(**kwargs)
if hasattr(suite, "initialize_suite"):
suite.initialize_suite()
try:
return runner.run(suite)
finally:

View File

@ -639,6 +639,51 @@ class CustomTestRunnerOptionsCmdlineTests(AdminScriptTestCase):
self.assertNoOutput(out)
class NoInitializeSuiteTestRunnerTests(SimpleTestCase):
@mock.patch.object(multiprocessing, "get_start_method", return_value="spawn")
@mock.patch(
"django.test.runner.ParallelTestSuite.initialize_suite",
side_effect=Exception("initialize_suite() is called."),
)
def test_no_initialize_suite_test_runner(self, *mocked_objects):
"""
The test suite's initialize_suite() method must always be called when
using spawn. It cannot rely on a test runner implementation.
"""
class NoInitializeSuiteTestRunner(DiscoverRunner):
def setup_test_environment(self, **kwargs):
return
def setup_databases(self, **kwargs):
return
def run_checks(self, databases):
return
def teardown_databases(self, old_config, **kwargs):
return
def teardown_test_environment(self, **kwargs):
return
def run_suite(self, suite, **kwargs):
kwargs = self.get_test_runner_kwargs()
runner = self.test_runner(**kwargs)
return runner.run(suite)
with self.assertRaisesMessage(Exception, "initialize_suite() is called."):
runner = NoInitializeSuiteTestRunner(
verbosity=0, interactive=False, parallel=2
)
runner.run_tests(
[
"test_runner_apps.sample.tests_sample.TestDjangoTestCase",
"test_runner_apps.simple.tests",
]
)
class Ticket17477RegressionTests(AdminScriptTestCase):
def setUp(self):
super().setUp()