From 137f671ee450e4ad92fda16f227d668d3efbde94 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Thu, 11 Jan 2018 20:04:36 +0000 Subject: [PATCH] Add a testing helper for serving HTTP locally. --- tests/helpers/__init__.py | 0 tests/helpers/http.py | 61 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 tests/helpers/__init__.py create mode 100644 tests/helpers/http.py diff --git a/tests/helpers/__init__.py b/tests/helpers/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/helpers/http.py b/tests/helpers/http.py new file mode 100644 index 00000000..e7ded9f8 --- /dev/null +++ b/tests/helpers/http.py @@ -0,0 +1,61 @@ +import http.server +import threading + + +class Server: + """Wraps an http.server.HTTPServer in a thread.""" + + def __init__(self, handler, host='', port=8000): + self.handler = handler + self._addr = (host, port) + self._server = None + self._thread = None + + @property + def address(self): + host, port = self._addr + if host == '': + host = 'localhost' + return '{}:{}'.format(host, port) + + def start(self): + if self._server is not None: + raise RuntimeError('already started') + self._server = http.server.HTTPServer(self._addr, self.handler) + self._thread = threading.Thread( + target=lambda: self._server.serve_forever()) + self._thread.start() + + def stop(self): + if self._server is None: + raise RuntimeError('not running') + self._server.shutdown() + self._thread.join() + self._server.server_close() + self._thread = None + self._server = None + + def __enter__(self): + self.start() + return self + + def __exit__(self, *args): + self.stop() + + +def json_file_handler(data): + """Return an HTTP handler that always serves the given JSON bytes.""" + + class HTTPHandler(http.server.BaseHTTPRequestHandler): + def do_GET(self): + self.send_response(200) + self.send_header('Content-Type', b'application/json') + self.send_header('Content-Length', + str(len(data)).encode('ascii')) + self.end_headers() + self.wfile.write(data) + + def log_message(self, *args, **kwargs): + pass + + return HTTPHandler