mirror of
https://github.com/kennethreitz/requests.git
synced 2026-06-05 22:50:18 +00:00
Added a way for TestServer request handlers to store data for later retrieval by the main thread (actual requests, for example)
This commit is contained in:
+21
-1
@@ -1779,6 +1779,7 @@ class TestTestServer(unittest.TestCase):
|
||||
with Server.basic_response_server() as (host, port):
|
||||
sock = socket.socket()
|
||||
sock.connect((host, port))
|
||||
|
||||
sock.close()
|
||||
|
||||
with pytest.raises(socket.error):
|
||||
@@ -1797,7 +1798,7 @@ class TestTestServer(unittest.TestCase):
|
||||
|
||||
assert r.status_code == 200
|
||||
assert r.text == 'roflol'
|
||||
assert r.headers['Content-Length'] == '6'
|
||||
assert r.headers['Content-Length'] == '6'
|
||||
|
||||
def test_basic_response(self):
|
||||
with Server.basic_response_server() as (host, port):
|
||||
@@ -1832,6 +1833,25 @@ class TestTestServer(unittest.TestCase):
|
||||
with pytest.raises(requests.exceptions.ConnectionError):
|
||||
r = requests.get(server_url)
|
||||
|
||||
def test_request_recovery(self):
|
||||
server = Server.basic_response_server(requests_to_handle=2)
|
||||
first_request = "put your hands up in the air"
|
||||
second_request = "put your hand down in the floor"
|
||||
|
||||
with server as address:
|
||||
sock1 = socket.socket()
|
||||
sock2 = socket.socket()
|
||||
|
||||
sock1.connect(address)
|
||||
sock1.send(first_request.encode())
|
||||
sock1.close()
|
||||
|
||||
sock2.connect(address)
|
||||
sock2.send(second_request.encode())
|
||||
sock2.close()
|
||||
|
||||
assert server.handler_results[0] == first_request
|
||||
assert server.handler_results[1] == second_request
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
+28
-5
@@ -2,18 +2,35 @@
|
||||
|
||||
import threading
|
||||
import socket
|
||||
import select
|
||||
|
||||
def consume_socket(sock, chunks=65536):
|
||||
while not sock.recv(chunks).endswith(b'\r\n\r\n'):
|
||||
pass
|
||||
|
||||
def consume_socket_content(sock, chunks=65536, timeout=0.5):
|
||||
content = ""
|
||||
more_to_read = select.select([sock], [], [], timeout)[0]
|
||||
|
||||
while more_to_read:
|
||||
new_content = sock.recv(chunks).decode("utf-8")
|
||||
|
||||
if len(new_content) == 0:
|
||||
more_to_read = False # empty recv means the socket disconnected
|
||||
|
||||
else:
|
||||
content += new_content
|
||||
# stop reading if no new data is received for a while
|
||||
more_to_read = select.select([sock], [], [], timeout)[0]
|
||||
|
||||
return content
|
||||
|
||||
class Server(threading.Thread):
|
||||
""" Dummy server using for unit testing """
|
||||
|
||||
def __init__(self, handler, host='localhost', port=0, requests_to_handle=1, wait_to_close_event=None):
|
||||
threading.Thread.__init__(self)
|
||||
|
||||
self.handler = handler
|
||||
self.handler_results = []
|
||||
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.requests_to_handle = requests_to_handle
|
||||
@@ -23,10 +40,14 @@ class Server(threading.Thread):
|
||||
self.stop_event = threading.Event()
|
||||
|
||||
@classmethod
|
||||
def text_response_server(cls, text, **kwargs):
|
||||
def text_response_server(cls, text, request_timeout=0.5, **kwargs):
|
||||
def text_response_handler(sock):
|
||||
request_content = consume_socket_content(sock, timeout=request_timeout)
|
||||
sock.send(text.encode())
|
||||
|
||||
return request_content
|
||||
|
||||
|
||||
server = Server(text_response_handler, **kwargs)
|
||||
|
||||
return server
|
||||
@@ -61,7 +82,9 @@ class Server(threading.Thread):
|
||||
def _handle_requests_and_close_server(self, server_sock):
|
||||
for _ in range(self.requests_to_handle):
|
||||
sock = server_sock.accept()[0]
|
||||
self.handler(sock)
|
||||
handler_result = self.handler(sock)
|
||||
|
||||
self.handler_results.append(handler_result)
|
||||
|
||||
if self.wait_to_close_event:
|
||||
self.wait_to_close_event.wait()
|
||||
|
||||
Reference in New Issue
Block a user