fix: Fix up merging request changes and make sure that there is no racing condition errors, and UI always gets correct information.

ref: N25B-256
This commit is contained in:
Björn Otgaar
2025-11-11 10:18:43 +01:00
parent 2d1a25e4ae
commit debc87c0bb
3 changed files with 67 additions and 75 deletions

View File

@@ -196,14 +196,14 @@ async def test_setup_creates_socket_and_negotiate_3(zmq_context, caplog):
fake_agent_instance = MockCommandAgent.return_value
fake_agent_instance.start = AsyncMock()
# --- Act ---
with caplog.at_level("ERROR"):
agent = RICommunicationAgent(
"test@server",
"password",
address="tcp://localhost:5555",
bind=False,
)
await agent.setup(max_retries=1)
agent = RICommunicationAgent(
"test@server",
"password",
address="tcp://localhost:5555",
bind=False,
)
await agent.setup(max_retries=1)
# --- Assert ---
fake_socket.connect.assert_any_call("tcp://localhost:5555")
@@ -211,7 +211,6 @@ async def test_setup_creates_socket_and_negotiate_3(zmq_context, caplog):
# Since it failed, there should not be any command agent.
fake_agent_instance.start.assert_not_awaited()
assert "Failed to set up RICommunicationAgent" in caplog.text
# Ensure the agent did not attach a ListenBehaviour
assert not any(isinstance(b, agent.ListenBehaviour) for b in agent.behaviours)
@@ -362,14 +361,14 @@ async def test_setup_creates_socket_and_negotiate_7(zmq_context, caplog):
fake_agent_instance.start = AsyncMock()
# --- Act ---
with caplog.at_level("WARNING"):
agent = RICommunicationAgent(
"test@server",
"password",
address="tcp://localhost:5555",
bind=False,
)
await agent.setup(max_retries=1)
agent = RICommunicationAgent(
"test@server",
"password",
address="tcp://localhost:5555",
bind=False,
)
await agent.setup(max_retries=1)
# --- Assert ---
fake_socket.connect.assert_any_call("tcp://localhost:5555")
@@ -377,7 +376,6 @@ async def test_setup_creates_socket_and_negotiate_7(zmq_context, caplog):
# Since it failed, there should not be any command agent.
fake_agent_instance.start.assert_not_awaited()
assert "Unhandled negotiation id:" in caplog.text
@pytest.mark.asyncio
@@ -398,21 +396,20 @@ async def test_setup_creates_socket_and_negotiate_timeout(zmq_context, caplog):
fake_agent_instance.start = AsyncMock()
# --- Act ---
with caplog.at_level("WARNING"):
agent = RICommunicationAgent(
"test@server",
"password",
address="tcp://localhost:5555",
bind=False,
)
await agent.setup(max_retries=1)
agent = RICommunicationAgent(
"test@server",
"password",
address="tcp://localhost:5555",
bind=False,
)
await agent.setup(max_retries=1)
# --- Assert ---
fake_socket.connect.assert_any_call("tcp://localhost:5555")
# Since it failed, there should not be any command agent.
fake_agent_instance.start.assert_not_awaited()
assert "No connection established in 20 seconds" in caplog.text
# Ensure the agent did not attach a ListenBehaviour
assert not any(isinstance(b, agent.ListenBehaviour) for b in agent.behaviours)
@@ -425,7 +422,6 @@ async def test_listen_behaviour_ping_correct(caplog):
fake_socket.recv_json = AsyncMock(return_value={"endpoint": "ping", "data": {}})
fake_socket.send_multipart = AsyncMock()
# TODO: Integration test between actual server and password needed for spade agents
agent = RICommunicationAgent("test@server", "password")
agent._req_socket = fake_socket
agent.connected = True
@@ -433,13 +429,10 @@ async def test_listen_behaviour_ping_correct(caplog):
behaviour = agent.ListenBehaviour()
agent.add_behaviour(behaviour)
# Run once (CyclicBehaviour normally loops)
with caplog.at_level("DEBUG"):
await behaviour.run()
await behaviour.run()
fake_socket.send_json.assert_awaited()
fake_socket.recv_json.assert_awaited()
assert "Received message" in caplog.text
@pytest.mark.asyncio
@@ -470,10 +463,9 @@ async def test_listen_behaviour_ping_wrong_endpoint(caplog):
agent.add_behaviour(behaviour)
# Run once (CyclicBehaviour normally loops)
with caplog.at_level("INFO"):
await behaviour.run()
assert "Received message with topic different than ping, while ping expected." in caplog.text
await behaviour.run()
fake_socket.send_json.assert_awaited()
fake_socket.recv_json.assert_awaited()
@@ -493,10 +485,9 @@ async def test_listen_behaviour_timeout(zmq_context, caplog):
behaviour = agent.ListenBehaviour()
agent.add_behaviour(behaviour)
with caplog.at_level("INFO"):
await behaviour.run()
assert "No ping" in caplog.text
await behaviour.run()
assert not any(isinstance(b, agent.ListenBehaviour) for b in agent.behaviours)
assert not agent.connected
@pytest.mark.asyncio
@@ -522,11 +513,8 @@ async def test_listen_behaviour_ping_no_endpoint(caplog):
behaviour = agent.ListenBehaviour()
agent.add_behaviour(behaviour)
# Run once (CyclicBehaviour normally loops)
with caplog.at_level("ERROR"):
await behaviour.run()
await behaviour.run()
assert "No received endpoint in message, excepted ping endpoint." in caplog.text
fake_socket.send_json.assert_awaited()
fake_socket.recv_json.assert_awaited()
@@ -546,11 +534,10 @@ async def test_setup_unexpected_exception(zmq_context, caplog):
bind=False,
)
with caplog.at_level("ERROR"):
await agent.setup(max_retries=1)
await agent.setup(max_retries=1)
# Ensure that the error was logged
assert "Unexpected error during negotiation: boom!" in caplog.text
assert not any(isinstance(b, agent.ListenBehaviour) for b in agent.behaviours)
assert not agent.connected
@pytest.mark.asyncio
@@ -582,11 +569,8 @@ async def test_setup_unpacking_exception(zmq_context, caplog):
)
# --- Act & Assert ---
with caplog.at_level("ERROR"):
await agent.setup(max_retries=1)
# Ensure the unpacking exception was logged
assert "Error unpacking negotiation data" in caplog.text
await agent.setup(max_retries=1)
# Ensure no command agent was started
fake_agent_instance.start.assert_not_awaited()