async def test_instantiate_one_consumer_per_handler_one_handler_registered(
            self):
        """
        Para cada handler registrado, teremos um Consumer. Esse Consumer conseguirá consumir múltiplas
        filas, se necessário.
        """
        app = App(**self.connection_parameters)

        @app.route(["asgard/counts"], vhost="/")
        async def _handler(message):
            return message

        consumers = app._build_consumers()
        self.assertEqual(1, len(consumers))
        self.assertEqual(["asgard/counts"], consumers[0].queue_name)
        self.assertEqual("/", consumers[0].vhost)

        queue_connection_parameters = consumers[0].queue.connection_parameters
        self.assertEqual(self.connection_parameters['host'],
                         queue_connection_parameters['host'])
        self.assertEqual(self.connection_parameters['user'],
                         queue_connection_parameters['login'])
        self.assertEqual(self.connection_parameters['password'],
                         queue_connection_parameters['password'])
        self.assertEqual(self.connection_parameters['prefetch_count'],
                         consumers[0].queue.prefetch_count)
예제 #2
0
    async def test_instantiate_one_consumer_per_handler_multiple_handlers_registered(self):
        app = App(**self.connection_parameters)

        @app.route(["asgard/counts"], vhost="/")
        async def _handler(message):
            return message

        @app.route(["asgard/counts/errors"], vhost="fluentd")
        async def _other_handler(message):
            return message

        consumers = app._build_consumers()
        self.assertEqual(2, len(consumers))

        self.assertEqual(["asgard/counts"], consumers[0].queue_name)
        self.assertEqual("/", consumers[0].vhost)
        queue_connection_parameters = consumers[0].queue.connection_parameters
        self.assertEqual(self.connection_parameters['host'], queue_connection_parameters['host'])
        self.assertEqual(self.connection_parameters['user'], queue_connection_parameters['login'])
        self.assertEqual(self.connection_parameters['password'], queue_connection_parameters['password'])
        self.assertEqual(self.connection_parameters['prefetch_count'], consumers[0].queue.prefetch_count)

        self.assertEqual(["asgard/counts/errors"], consumers[1].queue_name)
        self.assertEqual("fluentd", consumers[1].vhost)
        queue_connection_parameters = consumers[1].queue.connection_parameters
        self.assertEqual(self.connection_parameters['host'], queue_connection_parameters['host'])
        self.assertEqual(self.connection_parameters['user'], queue_connection_parameters['login'])
        self.assertEqual(self.connection_parameters['password'], queue_connection_parameters['password'])
        self.assertEqual(self.connection_parameters['prefetch_count'], consumers[1].queue.prefetch_count)
예제 #3
0
    async def test_raise_if_object_is_not_callable(self):
        app = App()

        class MyHandler:
            pass

        handler = MyHandler()

        with self.assertRaises(TypeError):
            app.route(["/"], type=RouteTypes.HTTP, methods=["GET"])(handler)
예제 #4
0
    async def test_can_registrer_a_callable_as_a_valid_handler(self):
        app = App()

        class MyHandler:
            async def __call__(self, wrapper: RequestWrapper):
                return web.json_response({"OK": True})

        handler = MyHandler()

        app.route(["/"], type=RouteTypes.HTTP, methods=["GET"])(handler)

        async with HttpClientContext(app) as client:
            resp = await client.get("/")
            data = await resp.json()
            self.assertEqual({"OK": True}, data)
    async def test_check_route_registry_full_options(self):
        expected_route = ["/asgard/counts/ok"]
        expected_vhost = "/"
        app = App(**self.connection_parameters)

        @app.route(expected_route,
                   vhost=expected_vhost,
                   options={
                       Options.BULK_SIZE: 1024,
                       Options.BULK_FLUSH_INTERVAL: 120
                   })
        async def _handler(message):
            return 42

        self.assertIsNotNone(app.routes_registry)
        expected_registry_entry = {
            "route": expected_route,
            "handler": _handler,
            "options": {
                "vhost": expected_vhost,
                "bulk_size": 1024,
                "bulk_flush_interval": 120,
                Events.ON_SUCCESS: Actions.ACK,
                Events.ON_EXCEPTION: Actions.REQUEUE,
            }
        }
        self.assertEqual(expected_registry_entry,
                         app.routes_registry[_handler])
        self.assertEqual(42, await app.routes_registry[_handler]['handler']
                         (None))
