def testserver(request): """A server that throws a 404 for the second request""" counter = 0 def simple_app(environ, start_response): """Simplest possible WSGI application""" nonlocal counter counter += 1 if counter != 2: status = '200 OK' response_headers = [('Content-type', 'text/plain'), ('Content-Disposition', ('testfile_{}'.format(counter)))] start_response(status, response_headers) return [b'Hello world!\n'] else: status = '404' response_headers = [('Content-type', 'text/plain')] start_response(status, response_headers) return "" server = WSGIServer(application=simple_app) server.start() request.addfinalizer(server.stop) return server
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 wsgi_serve(application): server = WSGIServer(application=application) try: server.start() yield server finally: 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 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 testserver(request): """Defines the testserver funcarg""" import pydash_web server = WSGIServer(application=pydash_web.flask_webapp) server.start() request.addfinalizer(server.stop) return server
def pytest_funcarg__groupme_api_server(request): """ Creates a PyTest functional argument out of Flask WSGI server mockup. """ server = WSGIServer(application=groupme_mock_server.app) server.start() request.addfinalizer(server.stop) return server
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 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 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 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 fake_cloud(request): """Defines the testserver funcarg""" app = FakeCloudServer() server = WSGIServer(application=app, ssl_context=('./tests/server.crt', './tests/server.key')) app.url = server.url server.start() request.addfinalizer(server.stop) return server
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 aws_lambda_runtime(request): app = Flask(__name__) runtime = None @app.before_request def capture_request(): runtime.capture_request(flask_request._get_current_object()) @app.route(f"{BASE_URL}/register", methods=["POST"]) def register(): request_headers = flask_request.headers request_body = flask_request.get_json() print(f"Register request headers: {request_headers}") print(f"Register request body: {request_body}") data = { "functionName": "helloWorld", "functionVersion": "X.X.X", "handler": "lambda_function.lambda_handler", } return (data, HEADERS) @app.route(f"{BASE_URL}/event/next") def next_event(): request_headers = flask_request.headers print(f"Next request headers: {request_headers}") if len(runtime.requests) > SHUTDOWN_MAX: data = { "eventType": "SHUTDOWN", "deadlineMs": 1581512138111, "shutdownReason": "OOPSIES", } else: data = { "eventType": "INVOKE", "deadlineMs": 1581512138111, "requestId": "aws-request-ID", "invokedFunctionArn": "invoked-function-arn", "tracing": { "type": "X-Amzn-Trace-Id", "value": "Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1", }, } return (data, HEADERS) server = WSGIServer(application=app, threaded=True) server.start() request.addfinalizer(server.stop) runtime = AwsLambdaRuntime(server, app) return runtime
def test_server(request, test_app, empty_db): """A uWSGI server fixture with permissions, admin user logged in""" server = WSGIServer(application=test_app.app) server.start() def fin(): print "finalizer test_server" server.stop() request.addfinalizer(fin) return server
def fake_cloud(request): """Defines the testserver funcarg""" app = FakeCloudServer() server = WSGIServer( application=app, ssl_context=(get_full_path("server.crt"), get_full_path("server.key")), ) app.url = server.url server.start() request.addfinalizer(server.stop) return server
def test_server_no_login_real_policy(request, test_app_no_login_real_policy, empty_db): """A uWSGI server fixture with permissions, and no user logged in""" server = WSGIServer(application=test_app_no_login_real_policy.app) server.start() def fin(): print "finalizer test_server" server.stop() request.addfinalizer(fin) return server
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 pytest_funcarg__failingserver(request): """Defines the testserver funcarg""" global request_sent request_sent = False global requested_url requested_url = None server = WSGIServer(application=failing_app) server.start() request.addfinalizer(server.stop) return server
def wms_server(request): """ Run the WMS server for the duration of these tests """ external_url = os.environ.get("SERVER_URL") if external_url: server = generic_obj() server.url = external_url else: server = WSGIServer(application=wms.app) server.start() request.addfinalizer(server.stop) return server
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()
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 zabbixserver(request): def func(): # noqa if getattr(server.app, 'status', None): del server.app.status del server.app.content server = WSGIServer(application=zabbix_fake_app) server.start() request.addfinalizer(server.stop) request._addfinalizer(func, scope='function') def serve_content(self, content, status=200): # noqa self.app.content = content self.app.status = status server.serve_content = partial(serve_content, server) return server
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 http_nlg(request): http_server = WSGIServer(application=nlg_app()) http_server.start() request.addfinalizer(http_server.stop) return http_server.url
def testserver(): server = WSGIServer(application=application) server.start() yield server server.stop()
def http_app(request, core_server): http_server = WSGIServer(application=core_server) http_server.start() request.addfinalizer(http_server.stop) return http_server.url
def fake_receiver(request): """Defines the testserver funcarg""" server = WSGIServer(application=fake_receiver_app) server.start() request.addfinalizer(server.stop) return server
def mini_sentry(request): app = Flask(__name__) app.debug = True sentry = None authenticated_relays = {} def is_trusted(relay_id, project_config): if authenticated_relays[relay_id].get("internal", False): return True if not project_config: return False return relay_id in project_config["config"]["trustedRelays"] def get_error_message(data): exceptions = data.get("exception", {}).get("values", []) exc_msg = (exceptions[0] or {}).get("value") message = data.get("message", {}).get("formatted") return exc_msg or message or "unknown error" @app.before_request def count_hits(): # Consume POST body even if we don't like this request # to no clobber the socket and buffers _ = flask_request.data if flask_request.url_rule: sentry.hit(flask_request.url_rule.rule) @app.route("/api/0/relays/register/challenge/", methods=["POST"]) def get_challenge(): relay_id = flask_request.json["relay_id"] public_key = flask_request.json["public_key"] version = flask_request.json["version"] assert relay_id == flask_request.headers["x-sentry-relay-id"] if relay_id not in sentry.known_relays: abort(403, "unknown relay") if version != CURRENT_VERSION: abort(403, "outdated version") authenticated_relays[relay_id] = sentry.known_relays[relay_id] return jsonify({"token": "123", "relay_id": relay_id}) @app.route("/api/0/relays/register/response/", methods=["POST"]) def check_challenge(): relay_id = flask_request.json["relay_id"] assert relay_id == flask_request.headers["x-sentry-relay-id"] assert relay_id in authenticated_relays return jsonify({"relay_id": relay_id}) @app.route("/api/666/envelope/", methods=["POST"]) def store_internal_error_event(): envelope = Envelope.deserialize(flask_request.data) event = envelope.get_event() if event is not None: error = AssertionError("Relay sent us event: " + get_error_message(event)) sentry.test_failures.append(("/api/666/envelope/", error)) return jsonify({"event_id": uuid.uuid4().hex}) @app.route("/api/42/envelope/", methods=["POST"]) def store_event(): if flask_request.headers.get("Content-Encoding", "") == "gzip": data = gzip.decompress(flask_request.data) else: abort(406, "Relay should always compress store requests") assert (flask_request.headers.get( "Content-Type") == "application/x-sentry-envelope" ), "Relay sent us non-envelope data to store" envelope = Envelope.deserialize(data) sentry.captured_events.put(envelope) return jsonify({"event_id": uuid.uuid4().hex}) @app.route("/api/<project>/store/", methods=["POST"]) @app.route("/api/<project>/envelope/", methods=["POST"]) def store_event_catchall(project): raise AssertionError(f"Unknown project: {project}") @app.route("/api/0/relays/projectids/", methods=["POST"]) def get_project_ids(): project_ids = {} for public_key in flask_request.json["publicKeys"]: project_ids[public_key] = _get_project_id(public_key, sentry.project_configs) return jsonify(projectIds=project_ids) @app.route("/api/0/relays/projectconfigs/", methods=["POST"]) def get_project_config(): relay_id = flask_request.headers["x-sentry-relay-id"] if relay_id not in authenticated_relays: abort(403, "relay not registered") rv = {} for project_id in flask_request.json["projects"]: project_config = sentry.project_configs[int(project_id)] if is_trusted(relay_id, project_config): rv[project_id] = project_config return jsonify(configs=rv) @app.route("/api/0/relays/publickeys/", methods=["POST"]) def public_keys(): relay_id = flask_request.headers["x-sentry-relay-id"] if relay_id not in authenticated_relays: abort(403, "relay not registered") ids = flask_request.json["relay_ids"] keys = {} relays = {} for id in ids: relay = authenticated_relays[id] if relay: keys[id] = relay["publicKey"] relays[id] = relay return jsonify(public_keys=keys, relays=relays) @app.route("/api/0/relays/outcomes/", methods=["POST"]) def outcomes(): """ Mock endpoint for outcomes. SENTRY DOES NOT IMPLEMENT THIS ENDPOINT! This is just used to verify Relay's batching behavior. """ relay_id = flask_request.headers["x-sentry-relay-id"] if relay_id not in authenticated_relays: abort(403, "relay not registered") outcomes_batch = flask_request.json sentry.captured_outcomes.put(outcomes_batch) return jsonify({}) @app.errorhandler(500) def fail(e): sentry.test_failures.append((flask_request.url, e)) raise e def reraise_test_failures(): if sentry.test_failures: pytest.fail( "{n} exceptions happened in mini_sentry:\n\n{failures}".format( n=len(sentry.test_failures), failures=sentry.format_failures())) # This marker is used by pytest_runtest_call in our conftest.py mark = pytest.mark.extra_failure_checks(checks=[reraise_test_failures]) request.node.add_marker(mark) WSGIRequestHandler.protocol_version = "HTTP/1.1" server = WSGIServer(application=app, threaded=True) server.start() request.addfinalizer(server.stop) sentry = Sentry(server.server_address, app) return sentry
def pytest_funcarg__ratelimited(request): """Defines the testserver funcarg""" server = WSGIServer(application=rate_limiting_app) server.start() request.addfinalizer(server.stop) return server
def test_server(request, test_app): server = WSGIServer(application=test_app.app) server.start() request.addfinalizer(server.stop) return server
def pytest_funcarg__slowserver(request): """Defines the testserver funcarg""" server = WSGIServer(application=slow_app) server.start() request.addfinalizer(server.stop) return server
def mini_sentry(request): app = Flask(__name__) app.debug = True sentry = None authenticated_relays = {} @app.route("/api/0/relays/register/challenge/", methods=["POST"]) def get_challenge(): relay_id = flask_request.json["relay_id"] public_key = flask_request.json["public_key"] authenticated_relays[relay_id] = public_key assert relay_id == flask_request.headers["x-sentry-relay-id"] return jsonify({"token": "123", "relay_id": relay_id}) @app.route("/api/0/relays/register/response/", methods=["POST"]) def check_challenge(): relay_id = flask_request.json["relay_id"] assert relay_id == flask_request.headers["x-sentry-relay-id"] assert relay_id in authenticated_relays return jsonify({"relay_id": relay_id}) @app.route("/api/666/store/", methods=["POST"]) def store_internal_error_event(): sentry.test_failures.append( ("/api/666/store/", AssertionError("Relay sent us event")) ) return jsonify({"event_id": uuid.uuid4().hex}) @app.route("/api/42/store/", methods=["POST"]) def store_event(): if flask_request.headers.get("Content-Encoding", "") == "gzip": data = gzip.decompress(flask_request.data) else: data = flask_request.data sentry.captured_events.put(json.loads(data)) return jsonify({"event_id": uuid.uuid4().hex}) @app.route("/api/<project>/store/", methods=["POST"]) def store_event_catchall(project): raise AssertionError(f"Unknown project: {project}") @app.route("/api/0/relays/projectconfigs/", methods=["POST"]) def get_project_config(): rv = {} for project_id in flask_request.json["projects"]: rv[project_id] = sentry.project_configs[int(project_id)] return jsonify(configs=rv) @app.route("/api/0/relays/publickeys/", methods=["POST"]) def public_keys(): ids = flask_request.json["relay_ids"] rv = {} for id in ids: rv[id] = authenticated_relays[id] return jsonify(public_keys=rv) @app.errorhandler(Exception) def fail(e): sentry.test_failures.append((flask_request.url, e)) raise e @request.addfinalizer def reraise_test_failures(): if sentry.test_failures: raise AssertionError( f"Exceptions happened in mini_sentry: {sentry.test_failures}" ) server = WSGIServer(application=app, threaded=True) server.start() request.addfinalizer(server.stop) sentry = Sentry(server.server_address, app) return sentry