"""Tests for in-memory state backend (Redis tested in integration).""" import asyncio import sys from pathlib import Path sys.path.insert(0, str(Path(__file__).parent.parent)) from tests.conftest import _run from app.models import EventType, RunEvent, RunRecord, RunStatus def _make_run(run_id: str = "gr_test_001") -> RunRecord: return RunRecord( run_id=run_id, graph="release_check", status=RunStatus.QUEUED, agent_id="sofiia", workspace_id="daarion", user_id="u_001", ) class TestMemoryBackend: def test_save_and_get_run(self): from app.state_backend import MemoryStateBackend backend = MemoryStateBackend() run = _make_run("gr_001") _run(backend.save_run(run)) fetched = _run(backend.get_run("gr_001")) assert fetched is not None assert fetched.run_id == "gr_001" assert fetched.status == RunStatus.QUEUED def test_get_missing_run_returns_none(self): from app.state_backend import MemoryStateBackend backend = MemoryStateBackend() assert _run(backend.get_run("does_not_exist")) is None def test_append_and_get_events(self): from app.state_backend import MemoryStateBackend backend = MemoryStateBackend() run = _make_run("gr_002") _run(backend.save_run(run)) ev1 = RunEvent(ts="2026-01-01T00:00:00Z", type=EventType.NODE_START, node="start_job") ev2 = RunEvent(ts="2026-01-01T00:00:01Z", type=EventType.TOOL_CALL, tool="job_orchestrator_tool", details={"hash": "abc123", "size": 200}) _run(backend.append_event("gr_002", ev1)) _run(backend.append_event("gr_002", ev2)) events = _run(backend.get_events("gr_002")) assert len(events) == 2 assert events[0].type == EventType.NODE_START assert events[1].tool == "job_orchestrator_tool" # Events should NOT contain payload content assert "size" in events[1].details def test_cancel_queued_run(self): from app.state_backend import MemoryStateBackend backend = MemoryStateBackend() run = _make_run("gr_003") _run(backend.save_run(run)) ok = _run(backend.cancel_run("gr_003")) assert ok is True fetched = _run(backend.get_run("gr_003")) assert fetched.status == RunStatus.CANCELLED def test_cancel_completed_run_returns_false(self): from app.state_backend import MemoryStateBackend backend = MemoryStateBackend() run = _make_run("gr_004") run.status = RunStatus.SUCCEEDED _run(backend.save_run(run)) ok = _run(backend.cancel_run("gr_004")) assert ok is False def test_update_run_status(self): from app.state_backend import MemoryStateBackend backend = MemoryStateBackend() run = _make_run("gr_005") _run(backend.save_run(run)) run.status = RunStatus.RUNNING run.started_at = "2026-01-01T00:00:00Z" _run(backend.save_run(run)) fetched = _run(backend.get_run("gr_005")) assert fetched.status == RunStatus.RUNNING assert fetched.started_at == "2026-01-01T00:00:00Z"