78 lines
2.4 KiB
Python
78 lines
2.4 KiB
Python
import asyncio
|
|
import json
|
|
import sys
|
|
from unittest.mock import AsyncMock
|
|
|
|
import pytest
|
|
|
|
from control_backend.agents.bdi.bdi_program_manager import BDIProgramManager
|
|
from control_backend.core.agent_system import InternalMessage
|
|
from control_backend.schemas.belief_message import BeliefMessage
|
|
from control_backend.schemas.program import Program
|
|
|
|
# Fix Windows Proactor loop for zmq
|
|
if sys.platform.startswith("win"):
|
|
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
|
|
|
|
|
|
def make_valid_program_json(norm="N1", goal="G1"):
|
|
return json.dumps(
|
|
{
|
|
"phases": [
|
|
{
|
|
"id": "phase1",
|
|
"label": "Phase 1",
|
|
"triggers": [],
|
|
"norms": [{"id": "n1", "label": "Norm 1", "norm": norm}],
|
|
"goals": [
|
|
{"id": "g1", "label": "Goal 1", "description": goal, "achieved": False}
|
|
],
|
|
}
|
|
]
|
|
}
|
|
)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_send_to_bdi():
|
|
manager = BDIProgramManager(name="program_manager_test")
|
|
manager.send = AsyncMock()
|
|
|
|
program = Program.model_validate_json(make_valid_program_json())
|
|
await manager._send_to_bdi(program)
|
|
|
|
assert manager.send.await_count == 1
|
|
msg: InternalMessage = manager.send.await_args[0][0]
|
|
assert msg.thread == "beliefs"
|
|
|
|
beliefs = BeliefMessage.model_validate_json(msg.body)
|
|
names = {b.name: b.arguments for b in beliefs.beliefs}
|
|
|
|
assert "norms" in names and names["norms"] == ["N1"]
|
|
assert "goals" in names and names["goals"] == ["G1"]
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_receive_programs_valid_and_invalid():
|
|
sub = AsyncMock()
|
|
sub.recv_multipart.side_effect = [
|
|
(b"program", b"{bad json"),
|
|
(b"program", make_valid_program_json().encode()),
|
|
]
|
|
|
|
manager = BDIProgramManager(name="program_manager_test")
|
|
manager.sub_socket = sub
|
|
manager._send_to_bdi = AsyncMock()
|
|
|
|
try:
|
|
# Will give StopAsyncIteration when the predefined `sub.recv_multipart` side-effects run out
|
|
await manager._receive_programs()
|
|
except StopAsyncIteration:
|
|
pass
|
|
|
|
# Only valid Program should have triggered _send_to_bdi
|
|
assert manager._send_to_bdi.await_count == 1
|
|
forwarded: Program = manager._send_to_bdi.await_args[0][0]
|
|
assert forwarded.phases[0].norms[0].norm == "N1"
|
|
assert forwarded.phases[0].goals[0].description == "G1"
|