[Python-checkins] bpo-38377: Add support.skip_if_broken_multiprocessing_synchronize() (GH-20944) (GH-20962) (GH-20966)

Victor Stinner webhook-mailer at python.org
Thu Jun 18 12:56:54 EDT 2020


https://github.com/python/cpython/commit/e8056180a13b6755e4e3e5505b7bf03f79da29fb
commit: e8056180a13b6755e4e3e5505b7bf03f79da29fb
branch: 3.8
author: Victor Stinner <vstinner at python.org>
committer: GitHub <noreply at github.com>
date: 2020-06-18T18:56:43+02:00
summary:

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 ddbeb2f3e02a510c5784ffd74c5e09e8c70b5881)
(cherry picked from commit b1e736113484c99acb57e4acb417b91a9e58e7ff)

files:
A Misc/NEWS.d/next/Tests/2020-06-17-18-00-21.bpo-38377.jfg4TH.rst
M Lib/test/_test_multiprocessing.py
M Lib/test/support/__init__.py
M Lib/test/test_asyncio/test_events.py
M Lib/test/test_concurrent_futures.py
M Lib/test/test_logging.py
M Lib/test/test_multiprocessing_main_handling.py
M Lib/test/test_venv.py

diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py
index d5cccac16f451..87f5044148fbe 100644
--- a/Lib/test/_test_multiprocessing.py
+++ b/Lib/test/_test_multiprocessing.py
@@ -31,7 +31,7 @@
 # Skip tests if _multiprocessing wasn't built.
 _multiprocessing = test.support.import_module('_multiprocessing')
 # Skip tests if sem_open implementation is broken.
-test.support.import_module('multiprocessing.synchronize')
+support.skip_if_broken_multiprocessing_synchronize()
 import threading
 
 import multiprocessing.connection
diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py
index 0906e7adbae9b..b75dbd214fe36 100644
--- a/Lib/test/support/__init__.py
+++ b/Lib/test/support/__init__.py
@@ -3377,3 +3377,26 @@ def save_restore_warnings_filters():
         yield
     finally:
         warnings.filters[:] = old_filters
+
+
+def skip_if_broken_multiprocessing_synchronize():
+    """
+    Skip tests if the multiprocessing.synchronize module is missing, if there
+    is no available semaphore implementation, or if creating a lock raises an
+    OSError.
+    """
+
+    # Skip tests if the _multiprocessing extension is missing.
+    import_module('_multiprocessing')
+
+    # Skip tests if there is no available semaphore implementation:
+    # multiprocessing.synchronize requires _multiprocessing.SemLock.
+    synchronize = import_module('multiprocessing.synchronize')
+
+    try:
+        # bpo-38377: On Linux, creating a semaphore is the current user
+        # does not have the permission to create a file in /dev/shm.
+        # Create a semaphore to check permissions.
+        synchronize.Lock(ctx=None)
+    except OSError as exc:
+        raise unittest.SkipTest(f"broken multiprocessing SemLock: {exc!r}")
diff --git a/Lib/test/test_asyncio/test_events.py b/Lib/test/test_asyncio/test_events.py
index 37f1cb7e53a8d..85838f17678af 100644
--- a/Lib/test/test_asyncio/test_events.py
+++ b/Lib/test/test_asyncio/test_events.py
@@ -2644,10 +2644,10 @@ def tearDown(self):
     if sys.platform != 'win32':
 
         def test_get_event_loop_new_process(self):
-            # Issue bpo-32126: The multiprocessing module used by
+            # bpo-32126: The multiprocessing module used by
             # ProcessPoolExecutor is not functional when the
             # multiprocessing.synchronize module cannot be imported.
-            support.import_module('multiprocessing.synchronize')
+            support.skip_if_broken_multiprocessing_synchronize()
 
             async def main():
                 pool = concurrent.futures.ProcessPoolExecutor()
diff --git a/Lib/test/test_concurrent_futures.py b/Lib/test/test_concurrent_futures.py
index ac722981659d3..a5a746eb3898f 100644
--- a/Lib/test/test_concurrent_futures.py
+++ b/Lib/test/test_concurrent_futures.py
@@ -3,7 +3,7 @@
 # Skip tests if _multiprocessing wasn't built.
 test.support.import_module('_multiprocessing')
 # Skip tests if sem_open implementation is broken.
