test: increased cb test coverage
This commit is contained in:
committed by
Luijkx,S.O.H. (Storm)
parent
de2e56ffce
commit
7f7c658901
@@ -2,7 +2,7 @@
|
||||
|
||||
import asyncio
|
||||
import logging
|
||||
from unittest.mock import AsyncMock
|
||||
from unittest.mock import AsyncMock, MagicMock
|
||||
|
||||
import pytest
|
||||
|
||||
@@ -70,3 +70,142 @@ async def test_get_agent():
|
||||
agent = ConcreteTestAgent("registrant")
|
||||
assert AgentDirectory.get("registrant") == agent
|
||||
assert AgentDirectory.get("non_existent") is None
|
||||
|
||||
|
||||
class DummyAgent(BaseAgent):
|
||||
async def setup(self):
|
||||
pass # we will test this separately
|
||||
|
||||
async def handle_message(self, msg: InternalMessage):
|
||||
self.last_handled = msg
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_base_agent_setup_is_noop():
|
||||
agent = DummyAgent("dummy")
|
||||
|
||||
# Should simply return without error
|
||||
assert await agent.setup() is None
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_send_to_local_agent(monkeypatch):
|
||||
sender = DummyAgent("sender")
|
||||
target = DummyAgent("receiver")
|
||||
|
||||
# Fake logger
|
||||
sender.logger = MagicMock()
|
||||
|
||||
# Patch inbox.put
|
||||
target.inbox.put = AsyncMock()
|
||||
|
||||
message = InternalMessage(to="receiver", sender="sender", body="hello")
|
||||
|
||||
await sender.send(message)
|
||||
|
||||
target.inbox.put.assert_awaited_once_with(message)
|
||||
sender.logger.debug.assert_called_once()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_process_inbox_calls_handle_message(monkeypatch):
|
||||
agent = DummyAgent("dummy")
|
||||
agent.logger = MagicMock()
|
||||
|
||||
# Make agent running so loop triggers
|
||||
agent._running = True
|
||||
|
||||
# Prepare inbox to give one message then stop
|
||||
msg = InternalMessage(to="dummy", sender="x", body="test")
|
||||
|
||||
async def get_once():
|
||||
agent._running = False # stop after first iteration
|
||||
return msg
|
||||
|
||||
agent.inbox.get = AsyncMock(side_effect=get_once)
|
||||
agent.handle_message = AsyncMock()
|
||||
|
||||
await agent._process_inbox()
|
||||
|
||||
agent.handle_message.assert_awaited_once_with(msg)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_receive_internal_zmq_loop_success(monkeypatch):
|
||||
agent = DummyAgent("dummy")
|
||||
agent.logger = MagicMock()
|
||||
agent._running = True
|
||||
|
||||
mock_socket = MagicMock()
|
||||
mock_socket.recv_multipart = AsyncMock(
|
||||
side_effect=[
|
||||
(
|
||||
b"topic",
|
||||
InternalMessage(to="dummy", sender="x", body="hi").model_dump_json().encode(),
|
||||
),
|
||||
asyncio.CancelledError(), # stop loop
|
||||
]
|
||||
)
|
||||
agent._internal_sub_socket = mock_socket
|
||||
|
||||
agent.inbox.put = AsyncMock()
|
||||
|
||||
await agent._receive_internal_zmq_loop()
|
||||
|
||||
agent.inbox.put.assert_awaited() # message forwarded
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_receive_internal_zmq_loop_exception_logs_error():
|
||||
agent = DummyAgent("dummy")
|
||||
agent.logger = MagicMock()
|
||||
agent._running = True
|
||||
|
||||
mock_socket = MagicMock()
|
||||
mock_socket.recv_multipart = AsyncMock(
|
||||
side_effect=[Exception("boom"), asyncio.CancelledError()]
|
||||
)
|
||||
agent._internal_sub_socket = mock_socket
|
||||
|
||||
agent.inbox.put = AsyncMock()
|
||||
|
||||
await agent._receive_internal_zmq_loop()
|
||||
|
||||
agent.logger.exception.assert_called_once()
|
||||
assert "Could not process ZMQ message." in agent.logger.exception.call_args[0][0]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_base_agent_handle_message_not_implemented():
|
||||
class RawAgent(BaseAgent):
|
||||
async def setup(self):
|
||||
pass
|
||||
|
||||
agent = RawAgent("raw")
|
||||
|
||||
msg = InternalMessage(to="raw", sender="x", body="hi")
|
||||
|
||||
with pytest.raises(NotImplementedError):
|
||||
await BaseAgent.handle_message(agent, msg)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_base_agent_setup_abstract_method_body_executes():
|
||||
"""
|
||||
Covers the 'pass' inside BaseAgent.setup().
|
||||
Since BaseAgent is abstract, we do NOT instantiate it.
|
||||
We call the coroutine function directly on BaseAgent and pass a dummy self.
|
||||
"""
|
||||
|
||||
class Dummy:
|
||||
"""Minimal stub to act as 'self'."""
|
||||
|
||||
pass
|
||||
|
||||
stub = Dummy()
|
||||
|
||||
# Call BaseAgent.setup() as an unbound coroutine, passing stub as 'self'
|
||||
result = await BaseAgent.setup(stub)
|
||||
|
||||
# The method contains only 'pass', so it returns None
|
||||
assert result is None
|
||||
|
||||
Reference in New Issue
Block a user