From c6ae228c8e66d8526f1c489a59c1a4020ec1049f Mon Sep 17 00:00:00 2001 From: Seth Michael Larson Date: Fri, 28 Aug 2020 13:11:37 -0500 Subject: [PATCH] Skip BrokenPipeError test on Windows --- src/urllib3/connectionpool.py | 10 +++++++--- test/__init__.py | 13 +++++++++++++ test/with_dummyserver/test_socketlevel.py | 14 ++++++++++++-- 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/src/urllib3/connectionpool.py b/src/urllib3/connectionpool.py index ab74216aef..6f0208915b 100644 --- a/src/urllib3/connectionpool.py +++ b/src/urllib3/connectionpool.py @@ -400,10 +400,14 @@ def _make_request( # Python 3 pass except IOError as e: - # EPIPE and ESHUTDOWN are BrokenPipeError on Python 2, and EPROTOTYPE is - # needed on macOS + # Python 2 and macOS/Linux + # EPIPE and ESHUTDOWN are BrokenPipeError on Python 2, and EPROTOTYPE is needed on macOS # https://erickt.github.io/blog/2014/11/19/adventures-in-debugging-a-potential-osx-kernel-bug/ - if e.errno not in (errno.EPIPE, errno.ESHUTDOWN, errno.EPROTOTYPE): + if e.errno not in { + errno.EPIPE, + errno.ESHUTDOWN, + errno.EPROTOTYPE, + }: raise # Reset the timeout for the recv() on the socket diff --git a/test/__init__.py b/test/__init__.py index 01f02738d0..92a069b52d 100644 --- a/test/__init__.py +++ b/test/__init__.py @@ -152,6 +152,19 @@ def wrapper(*args, **kwargs): return wrapper +def notWindows(test): + """Skips this test when running on Windows""" + + @six.wraps(test) + def wrapper(*args, **kwargs): + msg = "{name} does not run on Windows".format(name=test.__name__) + if platform.system() == "Windows": + pytest.skip(msg) + return test(*args, **kwargs) + + return wrapper + + def notOpenSSL098(test): """Skips this test for Python 3.5 macOS python.org distribution""" diff --git a/test/with_dummyserver/test_socketlevel.py b/test/with_dummyserver/test_socketlevel.py index de03930ec7..3b807aec83 100644 --- a/test/with_dummyserver/test_socketlevel.py +++ b/test/with_dummyserver/test_socketlevel.py @@ -57,6 +57,7 @@ class MimeToolMessage(object): LONG_TIMEOUT, notPyPy2, notSecureTransport, + notWindows, resolvesLocalhostFQDN, ) @@ -1783,7 +1784,10 @@ def socket_handler(listener): class TestBrokenPipe(SocketDummyServerTestCase): - def test_broken_pipe_ignore(self, monkeypatch): + @notWindows + def test_ignore_broken_pipe_errors(self, monkeypatch): + # On Windows an aborted connection raises an error on + # attempts to read data out of a socket that's been closed. sock_shut = Event() orig_connect = HTTPConnection.connect # a buffer that will cause two sendall calls @@ -1800,8 +1804,9 @@ def socket_handler(listener): sock.send( b"HTTP/1.1 404 Not Found\r\n" b"Connection: close\r\n" - b"Content-Length: 0\r\n" + b"Content-Length: 10\r\n" b"\r\n" + b"xxxxxxxxxx" ) sock.shutdown(socket.SHUT_RDWR) sock_shut.set() @@ -1812,5 +1817,10 @@ def socket_handler(listener): with HTTPConnectionPool(self.host, self.port) as pool: r = pool.request("POST", "/", body=buf) assert r.status == 404 + assert r.headers["content-length"] == "10" + assert r.data == b"xxxxxxxxxx" + r = pool.request("POST", "/admin", chunked=True, body=buf) assert r.status == 404 + assert r.headers["content-length"] == "10" + assert r.data == b"xxxxxxxxxx"