Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
More multiprocessing & concurrent.futures disables when forkserver ca…
…nnot work
  • Loading branch information
gpshead committed Dec 2, 2024
commit adfd6c7463eca301efb34a7eb73a7074574ef7ff
27 changes: 21 additions & 6 deletions Lib/test/_test_multiprocessing.py
Original file line number Diff line number Diff line change
Expand Up @@ -1431,6 +1431,7 @@ def _acquire_event(lock, event):
event.set()
time.sleep(1.0)

@hashlib_helper.requires_hashdigest('sha256') # Manager RPC connection auth
def test_repr_lock(self):
if self.TYPE != 'processes':
self.skipTest('test not appropriate for {}'.format(self.TYPE))
Expand Down Expand Up @@ -1496,6 +1497,7 @@ def _acquire_release(lock, timeout, l=None, n=1):
for _ in range(n):
lock.release()

@hashlib_helper.requires_hashdigest('sha256') # Manager RPC connection auth
def test_repr_rlock(self):
if self.TYPE != 'processes':
self.skipTest('test not appropriate for {}'.format(self.TYPE))
Expand Down Expand Up @@ -3417,6 +3419,7 @@ def tearDown(self):
self.mgr.shutdown()
self.mgr.join()

@hashlib_helper.requires_hashdigest('sha256') # multiprocessing.connection
def test_queue_get(self):
queue = self.mgr.Queue()
if gc.isenabled():
Expand Down Expand Up @@ -3730,6 +3733,7 @@ def test_context(self):
if self.TYPE == 'processes':
self.assertRaises(OSError, l.accept)

@hashlib_helper.requires_hashdigest('sha256') # connection auth
def test_empty_authkey(self):
# bpo-43952: allow empty bytes as authkey
def handler(*args):
Expand Down Expand Up @@ -5782,9 +5786,11 @@ def test_get_all_start_methods(self):
self.assertIn(methods[0], {'forkserver', 'spawn'},
msg='3.14+ default must not be fork')
if methods[0] == 'spawn':
# Confirm that the current default selection logic prefers
# forkserver vs spawn when available.
self.assertNotIn('forkserver', methods)
if not hashlib_helper.in_openssl_fips_mode():
# Confirm that the current default selection logic prefers
# forkserver vs spawn when available.
# OpenSSL FIPS mode can disable this by blocking sha256.
self.assertNotIn('forkserver', methods)

def test_preload_resources(self):
if multiprocessing.get_start_method() != 'forkserver':
Expand All @@ -5805,7 +5811,11 @@ def test_mixed_startmethod(self):
# Fork-based locks cannot be used with spawned process
for process_method in ["spawn", "forkserver"]:
queue = multiprocessing.get_context("fork").Queue()
process_ctx = multiprocessing.get_context(process_method)
try:
process_ctx = multiprocessing.get_context(process_method)
except ValueError as err:
self.skipTest(err)
continue
p = process_ctx.Process(target=close_queue, args=(queue,))
err_msg = "A SemLock created in a fork"
with self.assertRaisesRegex(RuntimeError, err_msg):
Expand All @@ -5814,8 +5824,13 @@ def test_mixed_startmethod(self):
# non-fork-based locks can be used with all other start methods
for queue_method in ["spawn", "forkserver"]:
for process_method in multiprocessing.get_all_start_methods():
queue = multiprocessing.get_context(queue_method).Queue()
process_ctx = multiprocessing.get_context(process_method)
try:
queue_ctx = multiprocessing.get_context(queue_method)
process_ctx = multiprocessing.get_context(process_method)
except ValueError as err:
self.skipTest(err)
continue
queue = queue_ctx.Queue()
p = process_ctx.Process(target=close_queue, args=(queue,))
p.start()
p.join()
Expand Down
7 changes: 7 additions & 0 deletions Lib/test/support/hashlib_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@
_hashlib = None


def in_openssl_fips_mode() -> bool:
"""Is OpenSSL based _hashlib is present & operating in FIPS mode?"""
if _hashlib and _hashlib.get_fips_mode() != 0:
return True
return False


def requires_hashdigest(digestname, openssl=None, usedforsecurity=True):
"""Decorator raising SkipTest if a hashing algorithm is not available

Expand Down
5 changes: 5 additions & 0 deletions Lib/test/test_concurrent_futures/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,11 @@ def test_spawn(self):

@support.skip_if_sanitizer("TSAN doesn't support threads after fork", thread=True)
def test_forkserver(self):
import multiprocessing
try:
multiprocessing.get_context("forkserver")
except ValueError as err:
self.skipTest(str(err))
self._test(ProcessPoolForkserverFailingInitializerTest)


Expand Down
5 changes: 4 additions & 1 deletion Lib/test/test_concurrent_futures/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,10 @@ def get_context(self):
self.skipTest("require unix system")
if support.check_sanitizer(thread=True):
self.skipTest("TSAN doesn't support threads after fork")
return super().get_context()
try:
return super().get_context()
except ValueError as err:
self.skipTest(str(err))


def create_executor_tests(remote_globals, mixin, bases=(BaseTestCase,),
Expand Down