from unittest.mock import AsyncMock import pytest import ingestor.metrics as metrics from ingestor.io.data_sink import DataSink def make_sink(data_manager=None): dm = data_manager or AsyncMock() sink = DataSink(data_manager=dm, postgres=AsyncMock()) sink.emit_metric = AsyncMock() return sink, dm @pytest.mark.asyncio async def test_publish_reading_fans_out_per_name(): sink, dm = make_sink() names = [ {'collection': 'raw_x', 'tag_name': 'Counter', 'model_id': '1', 'model_name': 'm1'}, {'collection': 'raw_y', 'tag_name': 'Contador', 'model_id': '2', 'model_name': 'm2'}, ] await sink.publish_reading( tag='ns=2;i=2', value=42, timestamp='2026-07-13T00:00:00Z', names=names ) assert dm.publish.await_count == 2 @pytest.mark.asyncio async def test_publish_reading_builds_doc_and_routes_collection(): sink, dm = make_sink() names = [{'collection': 'raw_x', 'tag_name': 'Counter', 'model_id': '1', 'model_name': 'm1'}] await sink.publish_reading( tag='ns=2;i=2', value=42, timestamp='2026-07-13T00:00:00Z', names=names ) collection, doc = dm.publish.await_args_list[0].args assert collection == 'raw_x' assert doc == { 'tag': 'ns=2;i=2', 'name': 'Counter', 'model_id': '1', 'timestamp': '2026-07-13T00:00:00Z', 'value': 42, } @pytest.mark.asyncio async def test_publish_reading_emits_tag_value_metric_per_name(): sink, dm = make_sink() names = [ {'collection': 'raw_x', 'tag_name': 'Counter', 'model_id': '1', 'model_name': 'm1'}, {'collection': 'raw_y', 'tag_name': 'Contador', 'model_id': '2', 'model_name': 'm2'}, ] await sink.publish_reading( tag='ns=2;i=2', value=42, timestamp='2026-07-13T00:00:00Z', names=names ) assert sink.emit_metric.await_count == 2 sink.emit_metric.assert_any_await( metric_object=metrics.OPC_TAG_VALUE, method='set', value=42, tags={'pod_id': dm.pod_id, 'tag_name': 'Counter', 'model_id': '1'}, ) @pytest.mark.asyncio async def test_publish_reading_without_model_id_keeps_legacy_doc(): """Names converted from a slot v1 carry no model_id: the document must be the same as the legacy OpcManager one (SIENTIAPDE-1974 NF2).""" sink, dm = make_sink() names = [{'collection': 'raw_x', 'tag_name': 'Counter'}] await sink.publish_reading( tag='ns=2;i=2', value=42, timestamp='2026-07-13 00:00:00+0000', names=names ) collection, doc = dm.publish.await_args_list[0].args assert collection == 'raw_x' assert doc == { 'tag': 'ns=2;i=2', 'name': 'Counter', 'timestamp': '2026-07-13 00:00:00+0000', 'value': 42, } _, kwargs = sink.emit_metric.await_args assert kwargs['tags']['model_id'] == ''