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

Skip to content

bpo-40275: Avoid importing socket in test.support #19603

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Apr 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 71 additions & 59 deletions Doc/library/test.rst
Original file line number Diff line number Diff line change
Expand Up @@ -348,11 +348,6 @@ The :mod:`test.support` module defines the following constants:
:data:`SHORT_TIMEOUT`.


.. data:: IPV6_ENABLED

Set to ``True`` if IPV6 is enabled on this host, ``False`` otherwise.


.. data:: SAVEDCWD

Set to :func:`os.getcwd`.
Expand Down Expand Up @@ -892,12 +887,6 @@ The :mod:`test.support` module defines the following functions:
A decorator for running tests that require support for xattr.


.. decorator:: skip_unless_bind_unix_socket

A decorator for running tests that require a functional bind() for Unix
sockets.


.. decorator:: anticipate_failure(condition)

A decorator to conditionally mark tests with
Expand Down Expand Up @@ -1148,31 +1137,6 @@ The :mod:`test.support` module defines the following functions:
is raised.


.. function:: bind_port(sock, host=HOST)

Bind the socket to a free port and return the port number. Relies on
ephemeral ports in order to ensure we are using an unbound port. This is
important as many tests may be running simultaneously, especially in a
buildbot environment. This method raises an exception if the
``sock.family`` is :const:`~socket.AF_INET` and ``sock.type`` is
:const:`~socket.SOCK_STREAM`, and the socket has
:const:`~socket.SO_REUSEADDR` or :const:`~socket.SO_REUSEPORT` set on it.
Tests should never set these socket options for TCP/IP sockets.
The only case for setting these options is testing multicasting via
multiple UDP sockets.

Additionally, if the :const:`~socket.SO_EXCLUSIVEADDRUSE` socket option is
available (i.e. on Windows), it will be set on the socket. This will
prevent anyone else from binding to our host/port for the duration of the
test.


.. function:: bind_unix_socket(sock, addr)

Bind a unix socket, raising :exc:`unittest.SkipTest` if
:exc:`PermissionError` is raised.


.. function:: catch_threading_exception()

Context manager catching :class:`threading.Thread` exception using
Expand Down Expand Up @@ -1234,29 +1198,6 @@ The :mod:`test.support` module defines the following functions:
.. versionadded:: 3.8


.. function:: find_unused_port(family=socket.AF_INET, socktype=socket.SOCK_STREAM)

Returns an unused port that should be suitable for binding. This is
achieved by creating a temporary socket with the same family and type as
the ``sock`` parameter (default is :const:`~socket.AF_INET`,
:const:`~socket.SOCK_STREAM`),
and binding it to the specified host address (defaults to ``0.0.0.0``)
with the port set to 0, eliciting an unused ephemeral port from the OS.
The temporary socket is then closed and deleted, and the ephemeral port is
returned.

