Skip to content

Commit e805618

Browse files
authored
bpo-38377: Add support.skip_if_broken_multiprocessing_synchronize() (GH-20944) (GH-20962) (GH-20966)
On Linux, skip tests using multiprocessing if the current user cannot create a file in /dev/shm/ directory. Add the skip_if_broken_multiprocessing_synchronize() function to the test.support module. (cherry picked from commit ddbeb2f) (cherry picked from commit b1e7361)
1 parent 3d974b2 commit e805618

File tree

8 files changed

+41
-12
lines changed

8 files changed

+41
-12
lines changed

Lib/test/_test_multiprocessing.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
# Skip tests if _multiprocessing wasn't built.
3232
_multiprocessing = test.support.import_module('_multiprocessing')
3333
# Skip tests if sem_open implementation is broken.
34-
test.support.import_module('multiprocessing.synchronize')
34+
support.skip_if_broken_multiprocessing_synchronize()
3535
import threading
3636

3737
import multiprocessing.connection

Lib/test/support/__init__.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3377,3 +3377,26 @@ def save_restore_warnings_filters():
33773377
yield
33783378
finally:
33793379
warnings.filters[:] = old_filters
3380+
3381+
3382+
def skip_if_broken_multiprocessing_synchronize():
3383+
"""
3384+
Skip tests if the multiprocessing.synchronize module is missing, if there
3385+
is no available semaphore implementation, or if creating a lock raises an
3386+
OSError.
3387+
"""
3388+
3389+
# Skip tests if the _multiprocessing extension is missing.
3390+
import_module('_multiprocessing')
3391+
3392+
# Skip tests if there is no available semaphore implementation:
3393+
# multiprocessing.synchronize requires _multiprocessing.SemLock.
3394+
synchronize = import_module('multiprocessing.synchronize')
3395+
3396+
try:
3397+
# bpo-38377: On Linux, creating a semaphore is the current user
3398+
# does not have the permission to create a file in /dev/shm.
3399+
# Create a semaphore to check permissions.
3400+
synchronize.Lock(ctx=None)
3401+
except OSError as exc:
3402+
raise unittest.SkipTest(f"broken multiprocessing SemLock: {exc!r}")

Lib/test/test_asyncio/test_events.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2644,10 +2644,10 @@ def tearDown(self):
26442644
if sys.platform != 'win32':
26452645

26462646
def test_get_event_loop_new_process(self):
2647-
# Issue bpo-32126: The multiprocessing module used by
2647+
# bpo-32126: The multiprocessing module used by
26482648
# ProcessPoolExecutor is not functional when the
26492649
# multiprocessing.synchronize module cannot be imported.
2650-
support.import_module('multiprocessing.synchronize')
2650+
support.skip_if_broken_multiprocessing_synchronize()
26512651

26522652
async def main():
26532653
pool = concurrent.futures.ProcessPoolExecutor()

Lib/test/test_concurrent_futures.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# Skip tests if _multiprocessing wasn't built.
44
test.support.import_module('_multiprocessing')
55
# Skip tests if sem_open implementation is broken.
6-
test.support.import_module('multiprocessing.synchronize')
6+
test.support.skip_if_broken_multiprocessing_synchronize()
77

88
from test.support.script_helper import assert_python_ok
99

Lib/test/test_logging.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3621,9 +3621,9 @@ def test_handle_called_with_queue_queue(self, mock_handle):
36213621

36223622
@patch.object(logging.handlers.QueueListener, 'handle')
36233623
def test_handle_called_with_mp_queue(self, mock_handle):
3624-
# Issue 28668: The multiprocessing (mp) module is not functional
3624+
# bpo-28668: The multiprocessing (mp) module is not functional
36253625
# when the mp.synchronize module cannot be imported.
3626-
support.import_module('multiprocessing.synchronize')
3626+
support.skip_if_broken_multiprocessing_synchronize()
36273627
for i in range(self.repeat):
36283628
log_queue = multiprocessing.Queue()
36293629
self.setup_and_log(log_queue, '%s_%s' % (self.id(), i))
@@ -3647,9 +3647,9 @@ def test_no_messages_in_queue_after_stop(self):
36473647
indicates that messages were not registered on the queue until
36483648
_after_ the QueueListener stopped.
36493649
"""
3650-
# Issue 28668: The multiprocessing (mp) module is not functional
3650+
# bpo-28668: The multiprocessing (mp) module is not functional
36513651
# when the mp.synchronize module cannot be imported.
3652-
support.import_module('multiprocessing.synchronize')
3652+
support.skip_if_broken_multiprocessing_synchronize()
36533653
for i in range(self.repeat):
36543654
queue = multiprocessing.Queue()
36553655
self.setup_and_log(queue, '%s_%s' %(self.id(), i))

Lib/test/test_multiprocessing_main_handling.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
AVAILABLE_START_METHODS = set(multiprocessing.get_all_start_methods())
2424

2525
# Issue #22332: Skip tests if sem_open implementation is broken.
26-
support.import_module('multiprocessing.synchronize')
26+
support.skip_if_broken_multiprocessing_synchronize()
2727

2828
verbose = support.verbose
2929

Lib/test/test_venv.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
import tempfile
1717
from test.support import (captured_stdout, captured_stderr, requires_zlib,
1818
can_symlink, EnvironmentVarGuard, rmtree,
19-
import_module)
19+
import_module,
20+
skip_if_broken_multiprocessing_synchronize)
2021
import threading
2122
import unittest
2223
import venv
@@ -324,10 +325,11 @@ def test_multiprocessing(self):
324325
"""
325326
Test that the multiprocessing is able to spawn.
326327
"""
327-
# Issue bpo-36342: Instanciation of a Pool object imports the
328+
# bpo-36342: Instantiation of a Pool object imports the
328329
# multiprocessing.synchronize module. Skip the test if this module
329330
# cannot be imported.
330-
import_module('multiprocessing.synchronize')
331+
skip_if_broken_multiprocessing_synchronize()
332+
331333
rmtree(self.env_dir)
332334
self.run_with_capture(venv.create, self.env_dir)
333335
envpy = os.path.join(os.path.realpath(self.env_dir),
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
On Linux, skip tests using multiprocessing if the current user cannot create
2+
a file in ``/dev/shm/`` directory. Add the
3+
:func:`~test.support.skip_if_broken_multiprocessing_synchronize` function to
4+
the :mod:`test.support` module.

0 commit comments

Comments
 (0)