test_orchestration_store.py 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. import json
  2. import pytest
  3. from agent.orchestration.models import (
  4. ArtifactRef,
  5. AttemptSubmission,
  6. TaskLedger,
  7. TaskStatus,
  8. )
  9. from agent.orchestration.state_machine import InvalidTaskTransition, transition
  10. from agent.orchestration.store import (
  11. FileSystemArtifactStore,
  12. FileSystemTaskStore,
  13. RevisionConflict,
  14. )
  15. @pytest.mark.asyncio
  16. async def test_ledger_atomic_revision_and_roundtrip(tmp_path):
  17. store = FileSystemTaskStore(str(tmp_path))
  18. ledger = TaskLedger(root_trace_id="root", mission="mission")
  19. committed = await store.commit(ledger, expected_revision=-1)
  20. assert committed.revision == 0
  21. loaded = await store.load("root")
  22. assert loaded.mission == "mission"
  23. assert loaded.revision == 0
  24. stale = TaskLedger(root_trace_id="root", mission="stale", revision=-1)
  25. with pytest.raises(RevisionConflict):
  26. await store.commit(stale, expected_revision=-1)
  27. on_disk = json.loads((tmp_path / "root" / "orchestration" / "ledger.json").read_text())
  28. assert on_disk["revision"] == 0
  29. @pytest.mark.asyncio
  30. async def test_snapshot_is_immutable_and_hash_is_stable(tmp_path):
  31. store = FileSystemArtifactStore(str(tmp_path)).for_root("root")
  32. submission = AttemptSubmission(
  33. summary=" delivered ",
  34. artifact_refs=[ArtifactRef(uri="file:///result", version="v1")],
  35. evidence_refs=[ArtifactRef(uri="db://row/1", digest="abc")],
  36. )
  37. first = await store.freeze("attempt-1", submission)
  38. second = await store.freeze("attempt-2", submission)
  39. assert first.sha256 == second.sha256
  40. assert (await store.get(first.snapshot_id)).normalized_content["summary"] == "delivered"
  41. with pytest.raises(ValueError, match="version or digest"):
  42. ArtifactRef(uri="file:///mutable")
  43. def test_state_machine_rejects_shortcut_to_completed():
  44. assert transition(TaskStatus.PENDING, TaskStatus.RUNNING) == TaskStatus.RUNNING
  45. with pytest.raises(InvalidTaskTransition):
  46. transition(TaskStatus.RUNNING, TaskStatus.COMPLETED)