예제 #6
0
    async def test_it_uses_the_connection_provided_by_the_route_if_one_exists(
            self):
        conn = AMQPConnection(
            hostname="127.0.0.1",
            username="******",
            password="******",
            prefetch=1024,
        )
        app = App(connections=[])

        @app.route(
            routes=["a_queue_name"],
            type=RouteTypes.AMQP_RABBITMQ,
            options={"connection": conn},
        )
        async def mock_handler(*args, **kwargs):
            pass

        MockedConsumer = Mock(return_value=Mock(spec=Consumer, queue=Mock()))
        with patch("asyncworker.signals.handlers.rabbitmq.Consumer",
                   MockedConsumer):
            await self.signal_handler.startup(app)

        MockedConsumer.assert_called_once_with(
            route_info=ANY,
            host=conn.hostname,
            username=conn.username,
            password=conn.password,
            prefetch_count=conn.prefetch,
        )
    async def test_check_route_registry_full_options(self):
        expected_routes = ["/asgard/counts/ok"]
        expected_vhost = "/"
        app = App(**self.connection_parameters)

        @app.route(
            expected_routes,
            type=RouteTypes.AMQP_RABBITMQ,
            vhost=expected_vhost,
            options={Options.BULK_SIZE: 1024, Options.BULK_FLUSH_INTERVAL: 120},
        )
        async def _handler(message):
            return 42

        self.assertIsNotNone(app.routes_registry)
        expected_registry_entry = {
            "type": RouteTypes.AMQP_RABBITMQ,
            "routes": expected_routes,
            "handler": _handler,
            "default_options": {},
            "vhost": expected_vhost,
            "options": {
                "bulk_size": 1024,
                "bulk_flush_interval": 120,
                Events.ON_SUCCESS: Actions.ACK,
                Events.ON_EXCEPTION: Actions.REQUEUE,
            },
        }
        route = app.routes_registry.route_for(_handler)
        self.assertEqual(expected_registry_entry, route)
        self.assertEqual(42, await route["handler"](None))
예제 #8
0
 def __init__(  # nosec
     self,
     hostname: str = "127.0.0.1",
     username: str = "guest",
     password: str = "guest",
     prefetch: int = 10,
     connection_name: str = "default",
 ):
     self.__connection = AMQPConnection(
         name=connection_name,
         hostname=hostname,
         username=username,
         password=password,
         prefetch=prefetch
     )
     self.__app = App(connections=[self.__connection])
 def setUp(self):
     self.queue_mock = Mock(connection=Mock(is_connected=True),
                            spec=JsonQueue)
     self.logger_mock = CoroutineMock(info=CoroutineMock(),
                                      debug=CoroutineMock(),
                                      error=CoroutineMock())
     self.connection_parameters = ("127.0.0.1", "guest", "guest", 1024)
     self.one_route_fixture = {
         "routes": ["/asgard/counts/ok"],
         "handler": _handler,
         "vhost": "/",
         "options": {
             "bulk_size": 1,
             "bulk_flush_interval": 60,
             Events.ON_SUCCESS: Actions.ACK,
             Events.ON_EXCEPTION: Actions.REQUEUE,
         },
     }
     self.app = App(
         **{
             "host": "127.0.0.1",
             "user": "******",
             "password": "******",
             "prefetch_count": 1024,
         })
     self.mock_message = self._make_msg()
     mock.patch.object(conf, "settings",
                       mock.Mock(FLUSH_TIMEOUT=0.1)).start()
예제 #10
0
 def setUp(self):
     self.queue_mock = Mock(
         connection=Mock(has_channel_ready=Mock(return_value=True)),
         spec=JsonQueue,
     )
     self.logger_mock = CoroutineMock(info=CoroutineMock(),
                                      debug=CoroutineMock(),
                                      error=CoroutineMock())
     self.connection_parameters = ("127.0.0.1", "guest", "guest", 1024)
     self.one_route_fixture = {
         "routes": ["/asgard/counts/ok"],
         "handler": _handler,
         "vhost": "/",
         "options": {
             "bulk_size": 1,
             "bulk_flush_interval": 1,
             Events.ON_SUCCESS: Actions.ACK,
             Events.ON_EXCEPTION: Actions.REQUEUE,
         },
     }
     self.connection = AMQPConnection(
         hostname="127.0.0.1",
         username="******",
         password="******",
         prefetch=1024,
     )
     self.app = App(connections=[self.connection])
     self.mock_message = self._make_msg()
     mock.patch.object(conf, "settings",
                       mock.Mock(FLUSH_TIMEOUT=0.1)).start()
