From e94b4891969dd87432dfa7770fc54e831a26361d Mon Sep 17 00:00:00 2001 From: Eduardo Rios Date: Wed, 14 Oct 2026 12:20:30 -0300 Subject: [PATCH] SIENTIAPDE-1975: Sonar fixes in the NATS consumer tests - One call per pytest.raises block (S5778): build the guarded start() before the block and nest the patch outside it. - The NATS callbacks stay async on purpose: nats-py rejects callbacks that are not coroutine functions. Comment it and assert it in the callback test, so nobody drops the async keyword to please S7503. Co-Authored-By: Claude Opus 5.5 --- ingestor/adapters/nats_consumer.py | 2 ++ tests/unit/adapters/test_nats_consumer.py | 11 +++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/ingestor/adapters/nats_consumer.py b/ingestor/adapters/nats_consumer.py index bc4bd87..b985142 100644 --- a/ingestor/adapters/nats_consumer.py +++ b/ingestor/adapters/nats_consumer.py @@ -94,6 +94,8 @@ class NatsWriteConsumer: f'{traceback.format_exc()}' ) + # These stay async with nothing to await: nats-py rejects callbacks that are not + # coroutine functions (InvalidCallbackTypeError on connect). async def _on_error(self, e: Exception) -> None: self.logger.warning(f'NATS error: {type(e).__name__} {e}') diff --git a/tests/unit/adapters/test_nats_consumer.py b/tests/unit/adapters/test_nats_consumer.py index eddca14..1485d1a 100644 --- a/tests/unit/adapters/test_nats_consumer.py +++ b/tests/unit/adapters/test_nats_consumer.py @@ -1,4 +1,5 @@ import asyncio +import inspect import json from unittest.mock import AsyncMock, MagicMock, patch @@ -76,9 +77,12 @@ async def test_start_gives_up_after_the_connect_timeout(): """start() runs on the main loop: an unreachable NATS must not block it.""" consumer = make_consumer(connect_timeout_s=0.1) nc = _fake_nc(connect=AsyncMock(side_effect=_hang)) + # Outer guard: fails the test instead of hanging it if start() ignores its timeout. + start = asyncio.wait_for(consumer.start(), timeout=5) - with patch(CLIENT, return_value=nc), pytest.raises(TimeoutError): - await asyncio.wait_for(consumer.start(), timeout=5) + with patch(CLIENT, return_value=nc): + with pytest.raises(TimeoutError): + await start nc.close.assert_awaited_once() assert consumer.closed is True @@ -115,6 +119,9 @@ async def test_connection_events_are_logged_in_one_line(): with patch(CLIENT, return_value=nc): await consumer.start() callbacks = nc.connect.await_args.kwargs + # nats-py raises InvalidCallbackTypeError on connect for a non-coroutine callback. + for name in ('error_cb', 'disconnected_cb', 'reconnected_cb'): + assert inspect.iscoroutinefunction(callbacks[name]), name await callbacks['error_cb'](OSError('connection refused')) await callbacks['disconnected_cb']()