20 _DEFAULT_SOCK_OPTIONS = (socket.SO_REUSEADDR,
21 socket.SO_REUSEPORT)
if os.name !=
'nt' else (
23 _UNRECOVERABLE_ERRNOS = (errno.EADDRINUSE, errno.ENOSR)
29 sock_options=_DEFAULT_SOCK_OPTIONS):
32 Useful for reserving a port for a system-under-test.
35 bind_address: The host to which to bind.
36 port: The port to which to bind.
37 listen: A boolean value indicating whether or not to listen on the socket.
38 sock_options: A sequence of socket options to apply to the socket.
42 - the address to which the socket is bound
43 - the port to which the socket is bound
44 - the socket object itself
46 _sock_options = sock_options
if sock_options
else []
48 address_families = (socket.AF_INET6, socket.AF_INET)
50 address_families = (socket.AF_INET)
51 for address_family
in address_families:
53 sock = socket.socket(address_family, socket.SOCK_STREAM)
54 for sock_option
in _sock_options:
55 sock.setsockopt(socket.SOL_SOCKET, sock_option, 1)
56 sock.bind((bind_address, port))
59 return bind_address, sock.getsockname()[1], sock
60 except OSError
as os_error:
62 if os_error.errno
in _UNRECOVERABLE_ERRNOS:
71 raise RuntimeError(
"Failed to bind to {} with sock_options {}".
format(
72 bind_address, sock_options))
75 @contextlib.contextmanager
79 sock_options=_DEFAULT_SOCK_OPTIONS):
80 """Opens a socket bound to an arbitrary port.
82 Useful for reserving a port for a system-under-test.
85 bind_address: The host to which to bind.
86 port: The port to which to bind.
87 listen: A boolean value indicating whether or not to listen on the socket.
88 sock_options: A sequence of socket options to apply to the socket.
92 - the address to which the socket is bound
93 - the port to which the socket is bound
95 host, port, sock =
get_socket(bind_address=bind_address,
98 sock_options=sock_options)