Refactor notification handler imports across multiple files to use CoreNotificationHandler instead of NotificationHandler for consistency and clarity.
154 lines
5.1 KiB
Python
154 lines
5.1 KiB
Python
from unittest.mock import MagicMock, patch, call
|
|
import pytest
|
|
from sientia_do.notifications.handlers import CoreNotificationHandler as NotificationHandler
|
|
from scouter.activities.faker import Faker
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_kafka_producer():
|
|
with patch('scouter.activities.faker.KafkaProducer') as mock:
|
|
producer = MagicMock()
|
|
mock.return_value = producer
|
|
yield producer
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_datetime():
|
|
with patch('scouter.activities.faker.datetime') as mock_dt:
|
|
mock_dt.now.return_value.strftime.return_value = '2025-05-14 14:54:24'
|
|
yield mock_dt
|
|
|
|
|
|
@pytest.fixture
|
|
def faker_instance(mock_kafka_producer):
|
|
logger = MagicMock()
|
|
notification_handler = MagicMock(spec=NotificationHandler)
|
|
return Faker(
|
|
bootstrap_servers='localhost:9092',
|
|
logger=logger,
|
|
notification_handler=notification_handler
|
|
)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_faker_init(faker_instance, mock_kafka_producer):
|
|
"""Test Faker initialization with correct parameters"""
|
|
assert faker_instance.producer is not None
|
|
assert len(faker_instance.tags) == 6
|
|
|
|
metadata = {
|
|
'metadata': {
|
|
'model_id': 'test_model_id',
|
|
'model_name': 'test_model',
|
|
'schedule_name': 'test_schedule',
|
|
'workflow_name': 'scouter'
|
|
}
|
|
}
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_generate_and_send_data_default_count(faker_instance,
|
|
mock_kafka_producer, mock_datetime):
|
|
"""Test generating data with default message count"""
|
|
# Mock random.choice to control the output
|
|
with patch('random.choice') as mock_choice, \
|
|
patch('random.uniform', return_value=42.5), \
|
|
patch('random.randint', return_value=3), \
|
|
patch('random.random', return_value=0.5):
|
|
|
|
# Setup mock for tag and name selection
|
|
mock_choice.side_effect = [
|
|
'ns=1;i=1001',
|
|
'ns=1;i=1002',
|
|
'ns=1;i=1003'
|
|
]
|
|
|
|
# Call the method
|
|
await faker_instance.generate_and_send_data({'topic': 'test_topic', **metadata})
|
|
|
|
# Verify the producer was called 3 times (default count)
|
|
assert mock_kafka_producer.send.call_count == 3
|
|
mock_kafka_producer.flush.assert_called_once()
|
|
|
|
# Verify the message format
|
|
expected_data = [{
|
|
'tag': 'ns=1;i=1001',
|
|
'name': 'Temperature Sensor',
|
|
'timestamp': '2025-05-14 14:54:24',
|
|
'value': 42.5
|
|
}, {
|
|
'tag': 'ns=1;i=1002',
|
|
'name': 'Vibration Meter',
|
|
'timestamp': '2025-05-14 14:54:24',
|
|
'value': 42.5
|
|
}, {
|
|
'tag': 'ns=1;i=1003',
|
|
'name': 'Pressure Gauge',
|
|
'timestamp': '2025-05-14 14:54:24',
|
|
'value': 42.5
|
|
}]
|
|
mock_kafka_producer.send.assert_has_calls([
|
|
call('test_topic', value=expected_data[0]),
|
|
call('test_topic', value=expected_data[1]),
|
|
call('test_topic', value=expected_data[2])
|
|
])
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_generate_and_send_data_custom_count(faker_instance, mock_kafka_producer):
|
|
"""Test generating data with custom message count"""
|
|
# Call the method with custom count
|
|
await faker_instance.generate_and_send_data({
|
|
'topic': 'test_topic',
|
|
'num_messages': 2,
|
|
**metadata
|
|
})
|
|
|
|
# Verify the producer was called 2 times
|
|
assert mock_kafka_producer.send.call_count == 2
|
|
mock_kafka_producer.flush.assert_called_once()
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_generate_and_send_data_no_topic(faker_instance):
|
|
"""Test that ValueError is raised when no topic is provided"""
|
|
with pytest.raises(ValueError, match="Topic must be specified in input_data"):
|
|
await faker_instance.generate_and_send_data({**metadata})
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
@patch('scouter.activities.faker.random.random', return_value=0.5)
|
|
async def test_generate_and_send_data_random_values(_random, faker_instance, mock_kafka_producer):
|
|
"""Test that random values are within expected ranges"""
|
|
# Call the method
|
|
await faker_instance.generate_and_send_data({'topic': 'test_topic', **metadata})
|
|
|
|
# Get the call arguments
|
|
call_args = mock_kafka_producer.send.call_args[1]['value']
|
|
|
|
# Verify the data structure
|
|
assert 'tag' in call_args
|
|
assert call_args['tag'] in faker_instance.tags
|
|
assert 'value' in call_args
|
|
assert 0 <= call_args['value'] <= 100
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
@patch('scouter.activities.faker.random.random', return_value=0.05)
|
|
async def test_generate_and_send_data_generate_null_values(
|
|
_random_mock,
|
|
faker_instance,
|
|
mock_kafka_producer):
|
|
# Call the method
|
|
await faker_instance.generate_and_send_data({'topic': 'test_topic',
|
|
'num_messages': 1,
|
|
**metadata})
|
|
|
|
# Get the call arguments
|
|
call_args = mock_kafka_producer.send.call_args[1]['value']
|
|
|
|
assert call_args['value'] is None
|
|
assert call_args['tag'] in faker_instance.tags
|
|
assert 'name' in call_args
|
|
assert 'timestamp' in call_args
|