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

Skip to content

Commit 0f86cd3

Browse files
authored
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).
1 parent 19fb134 commit 0f86cd3

5 files changed

Lines changed: 45 additions & 11 deletions

File tree

Lib/test/support/__init__.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@
8888
"requires_IEEE_754", "skip_unless_xattr", "requires_zlib",
8989
"anticipate_failure", "load_package_tests", "detect_api_mismatch",
9090
"check__all__", "requires_android_level", "requires_multiprocessing_queue",
91+
"skip_unless_bind_unix_socket",
9192
# sys
9293
"is_jython", "is_android", "check_impl_detail", "unix_shell",
9394
"setswitchinterval",
@@ -2432,6 +2433,28 @@ def skip_unless_xattr(test):
24322433
msg = "no non-broken extended attribute support"
24332434
return test if ok else unittest.skip(msg)(test)
24342435

2436+
_bind_nix_socket_error = None
2437+
def skip_unless_bind_unix_socket(test):
2438+
"""Decorator for tests requiring a functional bind() for unix sockets."""
2439+
if not hasattr(socket, 'AF_UNIX'):
2440+
return unittest.skip('No UNIX Sockets')(test)
2441+
global _bind_nix_socket_error
2442+
if _bind_nix_socket_error is None:
2443+
path = TESTFN + "can_bind_unix_socket"
2444+
with socket.socket(socket.AF_UNIX) as sock:
2445+
try:
2446+
sock.bind(path)
2447+
_bind_nix_socket_error = False
2448+
except OSError as e:
2449+
_bind_nix_socket_error = e
2450+
finally:
2451+
unlink(path)
2452+
if _bind_nix_socket_error:
2453+
msg = 'Requires a functional unix bind(): %s' % _bind_nix_socket_error
2454+
return unittest.skip(msg)(test)
2455+
else:
2456+
return test
2457+
24352458

24362459
def fs_is_case_insensitive(directory):
24372460
"""Detects if the file system for the specified directory is case-insensitive."""

Lib/test/test_asyncio/test_events.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import unittest
2323
from unittest import mock
2424
import weakref
25+
from test import support
2526

2627
if sys.platform != 'win32':
2728
import tty
@@ -470,7 +471,7 @@ def test_sock_client_ops(self):
470471
sock = socket.socket()
471472
self._basetest_sock_recv_into(httpd, sock)
472473

473-
@unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets')
474+
@support.skip_unless_bind_unix_socket
474475
def test_unix_sock_client_ops(self):
475476
with test_utils.run_test_unix_server() as httpd:
476477
sock = socket.socket(socket.AF_UNIX)
@@ -606,7 +607,7 @@ def test_create_connection(self):
606607
lambda: MyProto(loop=self.loop), *httpd.address)
607608
self._basetest_create_connection(conn_fut)
608609

609-
@unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets')
610+
@support.skip_unless_bind_unix_socket
610611
def test_create_unix_connection(self):
611612
# Issue #20682: On Mac OS X Tiger, getsockname() returns a
612613
# zero-length address for UNIX socket.
@@ -736,8 +737,8 @@ def test_create_ssl_connection(self):
736737
self._test_create_ssl_connection(httpd, create_connection,
737738
peername=httpd.address)
738739

740+
@support.skip_unless_bind_unix_socket
739741
@unittest.skipIf(ssl is None, 'No ssl module')
740-
@unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets')
741742
def test_create_ssl_unix_connection(self):
742743
# Issue #20682: On Mac OS X Tiger, getsockname() returns a
743744
# zero-length address for UNIX socket.
@@ -961,7 +962,7 @@ def _make_unix_server(self, factory, **kwargs):
961962

962963
return server, path
963964

964-
@unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets')
965+
@support.skip_unless_bind_unix_socket
965966
def test_create_unix_server(self):
966967
proto = MyProto(loop=self.loop)
967968
server, path = self._make_unix_server(lambda: proto)
@@ -1053,8 +1054,8 @@ def test_create_server_ssl(self):
10531054
# stop serving
10541055
server.close()
10551056

