summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorxdegaye <xdegaye@gmail.com>2017-11-24 16:35:55 (GMT)
committerGitHub <noreply@github.com>2017-11-24 16:35:55 (GMT)
commit0f86cd38f4a38f25a4aed3759a654a4b7fa49031 (patch)
treedbf1b69d6ba27e7ff77221cd97ebae60ee962a61
parent19fb134185ce155bc53f517116fca73093ba55e9 (diff)
downloadcpython-0f86cd38f4a38f25a4aed3759a654a4b7fa49031.zip
cpython-0f86cd38f4a38f25a4aed3759a654a4b7fa49031.tar.gz
cpython-0f86cd38f4a38f25a4aed3759a654a4b7fa49031.tar.bz2
bpo-28684: asyncio tests handle PermissionError raised on binding unix sockets (GH-4503)
The test.support.skip_unless_bind_unix_socket() decorator is used to skip asyncio tests that fail because the platform lacks a functional bind() function for unix domain sockets (as it is the case for non root users on the recent Android versions that run now SELinux in enforcing mode).
-rw-r--r--Lib/test/support/__init__.py23
-rw-r--r--Lib/test/test_asyncio/test_events.py15
-rw-r--r--Lib/test/test_asyncio/test_streams.py9
-rw-r--r--Lib/test/test_asyncio/test_unix_events.py4
-rw-r--r--Misc/NEWS.d/next/Library/2017-11-22-12-54-46.bpo-28684.NLiDKZ.rst5
5 files changed, 45 insertions, 11 deletions
diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py
index b7cbdc6..e864896 100644
--- a/Lib/test/support/__init__.py
+++ b/Lib/test/support/__init__.py
@@ -88,6 +88,7 @@ __all__ = [
"requires_IEEE_754", "skip_unless_xattr", "requires_zlib",
"anticipate_failure", "load_package_tests", "detect_api_mismatch",
"check__all__", "requires_android_level", "requires_multiprocessing_queue",
+ "skip_unless_bind_unix_socket",
# sys
"is_jython", "is_android", "check_impl_detail", "unix_shell",
"setswitchinterval",
@@ -2432,6 +2433,28 @@ def skip_unless_xattr(test):
msg = "no non-broken extended attribute support"
return test if ok else unittest.skip(msg)(test)
+_bind_nix_socket_error = None
+def skip_unless_bind_unix_socket(test):
+ """Decorator for tests requiring a functional bind() for unix sockets."""
+ if not hasattr(socket, 'AF_UNIX'):
+ return unittest.skip('No UNIX Sockets')(test)
+ global _bind_nix_socket_error
+ if _bind_nix_socket_error is None:
+ path = TESTFN + "can_bind_unix_socket"
+ with socket.socket(socket.AF_UNIX) as sock:
+ try:
+ sock.bind(path)
+ _bind_nix_socket_error = False
+ except OSError as e:
+ _bind_nix_socket_error = e
+ finally:
+ unlink(path)
+ if _bind_nix_socket_error:
+ msg = 'Requires a functional unix bind(): %s' % _bind_nix_socket_error
+ return unittest.skip(msg)(test)
+ else:
+ return test
+
def fs_is_case_insensitive(directory):
"""Detects if the file system for the specified directory is case-insensitive."""
diff --git a/Lib/test/test_asyncio/test_events.py b/Lib/test/test_asyncio/test_events.py
index 1a8bc13..78b30b9 100644
--- a/Lib/test/test_asyncio/test_events.py
+++ b/Lib/test/test_asyncio/test_events.py
@@ -22,6 +22,7 @@ import errno
import unittest
from unittest import mock
import weakref
+from test import support
if sys.platform != 'win32':
import tty
@@ -470,7 +471,7 @@ class EventLoopTestsMixin:
sock = socket.socket()
self._basetest_sock_recv_into(httpd, sock)
- @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets')
+ @support.skip_unless_bind_unix_socket
def test_unix_sock_client_ops(self):
with test_utils.run_test_unix_server() as httpd:
sock = socket.socket(socket.AF_UNIX)
@@ -606,7 +607,7 @@ class EventLoopTestsMixin:
lambda: MyProto(loop=self.loop), *httpd.address)
self._basetest_create_connection(conn_fut)
- @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets')
+ @support.skip_unless_bind_unix_socket
def test_create_unix_connection(self):
# Issue #20682: On Mac OS X Tiger, getsockname() returns a
# zero-length address for UNIX socket.
@@ -736,8 +737,8 @@ class EventLoopTestsMixin:
self._test_create_ssl_connection(httpd, create_connection,
peername=httpd.address)
+ @support.skip_unless_bind_unix_socket
@unittest.skipIf(ssl is None, 'No ssl module')
- @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets')
def test_create_ssl_unix_connection(self):
# Issue #20682: On Mac OS X Tiger, getsockname() returns a
# zero-length address for UNIX socket.
@@ -961,7 +962,7 @@ class EventLoopTestsMixin:
return server, path
- @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets')
+ @support.skip_unless_bind_unix_socket
def test_create_unix_server(self):
proto = MyProto(loop=self.loop)
server, path = self._make_unix_server(lambda: proto)
@@ -1053,8 +1054,8 @@ class EventLoopTestsMixin:
# stop serving
server.close()
+ @support.skip_unless_bind_unix_socket
@unittest.skipIf(ssl is None, 'No ssl module')
- @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets')
def test_create_unix_server_ssl(self):
proto = MyProto(loop=self.loop)
server, path = self._make_ssl_unix_server(
@@ -1113,8 +1114,8 @@ class EventLoopTestsMixin:
self.assertIsNone(proto.transport)
server.close()
+ @support.skip_unless_bind_unix_socket
@unittest.skipIf(ssl is None, 'No ssl module')
- @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets')
def test_create_unix_server_ssl_verify_failed(self):
proto = MyProto(loop=self.loop)
server, path = self._make_ssl_unix_server(
@@ -1171,8 +1172,8 @@ class EventLoopTestsMixin:
proto.transport.close()
server.close()
+ @support.skip_unless_bind_unix_socket
@unittest.skipIf(ssl is None, 'No ssl module')
- @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets')
def test_create_unix_server_ssl_verified(self):
proto = MyProto(loop=self.loop)
server, path = self._make_ssl_unix_server(
diff --git a/Lib/test/test_asyncio/test_streams.py b/Lib/test/test_asyncio/test_streams.py
index 6d16d20..a1e5bd7 100644
--- a/Lib/test/test_asyncio/test_streams.py
+++ b/Lib/test/test_asyncio/test_streams.py
@@ -9,6 +9,7 @@ import sys
import threading
import unittest
from unittest import mock
+from test import support
try:
import ssl
except ImportError:
@@ -57,7 +58,7 @@ class StreamReaderTests(test_utils.TestCase):
loop=self.loop)
self._basetest_open_connection(conn_fut)
- @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets')
+ @support.skip_unless_bind_unix_socket
def test_open_unix_connection(self):
with test_utils.run_test_unix_server() as httpd:
conn_fut = asyncio.open_unix_connection(httpd.address,
@@ -86,8 +87,8 @@ class StreamReaderTests(test_utils.TestCase):
self._basetest_open_connection_no_loop_ssl(conn_fut)
+ @support.skip_unless_bind_unix_socket
@unittest.skipIf(ssl is None, 'No ssl module')
- @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets')
def test_open_unix_connection_no_loop_ssl(self):
with test_utils.run_test_unix_server(use_ssl=True) as httpd:
conn_fut = asyncio.open_unix_connection(
@@ -113,7 +114,7 @@ class StreamReaderTests(test_utils.TestCase):
loop=self.loop)
self._basetest_open_connection_error(conn_fut)
- @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets')
+ @support.skip_unless_bind_unix_socket
def test_open_unix_connection_error(self):
with test_utils.run_test_unix_server() as httpd:
conn_fut = asyncio.open_unix_connection(httpd.address,
@@ -634,7 +635,7 @@ class StreamReaderTests(test_utils.TestCase):
server.stop()
self.assertEqual(msg, b"hello world!\n")
- @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets')
+ @support.skip_unless_bind_unix_socket
def test_start_unix_server(self):
class MyServer:
diff --git a/Lib/test/test_asyncio/test_unix_events.py b/Lib/test/test_asyncio/test_unix_events.py
index fe758ba..04284fa 100644
--- a/Lib/test/test_asyncio/test_unix_events.py
+++ b/Lib/test/test_asyncio/test_unix_events.py
@@ -13,6 +13,7 @@ import tempfile
import threading
import unittest
from unittest import mock
+from test import support
if sys.platform == 'win32':
raise unittest.SkipTest('UNIX only')
@@ -239,6 +240,7 @@ class SelectorEventLoopUnixSocketTests(test_utils.TestCase):
self.loop = asyncio.SelectorEventLoop()
self.set_event_loop(self.loop)
+ @support.skip_unless_bind_unix_socket
def test_create_unix_server_existing_path_sock(self):
with test_utils.unix_socket_path() as path:
sock = socket.socket(socket.AF_UNIX)
@@ -251,6 +253,7 @@ class SelectorEventLoopUnixSocketTests(test_utils.TestCase):
srv.close()
self.loop.run_until_complete(srv.wait_closed())
+ @support.skip_unless_bind_unix_socket
def test_create_unix_server_pathlib(self):
with test_utils.unix_socket_path() as path:
path = pathlib.Path(path)
@@ -308,6 +311,7 @@ class SelectorEventLoopUnixSocketTests(test_utils.TestCase):
@unittest.skipUnless(hasattr(socket, 'SOCK_NONBLOCK'),
'no socket.SOCK_NONBLOCK (linux only)')
+ @support.skip_unless_bind_unix_socket
def test_create_unix_server_path_stream_bittype(self):
sock = socket.socket(
socket.AF_UNIX, socket.SOCK_STREAM | socket.SOCK_NONBLOCK)
diff --git a/Misc/NEWS.d/next/Library/2017-11-22-12-54-46.bpo-28684.NLiDKZ.rst b/Misc/NEWS.d/next/Library/2017-11-22-12-54-46.bpo-28684.NLiDKZ.rst
new file mode 100644
index 0000000..9d8e4da
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2017-11-22-12-54-46.bpo-28684.NLiDKZ.rst
@@ -0,0 +1,5 @@
+The new test.support.skip_unless_bind_unix_socket() decorator is used here to
+skip asyncio tests that fail because the platform lacks a functional bind()
+function for unix domain sockets (as it is the case for non root users on the
+recent Android versions that run now SELinux in enforcing mode).
+