Add more socket-related testing helpers.

This commit is contained in:
Eric Snow 2018-04-09 20:02:55 +00:00
parent c01c1ba65a
commit d6252bcb16

View file

@ -1,10 +1,34 @@
from __future__ import absolute_import
from collections import namedtuple
import contextlib
import errno
import ptvsd.socket as _ptvsd
try:
BrokenPipeError # noqa
except NameError:
class BrokenPipeError(Exception):
pass
NOT_CONNECTED = (
errno.ENOTCONN,
errno.EBADF,
)
CLOSED = (
errno.EPIPE,
errno.ESHUTDOWN,
)
EOF = NOT_CONNECTED + CLOSED
# TODO: Add timeouts to the functions.
def create_server(address):
"""Return a server socket after binding."""
host, port = address
@ -53,6 +77,45 @@ def bind(address):
return connect, remote
def recv_as_read(sock):
"""Return a wrapper ardoung sock.read that arises EOFError when closed."""
def read(numbytes, _recv=sock.recv):
try:
return _recv(numbytes)
except BrokenPipeError:
raise EOFError
except OSError as exc:
if exc.errno in EOF:
raise EOFError
raise
return read
def send_as_write(sock):
"""Return a wrapper ardoung sock.send that arises EOFError when closed."""
def write(data, _send=sock.send):
try:
return _send(data)
except BrokenPipeError:
raise EOFError
except OSError as exc:
if exc.errno in EOF:
raise EOFError
raise
return write
@contextlib.contextmanager
def timeout(sock, timeout):
"""A context manager that sets a timeout on blocking socket ops."""
orig = sock.gettimeout()
sock.settimeout(timeout)
try:
yield
finally:
sock.settimeout(orig)
def close(sock):
"""Shutdown and close the socket."""
_ptvsd.close_socket(sock)