예제 #11
0
    async def test_instantiate_one_consumer_per_handler_one_handler_registered(
        self
    ):
        """
        Para cada handler registrado, teremos um Consumer. Esse Consumer conseguirá consumir múltiplas
        filas, se necessário.
        """
        app = App(connections=[self.connection])

        @app.route(["asgard/counts"], type=RouteTypes.AMQP_RABBITMQ, vhost="/")
        async def _handler(message):
            return message

        await app.startup()
        consumers = app[RouteTypes.AMQP_RABBITMQ]["consumers"]
        self.assertEqual(1, len(consumers))
        self.assertEqual(["asgard/counts"], consumers[0].queue_name)
        self.assertEqual("/", consumers[0].vhost)

        queue_connection_parameters = consumers[
            0
        ].queue.connection.connection_parameters
        self.assertEqual(
            self.connection.hostname, queue_connection_parameters["host"]
        )
        self.assertEqual(
            self.connection.username, queue_connection_parameters["login"]
        )
        self.assertEqual(
            self.connection.password, queue_connection_parameters["password"]
        )
        self.assertEqual(
            self.connection.prefetch, consumers[0].queue.prefetch_count
        )
예제 #12
0
    async def test_check_route_registry_add_headers_per_handler(self):
        expected_route = ["/v2/events", "/other/path"]
        aditional_headers = {"X-Other-Header": "X-Other-Value"}
        app = App(connections=[SSEConnection(**self.connection_parameters)])

        @app.route(
            expected_route,
            type=RouteTypes.SSE,
            headers=aditional_headers,
            options={
                Options.BULK_SIZE: 1024,
                Options.BULK_FLUSH_INTERVAL: 120
            },
        )
        async def _handler(message):
            return 42

        routes = app.routes_registry.sse_routes
        self.assertIsNotNone(routes)
        expected_registry_entry = SSERoute(
            type=RouteTypes.SSE,
            routes=expected_route,
            handler=_handler,
            options={
                "bulk_size": 1024,
                "bulk_flush_interval": 120,
                "headers": {
                    **self.default_headers,
                    **aditional_headers
                },
            },
        )
        self.assertEqual(expected_registry_entry, routes[0])
        self.assertEqual(42, await routes[0]["handler"](None))
예제 #13
0
    async def test_check_route_registry_full_options(self):
        expected_route = ["/v2/events", "/other/path"]
        app = App(connections=[SSEConnection(**self.connection_parameters)])

        @app.route(
            expected_route,
            type=RouteTypes.SSE,
            options={
                Options.BULK_SIZE: 1024,
                Options.BULK_FLUSH_INTERVAL: 120
            },
        )
        async def _handler(message):
            return 42

        routes = app.routes_registry.sse_routes
        self.assertIsNotNone(routes)
        expected_registry_entry = {
            "type": RouteTypes.SSE,
            "routes": expected_route,
            "handler": _handler,
            "options": {
                "bulk_size": 1024,
                "bulk_flush_interval": 120,
                "headers": self.default_headers,
            },
        }
        self.assertEqual(expected_registry_entry, routes[0])
        self.assertEqual(42, await routes[0]["handler"](None))
        self.assertEqual(self.logger, app.logger)
예제 #14
0
    async def test_user_can_use_metrics_endpoint_if_default_is_renamed(self):
        """
        Se estivermos com o endpoint de métricas habilitado mas o path foi trocado
        então devemos poder registrar um endpoint com o valor default do path de metricas

        Não é o melhor jeito de fazer o teste mas como o settings é instanciado no nível do módulo
        não temos muito com controlar o desencadear dos imports então por isso preciso ficar substiuindo
        os módulos para que o "novo" settings (após reload()) surta efeito.
        """
        from asyncworker import routes

        app = App()

        with mock.patch.dict(
                os.environ,
                ASYNCWORKER_METRICS_ROUTE_PATH="/asyncworker-metrics"):

            reload(conf)
            with mock.patch.object(routes, "conf", conf):

                @app.http.get(["/metrics"])
                async def _h():
                    return web.json_response({})

                async with HttpClientContext(app) as client:
                    resp = await client.get("/metrics")
                    self.assertEqual(HTTPStatus.OK, resp.status)
