diff options
author | Gabriel Falcão <gabrielfalcao@users.noreply.github.com> | 2021-05-24 22:30:35 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-05-24 22:30:35 +0200 |
commit | ca84d393f8d3e3220cca36981ebf10fb1c024d40 (patch) | |
tree | 7f8aa304dbf1576c1b708413134dac2c042843f3 | |
parent | 19880d856d2a62c52d8b218953d742e9ba10f784 (diff) | |
download | httpretty-ca84d393f8d3e3220cca36981ebf10fb1c024d40.tar.gz |
Respect socket timeout (#431)
* respect socket timeout
closes #430
* socket timeout default 0.1 seconds
* remove return
-rw-r--r-- | httpretty/core.py | 11 | ||||
-rw-r--r-- | tests/bugfixes/nosetests/test_430_respect_timeout.py | 54 |
2 files changed, 63 insertions, 2 deletions
diff --git a/httpretty/core.py b/httpretty/core.py index 302aa25..c73700c 100644 --- a/httpretty/core.py +++ b/httpretty/core.py @@ -74,7 +74,7 @@ from datetime import timedelta from errno import EAGAIN class __internals__: - thread_timeout = 0 # https://github.com/gabrielfalcao/HTTPretty/issues/426 + thread_timeout = 0.1 # https://github.com/gabrielfalcao/HTTPretty/issues/430 temp_files = [] threads = [] @@ -692,13 +692,20 @@ class fakesock(object): target=self._entry.fill_filekind, args=(self.fd,) ) + # execute body callback and send http response in a + # thread, wait for thread to finish within the timeout + # set via socket.settimeout() t.start() if self.timeout == SOCKET_GLOBAL_DEFAULT_TIMEOUT: timeout = get_default_thread_timeout() else: timeout = self.timeout - t.join(None) + + # fake socket timeout error by checking if the thread + # finished in time. + t.join(timeout) if t.is_alive(): + # For more info check issue https://github.com/gabrielfalcao/HTTPretty/issues/430 raise socket.timeout(timeout) return self.fd diff --git a/tests/bugfixes/nosetests/test_430_respect_timeout.py b/tests/bugfixes/nosetests/test_430_respect_timeout.py new file mode 100644 index 0000000..f21a546 --- /dev/null +++ b/tests/bugfixes/nosetests/test_430_respect_timeout.py @@ -0,0 +1,54 @@ +# This test is based on @mariojonke snippet: +# https://github.com/gabrielfalcao/HTTPretty/issues/430 +import time +from requests import Session +from requests.adapters import HTTPAdapter +from requests.exceptions import ReadTimeout + +from threading import Event + +from httpretty import httprettified +from httpretty import HTTPretty + + +def http(max_connections=1): + session = Session() + adapter = HTTPAdapter( + pool_connections=max_connections, + pool_maxsize=max_connections + ) + session.mount('http://', adapter) + session.mount('https://', adapter) + return session + + + +@httprettified(verbose=True, allow_net_connect=False) +def test_read_timeout(): + "#430 httpretty should respect read timeout" + event = Event() + uri = "http://example.com" + + # Given that I register a uri with a callback body that delays 10 seconds + wait_seconds = 10 + + def my_callback(request, url, headers): + event.wait(wait_seconds) + return 200, headers, "Received" + + HTTPretty.register_uri(HTTPretty.GET, uri, body=my_callback) + + # And I use a thread pool with 1 TCP connection max + max_connections = 1 + request = http(max_connections) + started_at = time.time() + # When I make an HTTP request with a read timeout of 0.1 and an indefinite connect timeout + when_called = request.get.when.called_with(uri, timeout=(None, 0.1)) + + # Then the request should have raised a connection timeout + when_called.should.have.raised(ReadTimeout) + + # And the total execution time should be less than 0.2 seconds + event.set() + total_time = time.time() - started_at + total_time.should.be.lower_than(0.2) |