211 lines
7.5 KiB
Python
211 lines
7.5 KiB
Python
import unittest
|
|
from unittest.mock import AsyncMock, MagicMock, patch
|
|
|
|
from aio_pika.abc import (
|
|
AbstractIncomingMessage,
|
|
AbstractRobustChannel,
|
|
AbstractRobustQueue,
|
|
)
|
|
|
|
from amqp.config.amq_configuration import AMQConfiguration
|
|
from amqp.model.model import AMQRoute, ServiceMessage
|
|
from amqp.model.service_message_type import ServiceMessageType
|
|
from amqp.router.router_base import (
|
|
CM_C_REQ_QUEUE,
|
|
CM_REQUEST_EXCHANGE,
|
|
)
|
|
from amqp.router.router_consumer import RouterConsumer
|
|
|
|
|
|
class TestRouterConsumer(unittest.IsolatedAsyncioTestCase):
|
|
def setUp(self):
|
|
# Create a mock for amq_adapter
|
|
self.amq_adapter = MagicMock()
|
|
self.amq_adapter.adapter_prefix.return_value = "test_"
|
|
self.amq_adapter.service_name = "test_service"
|
|
|
|
# Create the config mock with amq_adapter
|
|
self.config = MagicMock(spec=AMQConfiguration)
|
|
self.config.amq_adapter = self.amq_adapter
|
|
self.consumer = RouterConsumer(self.config)
|
|
|
|
# Mock channel
|
|
self.channel = AsyncMock(spec=AbstractRobustChannel)
|
|
self.consumer.channel = self.channel
|
|
|
|
# Mock queue
|
|
self.queue = AsyncMock(spec=AbstractRobustQueue)
|
|
self.channel.declare_queue.return_value = self.queue
|
|
|
|
def test_init(self):
|
|
"""Test initialization of RouterConsumer"""
|
|
self.assertIsNotNone(self.consumer)
|
|
self.assertEqual(self.consumer.amq_configuration, self.config)
|
|
|
|
@patch("amqp.router.router_consumer.logging_info")
|
|
async def test_init_routing_paths_consumer_success(self, mock_logging):
|
|
"""Test successful initialization of routing paths consumer"""
|
|
self.consumer.is_open = MagicMock(return_value=True)
|
|
|
|
await self.consumer.init_routing_paths_consumer(self.channel)
|
|
|
|
# Verify queue declaration
|
|
self.channel.declare_queue.assert_called_once_with(
|
|
name="test_" + CM_C_REQ_QUEUE, durable=True, exclusive=False, auto_delete=False
|
|
)
|
|
|
|
# Verify queue binding
|
|
self.queue.bind.assert_called_once_with(exchange=CM_REQUEST_EXCHANGE, routing_key="")
|
|
|
|
# Verify consumer setup
|
|
self.queue.consume.assert_called_once()
|
|
|
|
@patch("amqp.router.router_consumer.logging_error")
|
|
async def test_init_routing_paths_consumer_channel_closed(self, mock_logging):
|
|
"""Test initialization when channel is closed"""
|
|
self.consumer.is_open = MagicMock(return_value=False)
|
|
|
|
await self.consumer.init_routing_paths_consumer(self.channel)
|
|
|
|
mock_logging.assert_called_once()
|
|
self.channel.declare_queue.assert_not_called()
|
|
|
|
@patch("amqp.router.router_consumer.logging_debug")
|
|
@patch("amqp.router.router_consumer.logging_info")
|
|
async def test_handle_routing_data_request_message_valid(
|
|
self, mock_logging_info, mock_logging_debug
|
|
):
|
|
"""Test handling of valid routing data request message"""
|
|
# Setup
|
|
message = AsyncMock(spec=AbstractIncomingMessage)
|
|
message.delivery_tag = 1
|
|
message.consumer_tag = "test_consumer"
|
|
message.properties = MagicMock()
|
|
message.body = b"test_body"
|
|
|
|
# Mock service message factory
|
|
mock_service_message = ServiceMessage(
|
|
id=None,
|
|
payload_type=0,
|
|
message_type=ServiceMessageType.ROUTING_DATA_REQUEST,
|
|
recipient_name="test_service",
|
|
reply_to="other_service",
|
|
trace_info={},
|
|
message="test_payload",
|
|
)
|
|
self.consumer.service_message_factory = MagicMock()
|
|
self.consumer.service_message_factory.from_bytes = MagicMock(
|
|
return_value=mock_service_message
|
|
)
|
|
self.consumer.service_message_factory.of = MagicMock()
|
|
self.consumer.wrap_own_routes = MagicMock(return_value="test_routes")
|
|
self.consumer.publish_service_message = AsyncMock(return_value=True)
|
|
|
|
# Execute
|
|
await self.consumer.handle_routing_data_request_message(message)
|
|
|
|
# Verify
|
|
message.ack.assert_called_once_with(False)
|
|
self.consumer.publish_service_message.assert_called_once()
|
|
|
|
@patch("amqp.router.router_consumer.logging_info")
|
|
async def test_register_route_success(self, mock_logging):
|
|
"""Test successful route registration"""
|
|
# Setup
|
|
route = AMQRoute(
|
|
component_name="test_service",
|
|
exchange="test_exchange",
|
|
queue="test_queue",
|
|
key="test_key",
|
|
timeout=1000,
|
|
valid_until=0,
|
|
)
|
|
self.consumer.is_open = MagicMock(return_value=True)
|
|
self.consumer.publish_service_message = AsyncMock(return_value=True)
|
|
self.consumer.add_own_route = MagicMock()
|
|
|
|
# Execute
|
|
await self.consumer.register_route(route)
|
|
|
|
# Verify
|
|
self.consumer.publish_service_message.assert_called_once()
|
|
self.consumer.add_own_route.assert_called_once_with(route)
|
|
|
|
@patch("amqp.router.router_consumer.logging_warning")
|
|
async def test_register_route_channel_closed(self, mock_logging):
|
|
"""Test route registration when channel is closed"""
|
|
# Setup
|
|
route = AMQRoute(
|
|
component_name="test_service",
|
|
exchange="test_exchange",
|
|
queue="test_queue",
|
|
key="test_key",
|
|
timeout=1000,
|
|
valid_until=0,
|
|
)
|
|
self.consumer.is_open = MagicMock(return_value=False)
|
|
|
|
# Execute
|
|
await self.consumer.register_route(route)
|
|
|
|
# Verify
|
|
mock_logging.assert_called_once()
|
|
|
|
@patch("amqp.router.router_consumer.logging_info")
|
|
@patch("amqp.router.router_consumer.logging_warning")
|
|
async def test_remove_route_on_cleanup(self, mock_logging_warning, mock_logging_info):
|
|
"""Test route removal during cleanup"""
|
|
# Setup
|
|
route = AMQRoute(
|
|
component_name="test_service",
|
|
exchange="test_exchange",
|
|
queue="test_queue",
|
|
key="test_key",
|
|
timeout=1000,
|
|
valid_until=0,
|
|
)
|
|
self.consumer.publish_service_message = AsyncMock(return_value=True)
|
|
self.consumer.remove_route = MagicMock(return_value=True)
|
|
|
|
# Execute
|
|
result = await self.consumer.remove_route_on_cleanup(route)
|
|
|
|
# Verify
|
|
self.consumer.publish_service_message.assert_called_once()
|
|
self.consumer.remove_route.assert_called_once_with(route)
|
|
self.assertTrue(result)
|
|
|
|
@patch("amqp.router.router_consumer.logging_info")
|
|
@patch("amqp.router.router_consumer.logging_warning")
|
|
def test_cleanup(self, mock_logging_warning, mock_logging_info):
|
|
"""Test cleanup process"""
|
|
# Setup
|
|
routes = {
|
|
AMQRoute(
|
|
component_name="test_service",
|
|
exchange="test_exchange1",
|
|
queue="test_queue1",
|
|
key="test_key1",
|
|
timeout=1000,
|
|
valid_until=0,
|
|
),
|
|
AMQRoute(
|
|
component_name="test_service",
|
|
exchange="test_exchange2",
|
|
queue="test_queue2",
|
|
key="test_key2",
|
|
timeout=1000,
|
|
valid_until=0,
|
|
),
|
|
}
|
|
self.consumer.get_routes = MagicMock(return_value=routes)
|
|
self.consumer.remove_route_on_cleanup = AsyncMock(return_value=True)
|
|
self.consumer.wrap_routes = MagicMock(return_value="test_routes")
|
|
|
|
# Execute
|
|
self.consumer.cleanup()
|
|
|
|
# Verify
|
|
self.assertEqual(self.consumer.remove_route_on_cleanup.call_count, 2)
|
|
mock_logging_info.assert_called()
|