SIENTIAPDE-1312
Refactor OpcManager connection error handling and enhance unit tests - Simplified error handling during connection attempts in OpcManager by removing redundant disconnection logic. - Updated unit tests to include subscription_period_ms in server configuration and adjusted connection assertions to include a timeout parameter. - Added new tests for disconnection fallback functionality to ensure robust error handling during disconnect attempts.
This commit is contained in:
@@ -94,6 +94,7 @@ async def test_initialize_opc_from_config(opc_manager, ingestor_manager):
|
||||
server_config = {
|
||||
'name': 'server1',
|
||||
'url': 'opc.tcp://localhost:4840',
|
||||
'subscription_period_ms': 1000,
|
||||
'server_uri': 'http://opcua-server.simulator',
|
||||
'cert_path': '/path/to/cert',
|
||||
'private_key_path': '/path/to/private_key',
|
||||
@@ -109,6 +110,7 @@ async def test_initialize_opc_from_config(opc_manager, ingestor_manager):
|
||||
url=server_config['url'],
|
||||
data_manager=ingestor_manager.data_manager,
|
||||
logger=ingestor_manager.logger,
|
||||
subscription_period_ms=server_config['subscription_period_ms'],
|
||||
server_uri=server_config['server_uri'],
|
||||
notification_handler=ingestor_manager.notification_handler,
|
||||
cert_path=server_config['cert_path'],
|
||||
@@ -128,6 +130,7 @@ async def test_initialize_opc_from_config_exception(traceback_mock, opc_manager,
|
||||
server_config = {
|
||||
'name': 'server1',
|
||||
'url': 'opc.tcp://localhost:4840',
|
||||
'subscription_period_ms': 1000,
|
||||
'server_uri': 'http://opcua-server.simulator',
|
||||
'cert_path': '/path/to/cert',
|
||||
'private_key_path': '/path/to/private_key',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import json
|
||||
from datetime import datetime
|
||||
from unittest.mock import AsyncMock, MagicMock, call, patch
|
||||
from unittest.mock import ANY, AsyncMock, MagicMock, call, patch
|
||||
|
||||
import pytest
|
||||
from asyncua.crypto.security_policies import SecurityPolicyBasic256
|
||||
@@ -142,7 +142,7 @@ async def test_connect_no_security(client, mock_metrics, raw_opc_manager):
|
||||
|
||||
await raw_opc_manager.connect()
|
||||
|
||||
client.assert_called_once_with(raw_opc_manager.url, watchdog_intervall=3600000)
|
||||
client.assert_called_once_with(raw_opc_manager.url, timeout=10, watchdog_intervall=3600000)
|
||||
raw_opc_manager.client.connect.assert_called_once()
|
||||
raw_opc_manager.set_security.assert_not_called()
|
||||
mock_metrics.OPC_CONNECTIONS_TOTAL.labels.assert_called_once_with(
|
||||
@@ -169,7 +169,7 @@ async def test_connect_with_security(client, raw_opc_manager):
|
||||
|
||||
await raw_opc_manager.connect()
|
||||
|
||||
client.assert_called_once_with(raw_opc_manager.url, watchdog_intervall=3600000)
|
||||
client.assert_called_once_with(raw_opc_manager.url, timeout=10, watchdog_intervall=3600000)
|
||||
raw_opc_manager.client.connect.assert_called_once()
|
||||
raw_opc_manager.set_security.assert_called_once()
|
||||
|
||||
@@ -184,33 +184,15 @@ async def test_connect_exception_handling_and_metrics(
|
||||
simulated_error_message = 'Erro de conexão simulado'
|
||||
mock_client_instance.connect.side_effect = Exception(simulated_error_message)
|
||||
|
||||
raw_opc_manager.disconnect = AsyncMock()
|
||||
|
||||
opc_manager_instance = raw_opc_manager
|
||||
opc_manager_instance.cert_path = None
|
||||
|
||||
with pytest.raises(Exception, match=simulated_error_message):
|
||||
await opc_manager_instance.connect()
|
||||
|
||||
mock_metrics_module.OPC_CONNECTIONS_TOTAL.labels.assert_called_once_with(
|
||||
pod_id=opc_manager_instance.pod_id, server_name=opc_manager_instance.name
|
||||
)
|
||||
mock_metrics_module.OPC_CONNECTIONS_TOTAL.labels.return_value.inc.assert_called_once()
|
||||
|
||||
mock_metrics_module.OPC_CONNECTION_STATUS.labels.assert_called_once_with(
|
||||
pod_id=opc_manager_instance.pod_id,
|
||||
server_name=opc_manager_instance.name,
|
||||
server_url=opc_manager_instance.url,
|
||||
)
|
||||
mock_metrics_module.OPC_CONNECTION_STATUS.labels.return_value.set.assert_called_once_with(0)
|
||||
|
||||
mock_metrics_module.OPC_CONNECTIONS_FAILED.labels.assert_called_once_with(
|
||||
pod_id=opc_manager_instance.pod_id, server_name=opc_manager_instance.name
|
||||
)
|
||||
mock_metrics_module.OPC_CONNECTIONS_FAILED.labels.return_value.inc.assert_called_once()
|
||||
|
||||
opc_manager_instance.logger.error.assert_called_once_with(
|
||||
f'Failed to connect to {opc_manager_instance.name}: {simulated_error_message}'
|
||||
)
|
||||
|
||||
|
||||
opc_manager_instance.disconnect.assert_called_once()
|
||||
|
||||
@mark.asyncio
|
||||
async def test_create_subscription_no_client(raw_opc_manager):
|
||||
@@ -260,16 +242,15 @@ async def test_create_subscription_exception_during_client_call(
|
||||
opc_manager_instance.client = AsyncMock()
|
||||
|
||||
subscription_name = 'test_sub_client_error'
|
||||
simulated_period = 750
|
||||
simulated_error_message = 'Falha ao criar subscrição no cliente OPC'
|
||||
|
||||
opc_manager_instance.client.create_subscription.side_effect = Exception(simulated_error_message)
|
||||
|
||||
with pytest.raises(Exception, match=simulated_error_message):
|
||||
await opc_manager_instance.create_subscription(subscription_name, period=simulated_period)
|
||||
await opc_manager_instance.create_subscription(subscription_name)
|
||||
|
||||
opc_manager_instance.client.create_subscription.assert_called_once_with(
|
||||
simulated_period, opc_manager_instance
|
||||
opc_manager_instance.subscription_period_ms, opc_manager_instance
|
||||
)
|
||||
|
||||
opc_manager_instance.logger.error.assert_called_once_with(
|
||||
@@ -321,6 +302,28 @@ async def test_unsubscribe_success(opc_manager_subscribed):
|
||||
assert opc_manager_subscribed.subscriptions.get('sub1') is None
|
||||
|
||||
|
||||
|
||||
@mark.asyncio
|
||||
async def test_disconnection_fallback_success(opc_manager):
|
||||
opc_manager.client = AsyncMock()
|
||||
opc_manager.client.disconnect.return_value = True
|
||||
result = await opc_manager.disconnection_fallback()
|
||||
assert result == []
|
||||
|
||||
@mark.asyncio
|
||||
async def test_disconnection_fallback_fail(opc_manager):
|
||||
opc_manager.client = AsyncMock()
|
||||
opc_manager.client.disconnect.side_effect = Exception('Test error')
|
||||
result = await opc_manager.disconnection_fallback()
|
||||
assert result == [
|
||||
{'attempt': 1, 'error': 'Test error', 'traceback': ANY},
|
||||
{'attempt': 2, 'error': 'Test error', 'traceback': ANY},
|
||||
{'attempt': 3, 'error': 'Test error', 'traceback': ANY},
|
||||
{'attempt': 4, 'error': 'Test error', 'traceback': ANY},
|
||||
{'attempt': 5, 'error': 'Test error', 'traceback': ANY}, ]
|
||||
assert opc_manager.client.disconnect.call_count == 5
|
||||
|
||||
|
||||
@mark.asyncio
|
||||
async def test_disconnect_success(opc_manager_subscribed):
|
||||
opc_manager_subscribed.client = MagicMock()
|
||||
@@ -368,9 +371,7 @@ async def test_disconnect_error(opc_manager_subscribed):
|
||||
|
||||
opc_manager_subscribed.subscriptions['sub1'].delete.assert_called_once()
|
||||
opc_manager_subscribed.client = None
|
||||
opc_manager_subscribed.logger.error.assert_called_once_with(
|
||||
'Failed to disconnect from OPC UA server: Test error'
|
||||
)
|
||||
|
||||
|
||||
|
||||
@patch('ingestor.managers.opc_manager.metrics')
|
||||
|
||||
Reference in New Issue
Block a user