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:
Braulio Valdivielso Martínez
2015-12-08 20:40:58 +01:00
parent 578b032555
commit 3eeea3771b
2 changed files with 49 additions and 6 deletions
+21 -1
View File
@@ -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
View File
@@ -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()