def server(self): """Provides a test HTTP server. The test server is automatically created before a test and destroyed at the end. The server is serving a test application that can be used to verify requests. """ app = flask.Flask(__name__) app.debug = True # pylint: disable=unused-variable # (pylint thinks the flask routes are unusued.) @app.route('/basic') def index(): header_value = flask.request.headers.get('x-test-header', 'value') headers = {'X-Test-Header': header_value} return 'Basic Content', http_client.OK, headers @app.route('/server_error') def server_error(): return 'Error', http_client.INTERNAL_SERVER_ERROR # pylint: enable=unused-variable server = WSGIServer(application=app.wsgi_app) server.start() yield server server.stop()
def cal_broker(request, old_gains, new_gains): # get updates IDs from module new_update_id = getattr(request.module, "new_update_id", None) old_update_id = getattr(request.module, "old_update_id", None) # Create a basic flask server app = Flask("cal_broker") @app.route("/gain", methods=["POST"]) def gain_app(): content = flask_req.get_json() update_id = content["update_id"] if update_id == new_update_id: gains = encode_gains(*new_gains) elif update_id == old_update_id: gains = encode_gains(*old_gains) else: raise Exception( "Did not recognize update_id {}.".format(update_id)) print(f"Served gains with {update_id}") return jsonify(gains) # hand to localserver fixture server = WSGIServer(application=app) server.start() yield server server.stop()
def fake_jenkins(): # FIXME Sadly gevent1.0.1 together with python 2.7.9+ have a problem with running ssl servers. # jenkins_server = WSGIServer(application=jenkins_app, ssl_context='adhoc') jenkins_server = WSGIServer(application=jenkins_app) jenkins_server.start() yield jenkins_server jenkins_server.stop()
def wsgi_serve(application): server = WSGIServer(application=application) try: server.start() yield server finally: server.stop()
def server(self): """Provides a test HTTP server. The test server is automatically created before a test and destroyed at the end. The server is serving a test application that can be used to verify requests. """ app = flask.Flask(__name__) app.debug = True # pylint: disable=unused-variable # (pylint thinks the flask routes are unusued.) @app.route("/basic") def index(): header_value = flask.request.headers.get("x-test-header", "value") headers = {"X-Test-Header": header_value} return "Basic Content", http_client.OK, headers @app.route("/server_error") def server_error(): return "Error", http_client.INTERNAL_SERVER_ERROR @app.route("/wait") def wait(): time.sleep(3) return "Waited" # pylint: enable=unused-variable server = WSGIServer(application=app.wsgi_app) server.start() yield server server.stop()
def test_webserver(scope="session"): sys.path.append((os.path.normpath(os.path.join(__file__, "..", "..")))) import api server = WSGIServer(application=api.app) server.start() yield server server.stop()
def flask_wsgi_server(request, flask_app, elasticapm_client): server = WSGIServer(application=flask_app) apm_client = ElasticAPM(app=flask_app, client=elasticapm_client) flask_app.apm_client = apm_client server.start() yield server server.stop() apm_client.client.close()
def json_endpoint(temporary_path): server = WSGIServer(application=create_wsgi_endpoint_app(temporary_path)) server.start() server.temporary_path = temporary_path yield server server.stop()
def testserver(): """Defines the testserver funcarg""" server = WSGIServer(application=application, port=0) server.start() print(">>>> Serving on ", server.url) yield server server.stop() del server
def server(app): """Return an HTTP server hosting the web application. :rtype: pytest_localserver.http.WSGIServer """ server = WSGIServer(application=app) server.start() yield server server.stop()
def hitcounter(): errors = [] hits = {} hitlock = threading.Lock() rv = None def app(environ, start_response): if rv.before_request: rv.before_request() try: path = environ["PATH_INFO"] with hitlock: hits.setdefault(path, 0) hits[path] += 1 if path.startswith("/redirect/"): path = path[len("/redirect"):] start_response("302 Found", [("Location", path)]) return [b""] elif path.startswith("/msdl/"): path = path[len("/msdl/"):] with requests.get( f"https://msdl.microsoft.com/download/symbols/{path}", allow_redirects=False, # test redirects with msdl ) as r: start_response(f"{r.status_code} BOGUS", list(r.headers.items())) return [r.content] elif path.startswith("/respond_statuscode/"): statuscode = int(path.split("/")[2]) start_response(f"{statuscode} BOGUS", []) return [b""] elif path.startswith("/garbage_data/"): start_response("200 OK", []) return [b"bogus"] else: raise AssertionError("Bad path: {}".format(path)) except Exception as e: errors.append(e) start_response("500 Internal Server Error", []) return [b"error"] server = WSGIServer(application=app, threaded=True) server.start() rv = HitCounter(url=server.url, hits=hits) yield rv server.stop() for error in errors: raise error
def flask_wsgi_server(request, flask_app, zuqa_client): server = WSGIServer(application=flask_app) apm_client = ZUQA(app=flask_app, client=zuqa_client) flask_app.apm_client = apm_client server.start() try: yield server finally: server.stop() apm_client.client.close()
def mock_cloud_nossl(): """A Mock iotile.cloud instance for testing without ssl.""" cloud = MockIOTileCloud() server = WSGIServer(application=cloud) server.start() domain = server.url yield domain, cloud cloud.reset() server.stop()
def mock_cloud(): """A Mock iotile.cloud instance for testing with ssl.""" cloud = MockIOTileCloud() # Generate a new fake, unverified ssl cert for this server server = WSGIServer(application=cloud, ssl_context="adhoc") server.start() domain = server.url yield domain, cloud cloud.reset() server.stop()
def pypi_base(): """A Mock travis instance.""" travis = MockPyPI() # Generate a new fake, unverified ssl cert for this server server = WSGIServer(application=travis) server.start() url = server.url yield travis, url server.stop()
class BaseTestServer(abc.ABC): """ A pytest-localserver server which allows you to customise it's responses. Parameters ---------- callback A callable with signature ``(request_number, environ, start_response)``. If the callback returns anything other than `None` it is assumed that the callback has handled the WSGI request. If the callback returns `None` then `default_request_handler` is returned which will handle the WSGI request. """ def __init__(self, callback=None): self.requests = [] self.server = WSGIServer(application=self.request_handler) self.callback = callback self.request_number = 0 def callback_handler(self, environ, start_response): if self.callback is not None: return self.callback(self.request_number, environ, start_response) def request_handler(self, environ, start_response): self.requests.append(environ) callback_return = self.callback_handler(environ, start_response) self.request_number += 1 if callback_return: return callback_return return self.default_request_handler(environ, start_response) @abc.abstractmethod def default_request_handler(self, environ, start_response): return def start_server(self): self.server.start() def stop_server(self): self.server.stop() @property def url(self): return self.server.url
def feriennet_app_url(request, feriennet_app): feriennet_app.print_exceptions = True server = WSGIServer(application=feriennet_app) server.start() yield server.url server.stop()
def testserver(): server = WSGIServer(application=application) server.start() yield server server.stop()
class HitCounter: """A simple WSGI app which will count the number of times a URL path is served. Several URL paths are recognised: `/redirect/{tail}`: This redirects to `/{tail}`. `/msdl/{tail}`: This proxies the request to https://msdl.microsoft.com/download/symbols/{tail}. `/respond_statuscode/{num}`: returns and empty response with the given status code. `/garbage_data/{tail}`: returns 200 OK with some garbage data in the response body. Any other request will return 500 Internal Server Error and will be stored in self.errors. This object itself is a context manager, when entered the WSGI server will start serving, when exited it will stop serving. Attributes: :ivar url: The URL to reach the server, only available while the server is running. :ivar hits: Dictionary of URL paths to hit counters. :ivar before_request: Can be optionally set to execute a function before the request is handled. """ def __init__(self): self.url = None self.hits = collections.defaultdict(lambda: 0) self.before_request = None self._lock = threading.Lock() self.errors = [] self._server = WSGIServer(application=self._app, threaded=True) def __enter__(self): self._server.start() self.url = self._server.url def __exit__(self, exc_type, exc_val, exc_tb): self._server.stop() self.url = None def _app(self, environ, start_response): """The WSGI app.""" if self.before_request: self.before_request() try: path = environ["PATH_INFO"] with self._lock: self.hits[path] += 1 body = self._handle_path(path, start_response) except Exception as e: self.errors.append(e) start_response("500 Internal Server Error", []) return [b"error"] else: return body @staticmethod def _handle_path(path, start_response): if path.startswith("/redirect/"): path = path[len("/redirect"):] start_response("302 Found", [("Location", path)]) return [b""] elif path.startswith("/msdl/"): print(f"got requested: {path}") path = path[len("/msdl/"):] print(f"proxying {path}") with requests.get( f"https://msdl.microsoft.com/download/symbols/{path}", allow_redirects=False, # test redirects with msdl ) as r: print(f"status code: {r.status_code}") start_response(f"{r.status_code} BOGUS", list(r.headers.items())) return [r.content] elif path.startswith("/symbols/"): print(f"got requested: {path}") path = path[len("/symbols/"):] try: filename = os.path.join(os.path.dirname(__file__), "..", "fixtures", "symbols", path) with open(filename, "rb") as f: d = f.read() start_response("200 OK", [("Content-Length", str(len(d)))]) return [d] except IOError: start_response("404 NOT FOUND", []) return [b""] elif path.startswith("/respond_statuscode/"): statuscode = int(path.split("/")[2]) start_response(f"{statuscode} BOGUS", []) return [b""] elif path.startswith("/garbage_data/"): start_response("200 OK", []) return [b"bogus"] else: raise AssertionError("Bad path: {}".format(path))
def pypi_url(pypi_base, monkeypatch): _pypi, url = pypi_base monkeypatch.setenv('PYPI_URL', url) monkeypatch.setenv('PYPI_USER', 'test_user') monkeypatch.setenv('PYPI_PASS', 'test_pass') return url if __name__ == '__main__': slack = MockPyPI() import time logging.basicConfig(level=logging.DEBUG) # Generate a new fake, unverified ssl cert for this server server = WSGIServer(application=slack) server.start() try: url = server.url print("Server running at %s" % url) while True: time.sleep(1.0) except KeyboardInterrupt: pass finally: server.stop()