Initial commit
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import contextlib
|
||||
import shutil
|
||||
import unittest
|
||||
import uuid
|
||||
from pathlib import Path
|
||||
from unittest.mock import AsyncMock
|
||||
|
||||
from opc.core.models import ExecutionCheckpoint, SessionCompactionRecord, Task, TaskStatus
|
||||
from opc.database.store import OPCStore
|
||||
from opc.engine import OPCEngine
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def _workspace_tempdir() -> Path:
|
||||
base = Path.cwd() / ".tmp-test" / f"runtime-migration-{uuid.uuid4().hex}"
|
||||
base.mkdir(parents=True, exist_ok=True)
|
||||
try:
|
||||
yield base
|
||||
finally:
|
||||
shutil.rmtree(base, ignore_errors=True)
|
||||
|
||||
|
||||
class RuntimeV2MigrationTests(unittest.IsolatedAsyncioTestCase):
|
||||
async def test_checkpoint_lookup_migrates_legacy_payload_to_runtime_v2(self) -> None:
|
||||
with _workspace_tempdir() as tmpdir:
|
||||
store = OPCStore(tmpdir / "tasks.db")
|
||||
await store.initialize()
|
||||
task = Task(
|
||||
id="task-1",
|
||||
title="Need approval",
|
||||
session_id="sess-1",
|
||||
project_id="proj1",
|
||||
status=TaskStatus.AWAITING_REVIEW,
|
||||
metadata={},
|
||||
)
|
||||
await store.save_task(task)
|
||||
checkpoint = ExecutionCheckpoint(
|
||||
project_id="proj1",
|
||||
session_id="sess-1",
|
||||
checkpoint_type="task_user_input",
|
||||
task_id=task.id,
|
||||
payload={
|
||||
"task_id": task.id,
|
||||
"pause_request": {"reason": "Need confirmation"},
|
||||
"tool_name": "shell_exec",
|
||||
},
|
||||
)
|
||||
await store.save_execution_checkpoint(checkpoint)
|
||||
|
||||
engine = OPCEngine()
|
||||
engine.project_id = "proj1"
|
||||
engine.store = store
|
||||
|
||||
migrated = await engine.get_latest_pending_checkpoint_for_session("sess-1")
|
||||
assert migrated is not None
|
||||
self.assertIn("runtime_v2", migrated.payload)
|
||||
runtime_state = migrated.payload["runtime_v2"]
|
||||
self.assertTrue(runtime_state["runtime_session_id"].startswith("rtmig_"))
|
||||
self.assertTrue(runtime_state["migrated_from_legacy"])
|
||||
refreshed_task = await store.get_task(task.id)
|
||||
self.assertEqual(refreshed_task.metadata["migration_status"], "runtime_v2_migrated")
|
||||
self.assertEqual(
|
||||
refreshed_task.metadata["runtime_v2"]["runtime_session_id"],
|
||||
runtime_state["runtime_session_id"],
|
||||
)
|
||||
await store.close()
|
||||
|
||||
async def test_migrated_runtime_state_carries_legacy_compaction_boundary(self) -> None:
|
||||
with _workspace_tempdir() as tmpdir:
|
||||
store = OPCStore(tmpdir / "tasks.db")
|
||||
await store.initialize()
|
||||
task = Task(
|
||||
id="task-legacy",
|
||||
title="Legacy compacted session",
|
||||
session_id="sess-legacy",
|
||||
project_id="proj1",
|
||||
status=TaskStatus.AWAITING_REVIEW,
|
||||
)
|
||||
await store.save_task(task)
|
||||
await store.save_session_compaction(
|
||||
SessionCompactionRecord(
|
||||
session_id="sess-legacy",
|
||||
compaction_message_id="msg-compact",
|
||||
source_boundary_message_id="msg-boundary",
|
||||
)
|
||||
)
|
||||
engine = OPCEngine()
|
||||
engine.project_id = "proj1"
|
||||
engine.store = store
|
||||
|
||||
runtime_state = await engine._build_migrated_runtime_state(
|
||||
task,
|
||||
checkpoint_type="task_user_input",
|
||||
payload={},
|
||||
)
|
||||
|
||||
self.assertEqual(runtime_state["compaction_boundaries"][0]["source_boundary_message_id"], "msg-boundary")
|
||||
await store.close()
|
||||
|
||||
async def test_resume_task_checkpoint_restores_migrated_runtime_state(self) -> None:
|
||||
with _workspace_tempdir() as tmpdir:
|
||||
store = OPCStore(tmpdir / "tasks.db")
|
||||
await store.initialize()
|
||||
task = Task(
|
||||
id="task-2",
|
||||
title="Resume task",
|
||||
session_id="sess-2",
|
||||
project_id="proj1",
|
||||
status=TaskStatus.AWAITING_REVIEW,
|
||||
metadata={},
|
||||
)
|
||||
await store.save_task(task)
|
||||
checkpoint = ExecutionCheckpoint(
|
||||
project_id="proj1",
|
||||
session_id="sess-2",
|
||||
checkpoint_type="task_user_input",
|
||||
task_id=task.id,
|
||||
payload={
|
||||
"task_id": task.id,
|
||||
"task_ids": [task.id],
|
||||
"execution_mode": "task_mode",
|
||||
"pause_request": {"reason": "Need confirmation"},
|
||||
},
|
||||
)
|
||||
await store.save_execution_checkpoint(checkpoint)
|
||||
|
||||
engine = OPCEngine()
|
||||
engine.project_id = "proj1"
|
||||
engine.store = store
|
||||
engine._execute_single_agent = AsyncMock(return_value="resumed") # type: ignore[method-assign]
|
||||
|
||||
response = await engine._resume_task_checkpoint(checkpoint, "continue")
|
||||
|
||||
self.assertEqual(response, "resumed")
|
||||
resumed_task = await store.get_task(task.id)
|
||||
self.assertIn("runtime_resume", resumed_task.context_snapshot)
|
||||
self.assertTrue(
|
||||
resumed_task.context_snapshot["runtime_resume"]["runtime_session_id"].startswith("rtmig_")
|
||||
)
|
||||
await store.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user