def test_public_routes_class_view(self): insanic_application = Insanic("test2") class ClassView(InsanicView): @public_facing def get(self, request, *args, **kwargs): return {"method": "get"} @public_facing def post(self, request, *args, **kwargs): return {"method": "post"} def put(self, request, *args, **kwargs): return {"method": "put"} insanic_application.add_route( handler=ClassView.as_view(), uri="/insanic/", name="ClassView", strict_slashes=True, ) routes = insanic_application.router.routes_public assert "^/insanic/$" in routes assert sorted(routes["^/insanic/$"]["public_methods"]) == sorted( ["GET", "POST"])
def test_throttle(): app = Insanic("test") wait_time = 1000 from insanic.throttles import BaseThrottle class ForceThrottle(BaseThrottle): async def allow_request(self, *args, **kwargs): return False def wait(self, *args, **kwargs): return wait_time class DummyView(InsanicView): authentication_classes = () permission_classes = () throttle_classes = (ForceThrottle, ) def get(self, request): return json({"hello": "bye"}) app.add_route(DummyView.as_view(), "/") request, response = app.test_client.get("/") assert response.status == status.HTTP_429_TOO_MANY_REQUESTS assert str(wait_time) in response.json["description"]
def test_permission_denied(test_user_token_factory, user_level, monkeypatch): app = Insanic("test") response_body = {"insanic": "Gotta go insanely fast!"} class DummyView(InsanicView): authentication_classes = (authentication.JSONWebTokenAuthentication, ) permission_classes = (permissions.IsAdminUser, ) def get(self, request): return json(response_body) app.add_route(DummyView.as_view(), "/") user, token = test_user_token_factory(level=user_level, return_with_user=True) request, response = app.test_client.get("/", headers={ "Authorization": token, "x-consumer-username": user.id }) assert response.status == status.HTTP_403_FORBIDDEN assert (GlobalErrorCodes(response.json["error_code"]["value"]) == GlobalErrorCodes.permission_denied)
def test_sanic_error_handling(sanic_exception): app = Insanic("test") class ContentRange: total = 120 if sanic_exception.status_code == 416: raised_exception = sanic_exception("a", ContentRange()) elif sanic_exception.status_code == 405: raised_exception = sanic_exception("a", "HEAD", ["GET"]) else: raised_exception = sanic_exception("a") class DummyView(InsanicView): authentication_classes = () permission_classes = () def get(self, request): raise raised_exception app.add_route(DummyView.as_view(), "/") request, response = app.test_client.get("/") assert response.status == raised_exception.status_code assert response.json["description"] == "a" if hasattr(raised_exception, "headers"): for k, v in raised_exception.headers.items(): if (raised_exception.status_code == 405 and k.lower() == "content-length"): continue assert k.lower() in response.headers.keys() assert str(v) == response.headers[k]
def _init_event_polling(self, app: Insanic) -> None: """ Initializes for event polling. Actions: - Checks if global arn exists - Checks if filters are 0 to avoid receiving all messages - Loads iniesta configs - Attaches listeners - Checks if queue exists (initialize) - Checks subscriptions - Checks permissions """ self.load_config(app.config) if not app.config.INIESTA_DRY_RUN: # check if global arn exists self.check_global_arn(app.config) # check if filters are 0 if len(app.config.INIESTA_SQS_CONSUMER_FILTERS) == 0: raise ImproperlyConfigured( "INIESTA_SQS_CONSUMER_FILTERS is an empty list. " "Please specify events to receive!") listener = IniestaListener() app.register_listener(listener.after_server_start_event_polling, "after_server_start") app.register_listener(listener.before_server_stop_stop_polling, "before_server_stop")
def test_helper_method(self): """ Checks if the port is set in the settings. :return: """ app = Insanic("taels") app._helper(port=10000) assert settings.SERVICE_PORT == 10000
def _create_app_with_authentication(self, authentication_class): app = Insanic("test") class TokenView(InsanicView): authentication_classes = (authentication_class, ) @public_facing def get(self, request, *args, **kwargs): return json({}) app.add_route(TokenView.as_view(), "/") return app
def test_version_configuration_not_enforced(self): """ When version configuration is not enforced. :return: """ # ENFORCE_APPLICATION_VERSION should be False right now app = Insanic("good") assert app.config.APPLICATION_VERSION == "UNKNOWN" app = Insanic("good", version="1.1.1") assert app.config.APPLICATION_VERSION == "1.1.1"
def test_not_found(): app = Insanic("test") class DummyView(InsanicView): authentication_classes = () def get(self, request): return json({}) app.add_route(DummyView.as_view(), "/") request, response = app.test_client.get("/aaaa") assert response.status == status.HTTP_404_NOT_FOUND
def init_app(cls, app: Insanic) -> None: """ The initial entrypoint to initialize Infuse. #. Loads Infuse specific configurations #. Attaches a listener to change state to value defined in :code:`INFUSE_INITIAL_STATE`. #. Patches the Service object that handles circuit state when sending requests to other services. """ cls.load_config(app) cls.attach_listeners(app) patch() if hasattr(app, "plugin_initialized"): app.plugin_initialized("infuse", cls)
def test_no_depth(self): app = Insanic("ping") request, response = app.test_client.get("/ping/ping/") assert response.status_code == 200 assert "response" in response.json assert "process_time" in response.json
def test_view_only_json_authentication(): app = Insanic("test") class DummyView(InsanicView): authentication_classes = (authentication.JSONWebTokenAuthentication, ) def get(self, request): return json({}) app.add_route(DummyView.as_view(), "/") request, response = app.test_client.get("/") assert response.status == status.HTTP_401_UNAUTHORIZED assert (GlobalErrorCodes(response.json["error_code"]["value"]) == GlobalErrorCodes.authentication_credentials_missing)
def test_version_configuration_from_settings(self, monkeypatch): """ Tests version precedence. :param monkeypatch: :return: """ monkeypatch.setattr(settings, "ENFORCE_APPLICATION_VERSION", True) monkeypatch.setattr(settings, "APPLICATION_VERSION", "1.1.1") app = Insanic("good") assert app.config.APPLICATION_VERSION == "1.1.1" assert settings.APPLICATION_VERSION == "1.1.1" app = Insanic("good", version="2.2.2") assert app.config.APPLICATION_VERSION == "2.2.2" assert settings.APPLICATION_VERSION == "2.2.2"
def test_dont_initialize_middlewares(self): """ Same condition as test_initialize_middlewares. :return: """ app = Insanic("good", initialize_insanic_middlewares=False) initialized_middleware_list = self.get_attached_middlewares(app) assert initialized_middleware_list == set()
def test_view_invalid_method(): app = Insanic("test") response_body = {"insanic": "Gotta go insanely fast!"} class DummyView(InsanicView): authentication_classes = () permission_classes = () def get(self, request): return json(response_body) app.add_route(DummyView.as_view(), "/") request, response = app.test_client.post("/") assert response.status == status.HTTP_405_METHOD_NOT_ALLOWED assert (GlobalErrorCodes(response.json["error_code"]["value"]) == GlobalErrorCodes.method_not_allowed)
def test_version_configuration_enforced(self, monkeypatch): """ Test when version is enforced. Also checks any fallbacks. :param monkeypatch: :return: """ monkeypatch.setattr(settings, "ENFORCE_APPLICATION_VERSION", True) with pytest.raises(ImproperlyConfigured): Insanic("bad") with pytest.raises(ImproperlyConfigured): Insanic("bad", version=None) app = Insanic("good", version="2.2.2") assert app.config.APPLICATION_VERSION == "2.2.2" assert settings.APPLICATION_VERSION == "2.2.2"
def _init_producer(self, app: Insanic) -> None: """ Initializes the application with only SNS producing capabilities. Checks if the global sns arn exists. If not fails running of application. Actions: - Checks if global arn is valid - Loads iniesta configs """ self.load_config(app.config) if not app.config.INIESTA_DRY_RUN: # check if global arn exists self.check_global_arn(app.config) listener = IniestaListener() app.register_listener(listener.after_server_start_producer_check, "after_server_start")
def test_insanic_dont_attach_monitor_endpoints(self): """ Tests to skip monitor endpoints :return: """ app = Insanic("taels", attach_monitor_endpoints=False) assert app.metrics is empty assert app.blueprints == {}
def _init_queue_polling(self, app: Insanic) -> None: """ Basic sqs queue polling without the need for checking subscriptions. Actions: - Loads iniesta configs - Attaches listeners to check if queue exists """ self.load_config(app.config) if not app.config.INIESTA_DRY_RUN: listener = IniestaListener() app.register_listener( listener.after_server_start_start_queue_polling, "after_server_start", ) app.register_listener(listener.before_server_stop_stop_polling, "before_server_stop")
def test_view_invalid_method(): app_name = "test" app = Insanic(app_name) request, response = app.test_client.get(f"/{app_name}/health/") assert response.status == status.HTTP_200_OK assert response.json is not None assert response.json["service"] == app_name assert response.json["status"] == "OK" assert response.json["insanic_version"] == __version__
def test_insanic_app_basic_initialization(self): """ Just basic Insanic initialization :return: """ app = Insanic("taels") assert app.initialized_plugins == {} assert isinstance(app.config, LazySettings) assert app.config.SERVICE_NAME == "taels" assert app.config.APPLICATION_VERSION == "UNKNOWN" assert "monitor" in app.blueprints
def insanic_application( self, set_global_topic_arn, set_filters, monkeypatch, ): monkeypatch.setattr( settings, "INIESTA_INITIALIZATION_TYPE", ["EVENT_POLLING", "SNS_PRODUCER"], raising=False, ) app = Insanic("xavi") Iniesta.init_app(app) yield app
def test_depth_connection_doesnt_exist(self, monkeypatch): registry.reset() monkeypatch.setattr(settings, "SERVICE_CONNECTIONS", ["pong"]) app = Insanic("ping") request, response = app.test_client.get("/ping/ping/", params={"depth": 1}) assert response.status_code == 200 assert "response" in response.json assert "process_time" in response.json assert "response" in response.json assert "pong" in response.json["response"]
def init_app(cls, app: Insanic, recorder: AsyncAWSXRayRecorder = None) -> None: """ Initializes Insanic to use Incendiary. - This loads all default Incendiary configs. - Validates connection information to X-Ray Daemon. - Configures X-Ray SDK Recorder - Attaches middlewares to start stop segments - Replaces :code:`Service` object with :code:`IncendiaryService` to trace interservice communications. - Replaces asyncio task factory. - Patches configured modules. :param app: Your Insanic application/ :param recorder: If you want to use your own recorder. """ # checks to see if tracing can be enabled cls.app = app cls.load_config(app.config) messages = cls._check_prerequisites(app) if len(messages) == 0: global_sdk_config.set_sdk_enabled(True) app.xray_recorder = recorder or xray_recorder cls.setup_middlewares(app) cls.setup_client(app) cls.setup_listeners(app) patch(app.config.INCENDIARY_XRAY_PATCH_MODULES, raise_errors=False) app.plugin_initialized("incendiary", cls) else: cls._handle_error(app, messages) app.config.INCENDIARY_XRAY_ENABLED = False global_sdk_config.set_sdk_enabled(False)
def test_prometheus_metrics(): app_name = "prometheus" app = Insanic(app_name) request, response = app.test_client.get(f"/{app_name}/metrics/") assert response.status == status.HTTP_200_OK assert response.json is None assert "request_count_total" in response.text assert "total_task_count" in response.text assert "active_task_count" in response.text assert "proc_rss_mem_bytes" in response.text assert "proc_rss_mem_perc" in response.text assert "proc_cpu_perc" in response.text
def test_is_admin(test_user_token_factory, user_level): app = Insanic("test") response_body = {"insanic": "Gotta go insanely fast!"} class DummyView(InsanicView): authentication_classes = (authentication.JSONWebTokenAuthentication, ) permission_classes = (permissions.IsAdminUser, ) def get(self, request): return json(response_body) app.add_route(DummyView.as_view(), "/") user, token = test_user_token_factory(level=user_level, return_with_user=True) request, response = app.test_client.get("/", headers={ "Authorization": token, "x-consumer-username": user.id }) assert response.status == status.HTTP_200_OK assert response.json == response_body
def test_insanic_app_config_argument(self): """ Test to make sure the configs get loaded into settings :return: """ class SomeConfig: SOME_CONFIG = "hello" I_STILL_SURVIVE = "!" class SomeOtherConfig: SOME_CONFIG = "bye" Insanic("taels", app_config=(SomeConfig, SomeOtherConfig)) assert settings.SOME_CONFIG == "bye" assert settings.I_STILL_SURVIVE == "!"
def test_initialize_listeners(self) -> None: """ Tests if the default listeners for insanic were initialized :return: """ app = Insanic("good") from insanic import listeners listener_list = set() for attribute in dir(listeners): for listener in LISTENER_TYPES: if attribute.startswith(listener): listener_list.add(attribute) initialized_listener_list = self.get_attached_listeners(app) assert listener_list == initialized_listener_list
def test_json_metrics(): app_name = "test" app = Insanic(app_name) request, response = app.test_client.get(f"/{app_name}/metrics/?json") assert response.status == status.HTTP_200_OK assert response.json is not None assert "total_task_count" in response.json assert "active_task_count" in response.json assert "proc_rss_mem_bytes" in response.json assert "proc_rss_mem_perc" in response.json assert "proc_cpu_perc" in response.json assert "request_count" in response.json assert "timestamp" in response.json assert isinstance(response.json["total_task_count"], int) assert isinstance(response.json["active_task_count"], int) assert isinstance(response.json["proc_rss_mem_bytes"], float) assert isinstance(response.json["proc_rss_mem_perc"], float) assert isinstance(response.json["proc_cpu_perc"], float)
def test_initialize_middlewares(self): """ This may not work in debug mode because of Sanic's `asgi_client` property. Because debug will evaluate all attributes and while evaluating asgi_client, the SanicASGITestClient attaches it's own middleware. :return: """ app = Insanic("good") middleware_list = set() for attrib in dir(insanic_middleware): for middleware in MIDDLEWARE_TYPES: if attrib.startswith(middleware): middleware_list.add(attrib) initialized_middleware_list = self.get_attached_middlewares(app) assert middleware_list == initialized_middleware_list