chore: added missing tests
This commit is contained in:
@@ -577,3 +577,192 @@ async def test_create_mapping_recursive_goals(agent):
|
|||||||
assert str(child_goal_id) in agent._goal_map
|
assert str(child_goal_id) in agent._goal_map
|
||||||
assert agent._goal_map[str(child_goal_id)] == "child_goal"
|
assert agent._goal_map[str(child_goal_id)] == "child_goal"
|
||||||
assert agent._goal_reverse_map["child_goal"] == str(child_goal_id)
|
assert agent._goal_reverse_map["child_goal"] == str(child_goal_id)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_setup(agent):
|
||||||
|
"""Test the setup method initializes sockets correctly."""
|
||||||
|
with patch("control_backend.agents.user_interrupt.user_interrupt_agent.Context") as MockContext:
|
||||||
|
mock_ctx_instance = MagicMock()
|
||||||
|
MockContext.instance.return_value = mock_ctx_instance
|
||||||
|
|
||||||
|
mock_sub = MagicMock()
|
||||||
|
mock_pub = MagicMock()
|
||||||
|
mock_ctx_instance.socket.side_effect = [mock_sub, mock_pub]
|
||||||
|
|
||||||
|
# MOCK add_behavior so we don't rely on internal attributes
|
||||||
|
agent.add_behavior = MagicMock()
|
||||||
|
|
||||||
|
await agent.setup()
|
||||||
|
|
||||||
|
# Check sockets
|
||||||
|
mock_sub.connect.assert_called_with(settings.zmq_settings.internal_sub_address)
|
||||||
|
mock_pub.connect.assert_called_with(settings.zmq_settings.internal_pub_address)
|
||||||
|
|
||||||
|
# Verify add_behavior was called
|
||||||
|
agent.add_behavior.assert_called_once()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_receive_loop_advanced_scenarios(agent):
|
||||||
|
"""
|
||||||
|
Covers:
|
||||||
|
- JSONDecodeError (lines 86-88)
|
||||||
|
- Override: Trigger found (lines 108-109)
|
||||||
|
- Override: Norm found (lines 114-115)
|
||||||
|
- Override: Nothing found (line 134)
|
||||||
|
- Override Unachieve: Success & Fail (lines 136-145)
|
||||||
|
- Pause: Context true/false logs (lines 150-157)
|
||||||
|
- Next Phase (line 160)
|
||||||
|
"""
|
||||||
|
# 1. Setup Data Maps
|
||||||
|
agent._trigger_map["101"] = "trigger_slug"
|
||||||
|
agent._cond_norm_map["202"] = "norm_slug"
|
||||||
|
|
||||||
|
# 2. Define Payloads
|
||||||
|
# A. Invalid JSON
|
||||||
|
bad_json = b"INVALID{JSON"
|
||||||
|
|
||||||
|
# B. Override -> Trigger
|
||||||
|
override_trigger = json.dumps({"type": "override", "context": "101"}).encode()
|
||||||
|
|
||||||
|
# C. Override -> Norm
|
||||||
|
override_norm = json.dumps({"type": "override", "context": "202"}).encode()
|
||||||
|
|
||||||
|
# D. Override -> Unknown
|
||||||
|
override_fail = json.dumps({"type": "override", "context": "999"}).encode()
|
||||||
|
|
||||||
|
# E. Unachieve -> Success
|
||||||
|
unachieve_success = json.dumps({"type": "override_unachieve", "context": "202"}).encode()
|
||||||
|
|
||||||
|
# F. Unachieve -> Fail
|
||||||
|
unachieve_fail = json.dumps({"type": "override_unachieve", "context": "999"}).encode()
|
||||||
|
|
||||||
|
# G. Pause (True)
|
||||||
|
pause_true = json.dumps({"type": "pause", "context": "true"}).encode()
|
||||||
|
|
||||||
|
# H. Pause (False/Resume)
|
||||||
|
pause_false = json.dumps({"type": "pause", "context": ""}).encode()
|
||||||
|
|
||||||
|
# I. Next Phase
|
||||||
|
next_phase = json.dumps({"type": "next_phase", "context": ""}).encode()
|
||||||
|
|
||||||
|
# 3. Setup Socket
|
||||||
|
agent.sub_socket.recv_multipart.side_effect = [
|
||||||
|
(b"topic", bad_json),
|
||||||
|
(b"topic", override_trigger),
|
||||||
|
(b"topic", override_norm),
|
||||||
|
(b"topic", override_fail),
|
||||||
|
(b"topic", unachieve_success),
|
||||||
|
(b"topic", unachieve_fail),
|
||||||
|
(b"topic", pause_true),
|
||||||
|
(b"topic", pause_false),
|
||||||
|
(b"topic", next_phase),
|
||||||
|
asyncio.CancelledError, # End loop
|
||||||
|
]
|
||||||
|
|
||||||
|
# Mock internal helpers to verify calls
|
||||||
|
agent._send_to_bdi = AsyncMock()
|
||||||
|
agent._send_to_bdi_belief = AsyncMock()
|
||||||
|
agent._send_pause_command = AsyncMock()
|
||||||
|
agent._send_experiment_control_to_bdi_core = AsyncMock()
|
||||||
|
|
||||||
|
# 4. Run Loop
|
||||||
|
try:
|
||||||
|
await agent._receive_button_event()
|
||||||
|
except asyncio.CancelledError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# 5. Assertions
|
||||||
|
|
||||||
|
# JSON Error
|
||||||
|
agent.logger.error.assert_called_with("Received invalid JSON payload on topic %s", b"topic")
|
||||||
|
|
||||||
|
# Override Trigger
|
||||||
|
agent._send_to_bdi.assert_awaited_with("force_trigger", "trigger_slug")
|
||||||
|
|
||||||
|
# Override Norm
|
||||||
|
# We expect _send_to_bdi_belief to be called for the norm
|
||||||
|
# Note: The loop calls _send_to_bdi_belief(asl_cond_norm, "cond_norm")
|
||||||
|
agent._send_to_bdi_belief.assert_any_call("norm_slug", "cond_norm")
|
||||||
|
|
||||||
|
# Override Fail (Warning log)
|
||||||
|
agent.logger.warning.assert_any_call("Could not determine which element to override.")
|
||||||
|
|
||||||
|
# Unachieve Success
|
||||||
|
# Loop calls _send_to_bdi_belief(asl_cond_norm, "cond_norm", True)
|
||||||
|
agent._send_to_bdi_belief.assert_any_call("norm_slug", "cond_norm", True)
|
||||||
|
|
||||||
|
# Unachieve Fail
|
||||||
|
agent.logger.warning.assert_any_call("Could not determine which conditional norm to unachieve.")
|
||||||
|
|
||||||
|
# Pause Logic
|
||||||
|
agent._send_pause_command.assert_any_call("true")
|
||||||
|
agent.logger.info.assert_any_call("Sent pause command.")
|
||||||
|
|
||||||
|
# Resume Logic
|
||||||
|
agent._send_pause_command.assert_any_call("")
|
||||||
|
agent.logger.info.assert_any_call("Sent resume command.")
|
||||||
|
|
||||||
|
# Next Phase
|
||||||
|
agent._send_experiment_control_to_bdi_core.assert_awaited_with("next_phase")
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_handle_message_unknown_thread(agent):
|
||||||
|
"""Test handling of an unknown message thread (lines 213-214)."""
|
||||||
|
msg = InternalMessage(to="me", thread="unknown_thread", body="test")
|
||||||
|
await agent.handle_message(msg)
|
||||||
|
|
||||||
|
agent.logger.debug.assert_called_with(
|
||||||
|
"Received internal message on unhandled thread: unknown_thread"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_send_to_bdi_belief_edge_cases(agent):
|
||||||
|
"""
|
||||||
|
Covers:
|
||||||
|
- Unknown asl_type warning (lines 326-328)
|
||||||
|
- unachieve=True logic (lines 334-337)
|
||||||
|
"""
|
||||||
|
# 1. Unknown Type
|
||||||
|
await agent._send_to_bdi_belief("slug", "unknown_type")
|
||||||
|
|
||||||
|
agent.logger.warning.assert_called_with("Tried to send belief with unknown type")
|
||||||
|
agent.send.assert_not_called()
|
||||||
|
|
||||||
|
# Reset mock for part 2
|
||||||
|
agent.send.reset_mock()
|
||||||
|
|
||||||
|
# 2. Unachieve = True
|
||||||
|
await agent._send_to_bdi_belief("slug", "cond_norm", unachieve=True)
|
||||||
|
|
||||||
|
agent.send.assert_awaited()
|
||||||
|
sent_msg = agent.send.call_args.args[0]
|
||||||
|
|
||||||
|
# Verify it is a delete operation
|
||||||
|
body_obj = BeliefMessage.model_validate_json(sent_msg.body)
|
||||||
|
|
||||||
|
# Verify 'delete' has content
|
||||||
|
assert body_obj.delete is not None
|
||||||
|
assert len(body_obj.delete) == 1
|
||||||
|
assert body_obj.delete[0].name == "force_slug"
|
||||||
|
|
||||||
|
# Verify 'create' is empty (handling both None and [])
|
||||||
|
assert not body_obj.create
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_send_experiment_control_unknown(agent):
|
||||||
|
"""Test sending an unknown experiment control type (lines 366-367)."""
|
||||||
|
await agent._send_experiment_control_to_bdi_core("invalid_command")
|
||||||
|
|
||||||
|
agent.logger.warning.assert_called_with(
|
||||||
|
"Received unknown experiment control type '%s' to send to BDI Core.", "invalid_command"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Ensure it still sends an empty message (as per code logic, though thread is empty)
|
||||||
|
agent.send.assert_awaited()
|
||||||
|
msg = agent.send.call_args[0][0]
|
||||||
|
assert msg.thread == ""
|
||||||
|
|||||||
Reference in New Issue
Block a user