-test.support.import_module('multiprocessing.synchronize')
+test.support.skip_if_broken_multiprocessing_synchronize()
 
 from test.support.script_helper import assert_python_ok
 
diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py
index 90bf2a4d3ac06..09b273bf1fb2d 100644
--- a/Lib/test/test_logging.py
+++ b/Lib/test/test_logging.py
@@ -3621,9 +3621,9 @@ def test_handle_called_with_queue_queue(self, mock_handle):
 
         @patch.object(logging.handlers.QueueListener, 'handle')
         def test_handle_called_with_mp_queue(self, mock_handle):
-            # Issue 28668: The multiprocessing (mp) module is not functional
+            # bpo-28668: The multiprocessing (mp) module is not functional
             # when the mp.synchronize module cannot be imported.
-            support.import_module('multiprocessing.synchronize')
+            support.skip_if_broken_multiprocessing_synchronize()
             for i in range(self.repeat):
                 log_queue = multiprocessing.Queue()
                 self.setup_and_log(log_queue, '%s_%s' % (self.id(), i))
@@ -3647,9 +3647,9 @@ def test_no_messages_in_queue_after_stop(self):
             indicates that messages were not registered on the queue until
             _after_ the QueueListener stopped.
             """
-            # Issue 28668: The multiprocessing (mp) module is not functional
+            # bpo-28668: The multiprocessing (mp) module is not functional
             # when the mp.synchronize module cannot be imported.
-            support.import_module('multiprocessing.synchronize')
+            support.skip_if_broken_multiprocessing_synchronize()
             for i in range(self.repeat):
                 queue = multiprocessing.Queue()
                 self.setup_and_log(queue, '%s_%s' %(self.id(), i))
diff --git a/Lib/test/test_multiprocessing_main_handling.py b/Lib/test/test_multiprocessing_main_handling.py
index b6abfcc7e283d..be1ff10e03a55 100644
--- a/Lib/test/test_multiprocessing_main_handling.py
+++ b/Lib/test/test_multiprocessing_main_handling.py
@@ -23,7 +23,7 @@
 AVAILABLE_START_METHODS = set(multiprocessing.get_all_start_methods())
 
 # Issue #22332: Skip tests if sem_open implementation is broken.
-support.import_module('multiprocessing.synchronize')
+support.skip_if_broken_multiprocessing_synchronize()
 
 verbose = support.verbose
 
diff --git a/Lib/test/test_venv.py b/Lib/test/test_venv.py
index 7e05138a80dc8..28743f03ae203 100644
--- a/Lib/test/test_venv.py
+++ b/Lib/test/test_venv.py
@@ -16,7 +16,8 @@
 import tempfile
 from test.support import (captured_stdout, captured_stderr, requires_zlib,
                           can_symlink, EnvironmentVarGuard, rmtree,
-                          import_module)
+                          import_module,
+                          skip_if_broken_multiprocessing_synchronize)
 import threading
 import unittest
 import venv
@@ -324,10 +325,11 @@ def test_multiprocessing(self):
         """
         Test that the multiprocessing is able to spawn.
         """
-        # Issue bpo-36342: Instanciation of a Pool object imports the
+        # bpo-36342: Instantiation of a Pool object imports the
         # multiprocessing.synchronize module. Skip the test if this module
         # cannot be imported.
-        import_module('multiprocessing.synchronize')
+        skip_if_broken_multiprocessing_synchronize()
+
         rmtree(self.env_dir)
         self.run_with_capture(venv.create, self.env_dir)
         envpy = os.path.join(os.path.realpath(self.env_dir),
diff --git a/Misc/NEWS.d/next/Tests/2020-06-17-18-00-21.bpo-38377.jfg4TH.rst b/Misc/NEWS.d/next/Tests/2020-06-17-18-00-21.bpo-38377.jfg4TH.rst
new file mode 100644
index 0000000000000..11a30761d36c9
--- /dev/null
+++ b/Misc/NEWS.d/next/Tests/2020-06-17-18-00-21.bpo-38377.jfg4TH.rst
@@ -0,0 +1,4 @@
+On Linux, skip tests using multiprocessing if the current user cannot create
+a file in ``/dev/shm/`` directory. Add the
+:func:`~test.support.skip_if_broken_multiprocessing_synchronize` function to
+the :mod:`test.support` module.



More information about the Python-checkins mailing list