Either this method or :func:`bind_port` should be used for any tests
where a server socket needs to be bound to a particular port for the
duration of the test.
Which one to use depends on whether the calling code is creating a Python
socket, or if an unused port needs to be provided in a constructor
or passed to an external program (i.e. the ``-accept`` argument to
openssl's s_server mode). Always prefer :func:`bind_port` over
:func:`find_unused_port` where possible. Using a hard coded port is
discouraged since it can make multiple instances of the test impossible to
run simultaneously, which is a problem for buildbots.


.. function:: load_package_tests(pkg_dir, loader, standard_tests, pattern)

Generic implementation of the :mod:`unittest` ``load_tests`` protocol for
Expand Down Expand Up @@ -1472,6 +1413,77 @@ The :mod:`test.support` module defines the following classes:
it will be raised in :meth:`!__fspath__`.


:mod:`test.support.socket_helper` --- Utilities for socket tests
================================================================

.. module:: test.support.socket_helper
:synopsis: Support for socket tests.


The :mod:`test.support.socket_helper` module provides support for socket tests.

.. versionadded:: 3.9


.. data:: IPV6_ENABLED

Set to ``True`` if IPv6 is enabled on this host, ``False`` otherwise.


.. function:: find_unused_port(family=socket.AF_INET, socktype=socket.SOCK_STREAM)

Returns an unused port that should be suitable for binding. This is
achieved by creating a temporary socket with the same family and type as
the ``sock`` parameter (default is :const:`~socket.AF_INET`,
:const:`~socket.SOCK_STREAM`),
and binding it to the specified host address (defaults to ``0.0.0.0``)
with the port set to 0, eliciting an unused ephemeral port from the OS.
The temporary socket is then closed and deleted, and the ephemeral port is
returned.

Either this method or :func:`bind_port` should be used for any tests
where a server socket needs to be bound to a particular port for the
duration of the test.
Which one to use depends on whether the calling code is creating a Python
socket, or if an unused port needs to be provided in a constructor
or passed to an external program (i.e. the ``-accept`` argument to
openssl's s_server mode). Always prefer :func:`bind_port` over
:func:`find_unused_port` where possible. Using a hard coded port is
discouraged since it can make multiple instances of the test impossible to
run simultaneously, which is a problem for buildbots.


.. function:: bind_port(sock, host=HOST)

Bind the socket to a free port and return the port number. Relies on
ephemeral ports in order to ensure we are using an unbound port. This is
important as many tests may be running simultaneously, especially in a
buildbot environment. This method raises an exception if the
``sock.family`` is :const:`~socket.AF_INET` and ``sock.type`` is
:const:`~socket.SOCK_STREAM`, and the socket has
:const:`~socket.SO_REUSEADDR` or :const:`~socket.SO_REUSEPORT` set on it.
Tests should never set these socket options for TCP/IP sockets.
The only case for setting these options is testing multicasting via
multiple UDP sockets.

Additionally, if the :const:`~socket.SO_EXCLUSIVEADDRUSE` socket option is
available (i.e. on Windows), it will be set on the socket. This will
prevent anyone else from binding to our host/port for the duration of the
test.


.. function:: bind_unix_socket(sock, addr)

Bind a unix socket, raising :exc:`unittest.SkipTest` if
:exc:`PermissionError` is raised.


.. decorator:: skip_unless_bind_unix_socket

A decorator for running tests that require a functional ``bind()`` for Unix
sockets.


:mod:`test.support.script_helper` --- Utilities for the Python execution tests
==============================================================================

Expand Down
9 changes: 5 additions & 4 deletions Lib/test/_test_multiprocessing.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import test.support
import test.support.script_helper
from test import support
from test.support import socket_helper


# Skip tests if _multiprocessing wasn't built.
Expand Down Expand Up @@ -2928,7 +2929,7 @@ def test_remote(self):
authkey = os.urandom(32)

manager = QueueManager(
address=(test.support.HOST, 0), authkey=authkey, serializer=SERIALIZER
address=(socket_helper.HOST, 0), authkey=authkey, serializer=SERIALIZER
)
manager.start()
self.addCleanup(manager.shutdown)
Expand Down Expand Up @@ -2965,7 +2966,7 @@ def _putter(cls, address, authkey):
def test_rapid_restart(self):
authkey = os.urandom(32)
manager = QueueManager(
address=(test.support.HOST, 0), authkey=authkey, serializer=SERIALIZER)
address=(socket_helper.HOST, 0), authkey=authkey, serializer=SERIALIZER)
try:
srvr = manager.get_server()
addr = srvr.address
Expand Down Expand Up @@ -3455,7 +3456,7 @@ def _listener(cls, conn, families):
new_conn.close()
l.close()

l = socket.create_server((test.support.HOST, 0))
l = socket.create_server((socket_helper.HOST, 0))
conn.send(l.getsockname())
new_conn, addr = l.accept()
conn.send(new_conn)
Expand Down Expand Up @@ -4581,7 +4582,7 @@ def _child_test_wait_socket(cls, address, slow):

def test_wait_socket(self, slow=False):
from multiprocessing.connection import wait
l = socket.create_server((test.support.HOST, 0))
l = socket.create_server((socket_helper.HOST, 0))
addr = l.getsockname()
readers = []
procs = []
Expand Down
5 changes: 3 additions & 2 deletions Lib/test/eintrdata/eintr_tester.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import unittest

from test import support
from test.support import socket_helper

@contextlib.contextmanager
def kill_on_error(proc):
Expand Down Expand Up @@ -283,14 +284,14 @@ def test_sendmsg(self):
self._test_send(lambda sock, data: sock.sendmsg([data]))

def test_accept(self):
sock = socket.create_server((support.HOST, 0))
sock = socket.create_server((socket_helper.HOST, 0))
self.addCleanup(sock.close)
port = sock.getsockname()[1]

code = '\n'.join((
'import socket, time',
'',
'host = %r' % support.HOST,
'host = %r' % socket_helper.HOST,
'port = %s' % port,
'sleep_time = %r' % self.sleep_time,
'',
Expand Down
3 changes: 2 additions & 1 deletion Lib/test/ssl_servers.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@
SimpleHTTPRequestHandler, BaseHTTPRequestHandler)

from test import support
from test.support import socket_helper

here = os.path.dirname(__file__)

HOST = support.HOST
HOST = socket_helper.HOST
CERTFILE = os.path.join(here, 'keycert.pem')

# This one's based on HTTPServer, which is based on socketserver
Expand Down
Loading