예제 #15
0
    async def test_consume_one_message_app_with_multiple_connections(self):
        conn = AMQPConnection(hostname="127.0.0.1",
                              username="******",
                              password="******",
                              prefetch=1)
        conn_2 = AMQPConnection(
            hostname="127.0.0.1:5673",
            username="******",
            password="******",
            prefetch=1,
        )
        await conn["/"].connection._connect()
        await conn["/"].connection.channel.queue_declare("queue")
        await conn["/"].put(data={"num": 42}, routing_key="queue")

        app = App(connections=[conn, conn_2])

        @app.amqp.consume(["queue"], connection=conn)
        async def handler(msgs):
            global message_processed_multiple_connections
            message_processed_multiple_connections = True

        await app.startup()
        await asyncio.sleep(1)
        await app.shutdown()
        self.assertTrue(message_processed_multiple_connections)
예제 #16
0
    async def test_patched_startup_has_cors_configured(self):

        app = App()
        app._on_startup.clear()
        app._on_startup.append(patched_startup)

        @app.route(["/new-path"], type=RouteTypes.HTTP, methods=["GET"])
        async def handler(r):
            return web.json_response({})

        client = ClientSession()
        await app.startup()
        resp = await client.get(
            f"http://{settings.HTTP_HOST}:{settings.HTTP_PORT}/new-path",
            headers={"Origin": "server.com"},
        )
        self.assertEqual(HTTPStatus.OK, resp.status)

        self.assertTrue(
            "Access-Control-Allow-Origin" in resp.headers,
            "Header do CORS não encontrado",
        )
        self.assertEqual("server.com",
                         resp.headers.get("Access-Control-Allow-Origin"))
        await app.shutdown()
 async def setUp(self):
     self.queue_name = "test"
     self.connection = AMQPConnection(hostname="127.0.0.1",
                                      username="******",
                                      password="******",
                                      prefetch=1)
     self.app = App(connections=[self.connection])
예제 #18
0
    async def test_register_action_on_success(self):
        app = App(**self.connection_parameters)
        @app.route(["my-queue"], options = {Events.ON_SUCCESS: Actions.REJECT})
        async def _handler(message):
            return 42

        self.assertIsNotNone(app.routes_registry)
        self.assertEqual(Actions.REJECT, app.routes_registry[_handler]['options'][Events.ON_SUCCESS])
예제 #19
0
    async def test_startup_registers_one_connection_per_vhost_into_app_state(
            self, register):
        conn = AMQPConnection(
            hostname="127.0.0.1",
            username="******",
            password="******",
            prefetch=1024,
        )
        app = App(connections=[conn])
        app.routes_registry = self.routes_registry
        await self.signal_handler.startup(app)

        self.assertIn(conn, app.connections)
        register.assert_has_calls([
            call(consumer.queue)
            for consumer in app[RouteTypes.AMQP_RABBITMQ]["consumers"]
        ])
예제 #20
0
    async def test_startup_registers_one_connection_per_vhost_into_app_state(
            self, register):
        app = App(
            host="127.0.0.1",
            user="******",
            password="******",
            prefetch_count=1024,
        )
        app.routes_registry = self.routes_registry
        await self.signal_handler.startup(app)

        self.assertIsInstance(app[RouteTypes.AMQP_RABBITMQ]["connection"],
                              AMQPConnection)
        register.assert_has_calls([
            call(consumer.queue)
            for consumer in app[RouteTypes.AMQP_RABBITMQ]["consumers"]
        ])
예제 #21
0
    async def test_register_action_on_exception(self):
        app = App(**self.connection_parameters)
        @app.route(["my-queue"], options = {Events.ON_EXCEPTION: Actions.ACK})
        async def _handler(message):
            return 42

        self.assertIsNotNone(app.routes_registry)
        self.assertEqual(Actions.ACK, app.routes_registry[_handler]['options'][Events.ON_EXCEPTION])
 async def test_app_receives_queue_connection(self):
     app = App(host="127.0.0.1",
               user="******",
               password="******",
               prefetch_count=1024)
     self.assertEqual("127.0.0.1", app.host)
     self.assertEqual("guest", app.user)
     self.assertEqual("guest", app.password)
     self.assertEqual(1024, app.prefetch_count)
예제 #23
0
    async def test_test_register_default_actions(self):
        app = App(**self.connection_parameters)
        @app.route(["my-queue"])
        async def _handler(message):
            return 42

        self.assertIsNotNone(app.routes_registry)
        self.assertEqual(Actions.ACK, app.routes_registry[_handler]['options'][Events.ON_SUCCESS])
        self.assertEqual(Actions.REQUEUE, app.routes_registry[_handler]['options'][Events.ON_EXCEPTION])
