76 lines
2.4 KiB
Python
76 lines
2.4 KiB
Python
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from agentci.engine.events import (
|
|
JobProgress,
|
|
RuntimeSessionLinked,
|
|
WorkflowCreated,
|
|
WorkflowLinked,
|
|
)
|
|
from agentci.engine.model import Workflow, WorkflowKind
|
|
from agentci.engine.run import JobRun
|
|
|
|
|
|
class RecordingRepository:
|
|
def __init__(self, *, fail_event_ids: set[str] | None = None) -> None:
|
|
self.events: list[tuple[str, object]] = []
|
|
self.fail_event_ids = fail_event_ids or set()
|
|
|
|
async def apply(self, event_id: str, event: object) -> None:
|
|
self.events.append((event_id, event))
|
|
if event_id in self.fail_event_ids:
|
|
raise RuntimeError("write failed")
|
|
|
|
|
|
async def test_job_run_emits_each_report_payload_with_monotonic_ids() -> None:
|
|
repository = RecordingRepository()
|
|
run = JobRun(repository, "job-1", 10) # type: ignore[arg-type]
|
|
workflow = Workflow(
|
|
id="workflow-1",
|
|
kind=WorkflowKind.PLAN,
|
|
repo_owner="alice",
|
|
repo_name="repo",
|
|
issue_number=3,
|
|
workspace_path=Path("/work/repo"),
|
|
base_sha="abc",
|
|
)
|
|
|
|
await run.stage("cloning")
|
|
await run.create_workflow(workflow, "planning")
|
|
await run.link_workflow("workflow-2", "discussing")
|
|
await run.link_session("session-1")
|
|
|
|
assert repository.events == [
|
|
("task:10:report:1", JobProgress(job_id="job-1", stage="cloning")),
|
|
(
|
|
"task:10:report:2",
|
|
WorkflowCreated(job_id="job-1", workflow=workflow, stage="planning"),
|
|
),
|
|
(
|
|
"task:10:report:3",
|
|
WorkflowLinked(job_id="job-1", workflow_id="workflow-2", stage="discussing"),
|
|
),
|
|
(
|
|
"task:10:report:4",
|
|
RuntimeSessionLinked(job_id="job-1", session_id="session-1"),
|
|
),
|
|
]
|
|
|
|
|
|
async def test_failed_report_consumes_only_its_run_sequence_number() -> None:
|
|
repository = RecordingRepository(fail_event_ids={"task:10:report:1"})
|
|
first = JobRun(repository, "job-1", 10) # type: ignore[arg-type]
|
|
second = JobRun(repository, "job-2", 20) # type: ignore[arg-type]
|
|
|
|
with pytest.raises(RuntimeError, match="write failed"):
|
|
await first.stage("cloning")
|
|
await second.stage("fixing")
|
|
await first.link_session("session-1")
|
|
|
|
assert [event_id for event_id, _ in repository.events] == [
|
|
"task:10:report:1",
|
|
"task:20:report:1",
|
|
"task:10:report:2",
|
|
]
|