1057+
@support.skip_unless_bind_unix_socket
10561058
@unittest.skipIf(ssl is None, 'No ssl module')
1057-
@unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets')
10581059
def test_create_unix_server_ssl(self):
10591060
proto = MyProto(loop=self.loop)
10601061
server, path = self._make_ssl_unix_server(
@@ -1113,8 +1114,8 @@ def test_create_server_ssl_verify_failed(self):
11131114
self.assertIsNone(proto.transport)
11141115
server.close()
11151116

1117+
@support.skip_unless_bind_unix_socket
11161118
@unittest.skipIf(ssl is None, 'No ssl module')
1117-
@unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets')
11181119
def test_create_unix_server_ssl_verify_failed(self):
11191120
proto = MyProto(loop=self.loop)
11201121
server, path = self._make_ssl_unix_server(
@@ -1171,8 +1172,8 @@ def test_create_server_ssl_match_failed(self):
11711172
proto.transport.close()
11721173
server.close()
11731174

1175+
@support.skip_unless_bind_unix_socket
11741176
@unittest.skipIf(ssl is None, 'No ssl module')
1175-
@unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets')
11761177
def test_create_unix_server_ssl_verified(self):
11771178
proto = MyProto(loop=self.loop)
11781179
server, path = self._make_ssl_unix_server(

Lib/test/test_asyncio/test_streams.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import threading
1010
import unittest
1111
from unittest import mock
12+
from test import support
1213
try:
1314
import ssl
1415
except ImportError:
@@ -57,7 +58,7 @@ def test_open_connection(self):
5758
loop=self.loop)
5859
self._basetest_open_connection(conn_fut)
5960

60-
@unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets')
61+
@support.skip_unless_bind_unix_socket
6162
def test_open_unix_connection(self):
6263
with test_utils.run_test_unix_server() as httpd:
6364
conn_fut = asyncio.open_unix_connection(httpd.address,
@@ -86,8 +87,8 @@ def test_open_connection_no_loop_ssl(self):
8687

8788
self._basetest_open_connection_no_loop_ssl(conn_fut)
8889

90+
@support.skip_unless_bind_unix_socket
8991
@unittest.skipIf(ssl is None, 'No ssl module')
90-
@unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets')
9192
def test_open_unix_connection_no_loop_ssl(self):
9293
with test_utils.run_test_unix_server(use_ssl=True) as httpd:
9394
conn_fut = asyncio.open_unix_connection(
@@ -113,7 +114,7 @@ def test_open_connection_error(self):
113114
loop=self.loop)
114115
self._basetest_open_connection_error(conn_fut)
115116

116-
@unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets')
117+
@support.skip_unless_bind_unix_socket
117118
def test_open_unix_connection_error(self):
118119
with test_utils.run_test_unix_server() as httpd:
119120
conn_fut = asyncio.open_unix_connection(httpd.address,
@@ -634,7 +635,7 @@ def client(addr):
634635
server.stop()
635636
self.assertEqual(msg, b"hello world!\n")
636637

637-
@unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets')
638+
@support.skip_unless_bind_unix_socket
638639
def test_start_unix_server(self):
639640

640641
class MyServer:

Lib/test/test_asyncio/test_unix_events.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import threading
1414
import unittest
1515
from unittest import mock
16+
from test import support
1617

1718
if sys.platform == 'win32':
1819
raise unittest.SkipTest('UNIX only')
@@ -239,6 +240,7 @@ def setUp(self):
239240
self.loop = asyncio.SelectorEventLoop()
240241
self.set_event_loop(self.loop)
241242

243+
@support.skip_unless_bind_unix_socket
242244
def test_create_unix_server_existing_path_sock(self):
243245
with test_utils.unix_socket_path() as path:
244246
sock = socket.socket(socket.AF_UNIX)
@@ -251,6 +253,7 @@ def test_create_unix_server_existing_path_sock(self):
251253
srv.close()
252254
self.loop.run_until_complete(srv.wait_closed())
253255

256+
@support.skip_unless_bind_unix_socket
254257
def test_create_unix_server_pathlib(self):
255258
with test_utils.unix_socket_path() as path:
256259
path = pathlib.Path(path)
@@ -308,6 +311,7 @@ def test_create_unix_server_path_dgram(self):
308311

309312
@unittest.skipUnless(hasattr(socket, 'SOCK_NONBLOCK'),
310313
'no socket.SOCK_NONBLOCK (linux only)')
314+
@support.skip_unless_bind_unix_socket
311315
def test_create_unix_server_path_stream_bittype(self):
312316
sock = socket.socket(
313317
socket.AF_UNIX, socket.SOCK_STREAM | socket.SOCK_NONBLOCK)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
The new test.support.skip_unless_bind_unix_socket() decorator is used here to
2+
skip asyncio tests that fail because the platform lacks a functional bind()
3+
function for unix domain sockets (as it is the case for non root users on the
4+
recent Android versions that run now SELinux in enforcing mode).
5+

0 commit comments

Comments
 (0)