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:
parent
4f92cf87b0
commit
ba298a32b3
|
@ -492,6 +492,7 @@ class ParallelTestSuite(unittest.TestSuite):
|
||||||
Even with tblib, errors may still occur for dynamically created
|
Even with tblib, errors may still occur for dynamically created
|
||||||
exception classes which cannot be unpickled.
|
exception classes which cannot be unpickled.
|
||||||
"""
|
"""
|
||||||
|
self.initialize_suite()
|
||||||
counter = multiprocessing.Value(ctypes.c_int, 0)
|
counter = multiprocessing.Value(ctypes.c_int, 0)
|
||||||
pool = multiprocessing.Pool(
|
pool = multiprocessing.Pool(
|
||||||
processes=self.processes,
|
processes=self.processes,
|
||||||
|
@ -962,8 +963,6 @@ class DiscoverRunner:
|
||||||
def run_suite(self, suite, **kwargs):
|
def run_suite(self, suite, **kwargs):
|
||||||
kwargs = self.get_test_runner_kwargs()
|
kwargs = self.get_test_runner_kwargs()
|
||||||
runner = self.test_runner(**kwargs)
|
runner = self.test_runner(**kwargs)
|
||||||
if hasattr(suite, "initialize_suite"):
|
|
||||||
suite.initialize_suite()
|
|
||||||
try:
|
try:
|
||||||
return runner.run(suite)
|
return runner.run(suite)
|
||||||
finally:
|
finally:
|
||||||
|
|
|
@ -639,6 +639,51 @@ class CustomTestRunnerOptionsCmdlineTests(AdminScriptTestCase):
|
||||||
self.assertNoOutput(out)
|
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):
|
class Ticket17477RegressionTests(AdminScriptTestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super().setUp()
|
super().setUp()
|
||||||
|
|
Loading…
Reference in New Issue