From 90a4e9c09514fa16d8573512327ef33120c29549 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francis=20Clairicia-Rose-Claire-Jos=C3=A9phine?= Date: Sat, 9 Nov 2024 22:17:34 +0100 Subject: [PATCH] Documentation: Removed `reuse_port` option from UDP clients (#375) --- src/easynetwork/clients/async_udp.py | 7 ++-- src/easynetwork/clients/udp.py | 12 ++----- .../lowlevel/api_async/backend/abc.py | 2 +- src/easynetwork/servers/async_tcp.py | 7 ++-- src/easynetwork/servers/async_udp.py | 7 ++-- .../test_sync/test_client/test_udp.py | 33 +------------------ 6 files changed, 14 insertions(+), 54 deletions(-) diff --git a/src/easynetwork/clients/async_udp.py b/src/easynetwork/clients/async_udp.py index 55e6e73a..3c7087f5 100644 --- a/src/easynetwork/clients/async_udp.py +++ b/src/easynetwork/clients/async_udp.py @@ -103,14 +103,11 @@ def __init__( Connection Parameters: address: A pair of ``(host, port)`` for connection. local_address: If given, is a ``(local_host, local_port)`` tuple used to bind the socket locally. - reuse_port: Tells the kernel to allow this endpoint to be bound to the same port as other existing - endpoints are bound to, so long as they all set this flag when being created. - This option is not supported on Windows and some Unixes. - If the SO_REUSEPORT constant is not defined then this capability is unsupported. + family: The address family. Should be any of ``AF_UNSPEC``, ``AF_INET`` or ``AF_INET6``. Socket Parameters: socket: An already connected UDP :class:`socket.socket`. If `socket` is given, - none of and `local_address` and `reuse_port` should be specified. + none of `family` and `local_address` should be specified. """ super().__init__() diff --git a/src/easynetwork/clients/udp.py b/src/easynetwork/clients/udp.py index e6cfc28a..c62da086 100644 --- a/src/easynetwork/clients/udp.py +++ b/src/easynetwork/clients/udp.py @@ -56,7 +56,6 @@ def __init__( *, local_address: tuple[str, int] | None = ..., family: int = ..., - reuse_port: bool = ..., retry_interval: float = ..., ) -> None: ... @@ -86,14 +85,11 @@ def __init__( Connection Parameters: address: A pair of ``(host, port)`` for connection. local_address: If given, is a ``(local_host, local_port)`` tuple used to bind the socket locally. - reuse_port: Tells the kernel to allow this endpoint to be bound to the same port as other existing - endpoints are bound to, so long as they all set this flag when being created. - This option is not supported on Windows and some Unixes. - If the SO_REUSEPORT constant is not defined then this capability is unsupported. + family: The address family. Should be any of ``AF_UNSPEC``, ``AF_INET`` or ``AF_INET6``. Socket Parameters: socket: An already connected UDP :class:`socket.socket`. If `socket` is given, - none of and `local_address` and `reuse_port` should be specified. + none of `family` and `local_address` should be specified. Keyword Arguments: retry_interval: The maximum wait time to wait for a blocking operation before retrying. @@ -309,7 +305,6 @@ def _create_udp_socket( *, local_address: tuple[str, int] | None = None, family: int = _socket.AF_UNSPEC, - reuse_port: bool = False, ) -> _socket.socket: errors: list[OSError] = [] @@ -324,9 +319,6 @@ def _create_udp_socket( errors.clear() raise try: - if reuse_port: - _utils.set_reuseport(socket) - if local_address is not None: socket.bind(local_address) diff --git a/src/easynetwork/lowlevel/api_async/backend/abc.py b/src/easynetwork/lowlevel/api_async/backend/abc.py index f4f6ff7d..79974cb6 100644 --- a/src/easynetwork/lowlevel/api_async/backend/abc.py +++ b/src/easynetwork/lowlevel/api_async/backend/abc.py @@ -1070,7 +1070,7 @@ async def create_udp_endpoint( remote_host: The host IP/domain name. remote_port: Port of connection. local_address: If given, is a ``(local_host, local_port)`` tuple used to bind the socket locally. - family: The address family + family: The address family. Should be any of ``AF_UNSPEC``, ``AF_INET`` or ``AF_INET6``. Raises: OSError: unrelated OS error occurred. diff --git a/src/easynetwork/servers/async_tcp.py b/src/easynetwork/servers/async_tcp.py index ea70b226..635636c7 100644 --- a/src/easynetwork/servers/async_tcp.py +++ b/src/easynetwork/servers/async_tcp.py @@ -114,9 +114,10 @@ def __init__( ssl_standard_compatible: if :data:`False`, skip the closing handshake when closing the connection, and don't raise an exception if the peer does the same. backlog: is the maximum number of queued connections passed to :class:`~socket.socket.listen` (defaults to ``100``). - reuse_port: tells the kernel to allow this endpoint to be bound to the same port as other existing endpoints - are bound to, so long as they all set this flag when being created. - This option is not supported on Windows. + reuse_port: Tells the kernel to allow this endpoint to be bound to the same port as other existing + endpoints are bound to, so long as they all set this flag when being created. + This option is not supported on Windows and some Unixes. + If the SO_REUSEPORT constant is not defined then this capability is unsupported. max_recv_size: Read buffer size. If not given, a default reasonable value is used. log_client_connection: If :data:`True`, log clients connection/disconnection in :data:`logging.INFO` level. (This log will always be available in :data:`logging.DEBUG` level.) diff --git a/src/easynetwork/servers/async_udp.py b/src/easynetwork/servers/async_udp.py index 84381a5b..1505297e 100644 --- a/src/easynetwork/servers/async_udp.py +++ b/src/easynetwork/servers/async_udp.py @@ -80,9 +80,10 @@ def __init__( backend: The :term:`asynchronous backend interface` to use. Keyword Arguments: - reuse_port: tells the kernel to allow this endpoint to be bound to the same port as other existing endpoints - are bound to, so long as they all set this flag when being created. - This option is not supported on Windows. + reuse_port: Tells the kernel to allow this endpoint to be bound to the same port as other existing + endpoints are bound to, so long as they all set this flag when being created. + This option is not supported on Windows and some Unixes. + If the SO_REUSEPORT constant is not defined then this capability is unsupported. logger: If given, the logger instance to use. """ super().__init__( diff --git a/tests/unit_test/test_sync/test_client/test_udp.py b/tests/unit_test/test_sync/test_client/test_udp.py index 8b4a570c..1cb423f8 100644 --- a/tests/unit_test/test_sync/test_client/test_udp.py +++ b/tests/unit_test/test_sync/test_client/test_udp.py @@ -186,11 +186,9 @@ def test____dunder_init____create_datagram_endpoint____default( @pytest.mark.parametrize( "local_address", [None, ("local_address", 12345)], ids=lambda p: f"local_address=={p}", indirect=True ) - @pytest.mark.parametrize("reuse_port", [False, True], ids=lambda p: f"reuse_port=={p}") def test____dunder_init____create_datagram_endpoint____with_parameters( self, request: pytest.FixtureRequest, - reuse_port: bool, socket_family: int, local_address: tuple[str, int] | None, remote_address: tuple[str, int], @@ -207,7 +205,6 @@ def test____dunder_init____create_datagram_endpoint____with_parameters( mock_datagram_protocol, family=socket_family, local_address=local_address, - reuse_port=reuse_port, ) request.addfinalizer(client.close) @@ -216,7 +213,6 @@ def test____dunder_init____create_datagram_endpoint____with_parameters( family=socket_family, local_address=local_address, remote_address=remote_address, - reuse_port=reuse_port, ) assert mock_udp_socket.mock_calls == [ mocker.call.getpeername(), @@ -227,11 +223,9 @@ def test____dunder_init____create_datagram_endpoint____with_parameters( @pytest.mark.parametrize( "local_address", [None, ("local_address", 12345)], ids=lambda p: f"local_address=={p}", indirect=True ) - @pytest.mark.parametrize("reuse_port", [False, True], ids=lambda p: f"reuse_port=={p}") def test____dunder_init____create_datagram_endpoint____with_parameters____explicit_AF_UNSPEC( self, request: pytest.FixtureRequest, - reuse_port: bool, local_address: tuple[str, int] | None, remote_address: tuple[str, int], mock_datagram_protocol: MagicMock, @@ -245,7 +239,6 @@ def test____dunder_init____create_datagram_endpoint____with_parameters____explic mock_datagram_protocol, family=AF_UNSPEC, local_address=local_address, - reuse_port=reuse_port, ) request.addfinalizer(client.close) @@ -254,7 +247,6 @@ def test____dunder_init____create_datagram_endpoint____with_parameters____explic family=AF_UNSPEC, local_address=local_address, remote_address=remote_address, - reuse_port=reuse_port, ) @pytest.mark.parametrize("socket_family", list(UNSUPPORTED_FAMILIES), indirect=True) @@ -917,7 +909,6 @@ def test____create_udp_socket____default( mock_socket_ipv4.close.assert_not_called() @pytest.mark.parametrize("with_local_address", [False, True], ids=lambda boolean: f"with_local_address=={boolean}") - @pytest.mark.parametrize("set_reuse_port", [False, True], ids=lambda boolean: f"set_reuse_port=={boolean}") @pytest.mark.parametrize( ["family", "socket_families"], [ @@ -930,14 +921,12 @@ def test____create_udp_socket____default( def test____create_udp_socket____with_parameters( self, with_local_address: bool, - set_reuse_port: bool, family: int, socket_families: tuple[int, ...], mock_socket_cls: MagicMock, mock_getaddrinfo: MagicMock, mock_socket_ipv4: MagicMock, mock_socket_ipv6: MagicMock, - SO_REUSEPORT: int, ) -> None: # Arrange remote_address: tuple[str, int] = ("remote_address", 12345) @@ -948,7 +937,6 @@ def test____create_udp_socket____with_parameters( local_address=local_address, remote_address=remote_address, family=family, - reuse_port=set_reuse_port, ) # Assert @@ -967,10 +955,7 @@ def test____create_udp_socket____with_parameters( mock_socket_cls.assert_called_once_with(AF_INET6, SOCK_DGRAM, IPPROTO_UDP) used_socket = mock_socket_ipv6 not_used_socket = mock_socket_ipv4 - if set_reuse_port: - used_socket.setsockopt.assert_called_once_with(SOL_SOCKET, SO_REUSEPORT, True) - else: - used_socket.setsockopt.assert_not_called() + used_socket.setsockopt.assert_not_called() if local_address is None: used_socket.bind.assert_not_called() else: @@ -1104,22 +1089,6 @@ def test____create_udp_socket____all_failed( mock_socket_ipv6.connect.assert_not_called() mock_socket_ipv6.close.assert_not_called() - @pytest.mark.usefixtures("remove_SO_REUSEPORT_support") - def test____create_udp_socket____SO_REUSEPORT_not_supported( - self, - mock_socket_ipv4: MagicMock, - ) -> None: - # Arrange - remote_address: tuple[str, int] = ("remote_address", 12345) - local_address: tuple[str, int] = ("local_address", 11111) - - # Act - with pytest.raises(ValueError): - _ = create_udp_socket(local_address=local_address, remote_address=remote_address, reuse_port=True) - - # Assert - mock_socket_ipv4.close.assert_called_once_with() - @pytest.mark.parametrize("fail_on", ["socket", "bind"], ids=lambda fail_on: f"fail_on=={fail_on}") def test____create_udp_socket____unrelated_exception( self,