예제 #24
0
    async def test_instantiate_one_consumer_per_handler_multiple_handlers_registered_bla(
        self
    ):
        app = App(connections=[self.connection])

        @app.route(["asgard/counts"], type=RouteTypes.AMQP_RABBITMQ, vhost="/")
        async def _handler(message):
            return message

        @app.route(
            ["asgard/counts/errors"],
            type=RouteTypes.AMQP_RABBITMQ,
            vhost="fluentd",
        )
        async def _other_handler(message):
            return message

        await app.startup()
        consumers = app[RouteTypes.AMQP_RABBITMQ]["consumers"]
        self.assertEqual(2, len(consumers))

        self.assertEqual(["asgard/counts"], consumers[0].queue_name)
        self.assertEqual("/", consumers[0].vhost)
        queue_connection_parameters = consumers[
            0
        ].queue.connection.connection_parameters
        self.assertEqual(
            self.connection.hostname, queue_connection_parameters["host"]
        )
        self.assertEqual(
            self.connection.username, queue_connection_parameters["login"]
        )
        self.assertEqual(
            self.connection.password, queue_connection_parameters["password"]
        )
        self.assertEqual(
            self.connection.prefetch, consumers[0].queue.prefetch_count
        )

        self.assertEqual(["asgard/counts/errors"], consumers[1].queue_name)
        self.assertEqual("fluentd", consumers[1].vhost)
        queue_connection_parameters = consumers[
            1
        ].queue.connection.connection_parameters
        self.assertEqual(
            self.connection.hostname, queue_connection_parameters["host"]
        )
        self.assertEqual(
            self.connection.username, queue_connection_parameters["login"]
        )
        self.assertEqual(
            self.connection.password, queue_connection_parameters["password"]
        )
        self.assertEqual(
            self.connection.prefetch, consumers[1].queue.prefetch_count
        )
예제 #25
0
    async def test_register_bulk_flush_timeout(self):
        expected_bulk_flush_interval = 120
        app = App(**self.connection_parameters)
        @app.route(["my-queue"], options={Options.BULK_FLUSH_INTERVAL: expected_bulk_flush_interval})
        async def _handler(message):
            return 42

        self.assertIsNotNone(app.routes_registry)
        self.assertEqual(expected_bulk_flush_interval, app.routes_registry[_handler]['options']['bulk_flush_interval'])
        self.assertEqual(42, await app.routes_registry[_handler]['handler'](None))
예제 #26
0
    async def test_raise_if_handler_is_not_coroutine(self):
        app = App()

        with self.assertRaises(TypeError) as err:

            @app.route(["/"], type=RouteTypes.HTTP, methods=["GET"])
            def handler(wrapper: RequestWrapper):
                return web.json_response({"OK": True})

        self.assertTrue("handler must be a coroutine" in err.exception.args[0])
예제 #27
0
    async def test_raise_if_handler_is_sync(self):
        app = App()

        with self.assertRaises(TypeError) as err:

            @app.amqp.consume(["/"])
            def handler():
                pass

        self.assertTrue("handler must be async" in err.exception.args[0])
예제 #28
0
    async def test_raise_if_handler_is_not_coroutine_new_decorator(self):
        app = App()

        with self.assertRaises(TypeError) as err:

            @app.http.get(["/"])
            def handler(wrapper: RequestWrapper):
                return web.json_response({"OK": True})

        self.assertTrue("handler must be async" in err.exception.args[0])
예제 #29
0
    async def test_register_default_bulk_size_and_default_bulk_flush_timeout(self):
        app = App(**self.connection_parameters)
        @app.route(["my-queue"])
        async def _handler(message):
            return 42

        self.assertIsNotNone(app.routes_registry)
        self.assertEqual(Defaultvalues.BULK_SIZE, app.routes_registry[_handler]['options']['bulk_size'])
        self.assertEqual(Defaultvalues.BULK_FLUSH_INTERVAL, app.routes_registry[_handler]['options']['bulk_flush_interval'])
        self.assertEqual(42, await app.routes_registry[_handler]['handler'](None))
예제 #30
0
    async def test_raise_if_object_is_not_callable_new_decorator(self):
        app = App()

        class MyHandler:
            pass

        handler = MyHandler()

        with self.assertRaises(TypeError):
            app.http.get(["/"])(handler)