45941de6b1
Remove the loop for monitoring the CPU usage, adopt changes in the management service for the reporting message format, update the timing for sending out report, similar to java adapter. ISSUES RELATED: clevermicro/amq-adapter-python#58
185 lines
7.2 KiB
Python
185 lines
7.2 KiB
Python
import unittest
|
|
from unittest.mock import AsyncMock, Mock, patch
|
|
|
|
from amqp.config.amq_configuration import AMQAdapter, AMQConfiguration
|
|
from amqp.service.amq_service import AMQService
|
|
|
|
|
|
class TestAMQService(unittest.IsolatedAsyncioTestCase):
|
|
def setUp(self):
|
|
# Create a mock configuration
|
|
self.mock_adapter = Mock(spec=AMQAdapter)
|
|
self.mock_adapter.generator_id = 12345
|
|
self.mock_adapter.service_name = "test-service"
|
|
self.mock_adapter.route_mapping = {}
|
|
self.mock_adapter.swarm_service_id = "test-swarm-id"
|
|
self.mock_adapter.swarm_task_id = "test-task-id"
|
|
|
|
self.mock_config = Mock(spec=AMQConfiguration)
|
|
self.mock_config.amq_adapter = self.mock_adapter
|
|
|
|
# Add dispatch configuration
|
|
self.mock_dispatch = Mock()
|
|
self.mock_dispatch.amq_host = "localhost"
|
|
self.mock_dispatch.amq_port = 5672
|
|
self.mock_dispatch.rabbit_mq_user = "guest"
|
|
self.mock_dispatch.rabbit_mq_password = "guest"
|
|
self.mock_dispatch.use_dlq = False
|
|
self.mock_config.dispatch = self.mock_dispatch
|
|
|
|
# Add backpressure configuration
|
|
self.mock_backpressure = Mock()
|
|
self.mock_backpressure.threshold_threads = 10
|
|
self.mock_config.backpressure = self.mock_backpressure
|
|
|
|
# Create service instance with mocked configuration
|
|
self.service = AMQService(self.mock_config)
|
|
|
|
# Mock the event loop
|
|
self.mock_loop = Mock()
|
|
self.service.loop = self.mock_loop
|
|
|
|
def tearDown(self):
|
|
# Clean up any resources
|
|
if hasattr(self, "service"):
|
|
self.service.cleanup()
|
|
|
|
@patch("amqp.service.amq_service.RabbitMQClient")
|
|
@patch("amqp.service.amq_service.DataMessageFactory")
|
|
@patch("amqp.service.amq_service.ServiceMessageFactory")
|
|
@patch("amqp.service.amq_service.initialize_telemetry")
|
|
def test_init(
|
|
self, mock_telemetry, mock_service_factory, mock_data_factory, mock_rabbit_client
|
|
):
|
|
# Test initialization of AMQService
|
|
service = AMQService(self.mock_config)
|
|
|
|
# Verify that all required components are initialized
|
|
self.assertIsNotNone(service.amq_configuration)
|
|
self.assertIsNotNone(service.data_message_factory)
|
|
self.assertIsNotNone(service.rabbit_mq_client)
|
|
self.assertIsNotNone(service.tracer)
|
|
self.assertIsNotNone(service.service_message_factory)
|
|
|
|
@patch("amqp.service.amq_service.RabbitMQClient")
|
|
async def test_register_routes_valid(self, mock_rabbit_client):
|
|
# Setup mock route mapping
|
|
self.mock_adapter.route_mapping = "test-service:test-exchange:test-queue:test.#:5:0"
|
|
|
|
# Setup mock rabbit client
|
|
mock_client = Mock()
|
|
mock_client.register_inbound_routes = AsyncMock()
|
|
mock_client.register_data_reply_callback = AsyncMock()
|
|
mock_client.init = AsyncMock()
|
|
mock_client.request_routes = AsyncMock()
|
|
mock_client.channel = Mock()
|
|
mock_client.channel.is_closed = False
|
|
self.service.rabbit_mq_client = mock_client
|
|
|
|
# Setup mock service adapter
|
|
mock_service_adapter = Mock()
|
|
mock_service_adapter.loop = self.mock_loop
|
|
|
|
# Setup mock message handler
|
|
mock_handler = Mock()
|
|
mock_handler.inbound_data_message_callback_no_thread = AsyncMock()
|
|
mock_handler.reply_received_callback = AsyncMock()
|
|
self.service.amq_data_message_handler = mock_handler
|
|
|
|
# Initialize the service
|
|
await self.service.init(self.mock_loop, mock_service_adapter)
|
|
|
|
# Call register_routes
|
|
await self.service.register_routes()
|
|
|
|
# Verify that routes were registered twice (once in init, once in register_routes)
|
|
self.assertEqual(mock_client.register_inbound_routes.call_count, 2)
|
|
self.assertEqual(mock_client.register_data_reply_callback.call_count, 2)
|
|
|
|
@patch("amqp.service.amq_service.RabbitMQClient")
|
|
async def test_register_routes_invalid(self, mock_rabbit_client):
|
|
# Setup invalid route mapping
|
|
self.mock_adapter.route_mapping = None
|
|
|
|
# Setup mock rabbit client
|
|
mock_client = Mock()
|
|
mock_client.register_inbound_routes = AsyncMock()
|
|
mock_client.register_data_reply_callback = AsyncMock()
|
|
self.service.rabbit_mq_client = mock_client
|
|
|
|
# Call register_routes
|
|
result = await self.service.register_routes()
|
|
|
|
# Verify that no routes were registered
|
|
mock_client.register_inbound_routes.assert_not_called()
|
|
mock_client.register_data_reply_callback.assert_not_called()
|
|
self.assertIsNone(result)
|
|
|
|
@patch("amqp.service.amq_service.RabbitMQClient")
|
|
async def test_reinitialize_if_disconnected(self, mock_rabbit_client):
|
|
# Setup mock route mapping
|
|
self.mock_adapter.route_mapping = "test-service:test-exchange:test-queue:test.#:5:0"
|
|
|
|
# Setup mock rabbit client with closed channel
|
|
mock_client = AsyncMock()
|
|
mock_client.channel = Mock()
|
|
mock_client.channel.is_closed = True
|
|
mock_client.init = AsyncMock()
|
|
mock_client.register_inbound_routes = AsyncMock()
|
|
mock_client.register_data_reply_callback = AsyncMock()
|
|
mock_client.request_routes = AsyncMock()
|
|
|
|
# Make the constructor return our mock client
|
|
mock_rabbit_client.return_value = mock_client
|
|
self.service.rabbit_mq_client = mock_client
|
|
|
|
# Setup mock message handler
|
|
mock_handler = Mock()
|
|
mock_handler.inbound_data_message_callback_no_thread = AsyncMock()
|
|
mock_handler.reply_received_callback = AsyncMock()
|
|
self.service.amq_data_message_handler = mock_handler
|
|
|
|
# Call reinitialize_if_disconnected
|
|
await self.service.reinitialize_if_disconnected()
|
|
|
|
# Verify that client was reinitialized
|
|
mock_client.init.assert_called_once()
|
|
|
|
# def test_send_message(self):
|
|
# # Create mock message and future
|
|
# mock_message = Mock(spec=DataMessage)
|
|
# mock_message.id.return_value = "test-id"
|
|
# mock_future = MagicMock()
|
|
#
|
|
# # Setup mock message handler
|
|
# self.service.amq_data_message_handler = Mock()
|
|
# self.service.amq_data_message_handler.outstanding = {}
|
|
#
|
|
# # Send message
|
|
# self.service.send_message(mock_message, mock_future)
|
|
#
|
|
# # Verify message was added to outstanding
|
|
# self.assertEqual(self.service.amq_data_message_handler.outstanding["test-id"], mock_future)
|
|
|
|
def test_remove_outstanding_future(self):
|
|
# Setup mock message handler with outstanding message
|
|
self.service.amq_data_message_handler = Mock()
|
|
self.service.amq_data_message_handler.outstanding = {"test-id": Mock()}
|
|
|
|
# Remove future
|
|
self.service.remove_outstanding_future("test-id")
|
|
|
|
# Verify message was removed from outstanding
|
|
self.assertNotIn("test-id", self.service.amq_data_message_handler.outstanding)
|
|
|
|
def test_cleanup(self):
|
|
# Setup mock rabbit client
|
|
mock_client = Mock()
|
|
self.service.rabbit_mq_client = mock_client
|
|
|
|
# Call cleanup
|
|
self.service.cleanup()
|
|
|
|
# Verify rabbit client cleanup was called
|
|
mock_client.cleanup.assert_called_once()
|