async def test_ok(self, event_loop, exchange): connection = cabbage.AmqpConnection(hosts=[(HOST, 5672)], loop=event_loop) rpc = cabbage.AsyncAmqpRpc(connection=connection) rpc.callback_exchange = exchange with patch('cabbage.amqp.aioamqp_connect') as mock_connect: mock_connect.return_value = (MockTransport(), MockProtocol()) await rpc.connect() mock_connect.assert_called_once() # check that client is set up correctly: assert isinstance(rpc.channel, aioamqp.channel.Channel ) # actually it's a mock pretending to be a Channel rpc.channel.queue_declare.assert_called_with(exclusive=True) rpc.channel.basic_consume.assert_called_once_with( callback=rpc._on_response, queue_name=rpc.callback_queue) if rpc.callback_exchange != '': rpc.channel.exchange_declare.assert_called_once_with( exchange_name=rpc.callback_exchange, type_name='topic', durable=True) rpc.channel.queue_bind.assert_called_once_with( queue_name=rpc.callback_queue, exchange_name=rpc.callback_exchange, routing_key=rpc.callback_queue) else: rpc.channel.exchange_declare.assert_not_called() rpc.channel.queue_bind.assert_not_called()
async def test_defaults(self, connection): rpc = cabbage.AsyncAmqpRpc(connection=connection) await rpc.connect() assert rpc.channel.queue_declare.call_count == 1 assert rpc.channel.basic_consume.call_count == 1 await rpc.subscribe(request_handler=lambda x: x, queue=SUBSCRIPTION_QUEUE) assert rpc.channel.queue_declare.call_count == 2 assert rpc.channel.basic_consume.call_count == 2 rpc.channel.basic_qos.assert_called_once_with( prefetch_count=rpc.prefetch_count, prefetch_size=0, connection_global=False) rpc.channel.queue_declare.assert_called_with( queue_name=SUBSCRIPTION_QUEUE, durable=True, arguments={ 'x-dead-letter-exchange': 'DLX', 'x-dead-letter-routing-key': 'dlx_rpc' }) # rpc.channel.basic_consume.assert_called_with( # callback=rpc._on_request, queue_name=SUBSCRIPTION_QUEUE) # It is an error to attempt declaring or binding on default exchange: rpc.channel.exchange_declare.assert_not_called() rpc.channel.queue_bind.assert_not_called()
async def test_launch_server(self, connection, number_of_tasks, pending): """ Test for cabbage.AsyncAmqpRpc.stop(). All tasks should execute asynchronously. In process of tests it may be created a big task (pending variable) if compare with others ones. In this case the task should continue the executing after calling the target function """ small_delay = TEST_DELAY * 0.5 big_delay = TEST_DELAY * 3 rpc = cabbage.AsyncAmqpRpc(connection=connection) rpc.shutdown_timeout = TEST_DELAY await rpc.connect() await rpc.subscribe(request_handler=lambda x: x, queue=SUBSCRIPTION_QUEUE) rpc._tasks = [ asyncio.sleep(small_delay) for i in range(number_of_tasks) ] if pending: # a big delay task rpc._tasks.append(asyncio.sleep(big_delay)) await asyncio.sleep(TEST_DELAY) future = asyncio.ensure_future(rpc.stop()) await asyncio.sleep(TEST_DELAY) # if self._tasks contains a big delay task, the operation shouldn't be done if pending: await asyncio.sleep(big_delay) assert future.done()
async def test_amqp_defaults(self, connection): """Test that broker defaults (empty queue, empty exchange) are handled well.""" rpc = cabbage.AsyncAmqpRpc(connection=connection) await rpc.connect() assert rpc.channel.queue_declare.call_count == 1 assert rpc.channel.basic_consume.call_count == 1 await rpc.subscribe(request_handler=lambda x: x, exchange='', queue='') assert rpc.channel.queue_declare.call_count == 2 assert rpc.channel.basic_consume.call_count == 2 rpc.channel.basic_qos.assert_called_once_with( prefetch_count=rpc.prefetch_count, prefetch_size=0, connection_global=False) rpc.channel.queue_declare.assert_called_with( queue_name='', durable=True, arguments={ 'x-dead-letter-exchange': 'DLX', 'x-dead-letter-routing-key': 'dlx_rpc' }) # rpc.channel.basic_consume.assert_called_with( # callback=rpc._on_request, queue_name=RANDOM_QUEUE) # We are still on default exchange: rpc.channel.exchange_declare.assert_not_called() rpc.channel.queue_bind.assert_not_called()
def __init__(self, loop=None): self.loop = loop or asyncio.get_event_loop() self.connection = cabbage.AmqpConnection(hosts=[(TEST_RABBITMQ_HOST, 5672)], loop=self.loop) self.rpc = cabbage.AsyncAmqpRpc( connection=self.connection, subscriptions=[(self.handle, 'fake', '', 'fake')] ) self.responses = {}
async def test_no_response(self, connection, data, expected_payload): """Check that data is correctly encoded (if needed) and sent.""" rpc = cabbage.AsyncAmqpRpc(connection=connection) await rpc.connect() await rpc.send_rpc(destination=TEST_DESTINATION, data=data, await_response=False) rpc.channel.basic_publish.assert_called_once_with( exchange_name='', routing_key=TEST_DESTINATION, properties={}, payload=expected_payload)
async def test_exception(self, connection, body, expected, is_async): handler = self.request_handler_factory(is_async, fail=True) rpc = cabbage.AsyncAmqpRpc(connection=connection) await rpc.connect() await rpc.handle_rpc(channel=rpc.channel, body=body, envelope=MockEnvelope(), properties=MockProperties(), request_handler=handler) handler.assert_called_once_with(expected) rpc.channel.basic_client_nack.assert_called_once_with( delivery_tag=DELIVERY_TAG) rpc.channel.basic_client_ack.assert_not_called()
async def test_ok(): fake_rpc = FakeRpcServer() fake_rpc.responses['abc'] = '123' await fake_rpc.run() conn = cabbage.AmqpConnection(hosts=[(TEST_RABBITMQ_HOST, 5672)]) rpc = cabbage.AsyncAmqpRpc(connection=conn) await rpc.run() result = await rpc.send_rpc('fake', data='abc', await_response=True) assert result == '123' await rpc.stop() await fake_rpc.stop()
async def test_not_responding(self, connection, body, expected, is_async): """Handler returns None instead of str/bytes => no response needed.""" handler = self.request_handler_factory(is_async, responding=False, fail=False) rpc = cabbage.AsyncAmqpRpc(connection=connection) await rpc.connect() await rpc.handle_rpc(channel=rpc.channel, body=body, envelope=MockEnvelope(), properties=MockProperties(), request_handler=handler) handler.assert_called_once_with(expected) rpc.channel.basic_client_nack.assert_not_called() rpc.channel.basic_client_ack.assert_called_once_with( delivery_tag=DELIVERY_TAG) rpc.channel.basic_publish.assert_not_called()
async def test_correlation_id(self, connection, correlation_id, expected): """Check that correlation id either matches the custom id or is generated from uuid.""" rpc = cabbage.AsyncAmqpRpc(connection=connection) await rpc.connect() with patch('cabbage.amqp.AsyncAmqpRpc._await_response', return_value=b'response', autospec=True), \ patch('cabbage.amqp.uuid.uuid4', return_value=RESPONSE_CORR_ID): await rpc.send_rpc(destination=TEST_DESTINATION, data='payload', await_response=True, correlation_id=correlation_id) rpc.channel.basic_publish.assert_called_once_with( exchange_name='', routing_key=TEST_DESTINATION, payload=b'payload', properties={ 'reply_to': RANDOM_QUEUE, 'correlation_id': expected })
async def test_ok(self, connection): def request_handler(request): return request rpc = cabbage.AsyncAmqpRpc(connection=connection, queue_params=dict(passive=False, durable=True, exclusive=True, auto_delete=True), exchange_params=dict(type_name='fanout', passive=False, durable=True, auto_delete=True)) await rpc.connect() assert rpc.channel.queue_declare.call_count == 1 assert rpc.channel.basic_consume.call_count == 1 await rpc.subscribe(exchange=TEST_EXCHANGE, queue=SUBSCRIPTION_QUEUE, routing_key=SUBSCRIPTION_KEY, request_handler=request_handler) assert rpc.channel.queue_declare.call_count == 2 assert rpc.channel.basic_consume.call_count == 2 rpc.channel.basic_qos.assert_called_once_with( prefetch_count=rpc.prefetch_count, prefetch_size=0, connection_global=False) rpc.channel.exchange_declare.assert_called_once_with( exchange_name=TEST_EXCHANGE, type_name='fanout', passive=False, durable=True, auto_delete=True) rpc.channel.queue_bind.assert_called_once_with( exchange_name=TEST_EXCHANGE, queue_name=SUBSCRIPTION_QUEUE, routing_key=SUBSCRIPTION_KEY) rpc.channel.queue_declare.assert_called_with( queue_name=SUBSCRIPTION_QUEUE, auto_delete=True, durable=True, exclusive=True, passive=False)
async def test_await_response(self, connection, data, sent_payload, received_payload, expected_result): """Check that data returned by await_response is parsed and returned correctly.""" rpc = cabbage.AsyncAmqpRpc(connection=connection) await rpc.connect() with patch('cabbage.amqp.AsyncAmqpRpc._await_response', return_value=received_payload, autospec=True), \ patch('cabbage.amqp.uuid.uuid4', return_value=RESPONSE_CORR_ID): result = await rpc.send_rpc(destination=TEST_DESTINATION, data=data, await_response=True) assert result == expected_result rpc.channel.basic_publish.assert_called_once_with( exchange_name='', routing_key=TEST_DESTINATION, payload=sent_payload, properties={ 'reply_to': RANDOM_QUEUE, 'correlation_id': RESPONSE_CORR_ID })
async def test_responding(self, connection, body, expected, is_async): handler = self.request_handler_factory(is_async, responding=True, fail=False) rpc = cabbage.AsyncAmqpRpc(connection=connection) await rpc.connect() await rpc.handle_rpc(channel=rpc.channel, body=body, envelope=MockEnvelope(), properties=MockProperties(), request_handler=handler) handler.assert_called_once_with(expected) rpc.channel.basic_client_nack.assert_not_called() rpc.channel.basic_client_ack.assert_called_once_with( delivery_tag=DELIVERY_TAG) rpc.channel.basic_publish.assert_called_once_with( exchange_name='', payload=body, properties={'correlation_id': RESPONSE_CORR_ID}, routing_key=RANDOM_QUEUE)
async def test_ok(self, connection): rpc = cabbage.AsyncAmqpRpc(connection=connection) await rpc.connect() await rpc.unsubscribe(consumer_tag=CONSUMER_TAG) rpc.channel.basic_cancel.assert_called_once_with( consumer_tag=CONSUMER_TAG)
async def rpc(connection): _rpc = cabbage.AsyncAmqpRpc(connection=connection) await _rpc.connect() return _rpc