summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabriel Falcão <gabrielfalcao@users.noreply.github.com>2021-05-24 22:30:35 +0200
committerGitHub <noreply@github.com>2021-05-24 22:30:35 +0200
commitca84d393f8d3e3220cca36981ebf10fb1c024d40 (patch)
tree7f8aa304dbf1576c1b708413134dac2c042843f3
parent19880d856d2a62c52d8b218953d742e9ba10f784 (diff)
downloadhttpretty-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.py11
-rw-r--r--tests/bugfixes/nosetests/test_430_respect_timeout.py54
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)