test: add comprehensive test suite for Phase 2A event bridge
This commit is contained in:
121
tests/conftest.py
Normal file
121
tests/conftest.py
Normal file
@@ -0,0 +1,121 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import pathlib
|
||||
import sys
|
||||
import tempfile
|
||||
from dataclasses import dataclass
|
||||
from typing import Any
|
||||
|
||||
|
||||
REPO_ROOT = pathlib.Path(__file__).resolve().parents[1]
|
||||
EVENTS_DIR = REPO_ROOT / "tools" / "orchestrator-matrix" / "events"
|
||||
if str(EVENTS_DIR) not in sys.path:
|
||||
sys.path.insert(0, str(EVENTS_DIR))
|
||||
|
||||
|
||||
@dataclass
|
||||
class TempPaths:
|
||||
root: pathlib.Path
|
||||
events_path: pathlib.Path
|
||||
cursor_path: pathlib.Path
|
||||
config_path: pathlib.Path
|
||||
|
||||
|
||||
def make_temp_paths() -> tuple[tempfile.TemporaryDirectory[str], TempPaths]:
|
||||
tempdir = tempfile.TemporaryDirectory()
|
||||
root = pathlib.Path(tempdir.name)
|
||||
orch_dir = root / ".mosaic" / "orchestrator"
|
||||
return tempdir, TempPaths(
|
||||
root=root,
|
||||
events_path=orch_dir / "events.ndjson",
|
||||
cursor_path=orch_dir / "event_cursor.json",
|
||||
config_path=orch_dir / "config.json",
|
||||
)
|
||||
|
||||
|
||||
def sample_events() -> list[dict[str, Any]]:
|
||||
return [
|
||||
{
|
||||
"event_type": "task.assigned",
|
||||
"task_id": "TASK-001",
|
||||
"message": "Assigned to codex",
|
||||
"metadata": {"runtime": "codex", "dispatch": "exec"},
|
||||
},
|
||||
{
|
||||
"event_type": "task.started",
|
||||
"task_id": "TASK-001",
|
||||
"message": "Worker execution started",
|
||||
"metadata": {"runtime": "codex", "dispatch": "exec", "attempt": 1, "max_attempts": 3},
|
||||
},
|
||||
{
|
||||
"event_type": "task.completed",
|
||||
"task_id": "TASK-001",
|
||||
"message": "Completed successfully",
|
||||
"metadata": {"task_title": "Finish test suite", "duration_seconds": 12.4},
|
||||
},
|
||||
{
|
||||
"event_type": "task.failed",
|
||||
"task_id": "TASK-002",
|
||||
"message": "Exploded with stack trace",
|
||||
"metadata": {"attempt": 2, "max_attempts": 3},
|
||||
},
|
||||
{
|
||||
"event_type": "task.escalated",
|
||||
"task_id": "TASK-003",
|
||||
"message": "Human review required",
|
||||
"metadata": {"attempt": 1},
|
||||
},
|
||||
{
|
||||
"event_type": "task.gated",
|
||||
"task_id": "TASK-004",
|
||||
"message": "Waiting for quality gates",
|
||||
"metadata": {},
|
||||
},
|
||||
{
|
||||
"event_type": "task.retry.scheduled",
|
||||
"task_id": "TASK-002",
|
||||
"message": "Retry scheduled",
|
||||
"metadata": {"attempt": 3, "max_attempts": 3},
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
def sample_config(
|
||||
*,
|
||||
enabled: bool = True,
|
||||
event_filter: list[str] | None = None,
|
||||
url: str = "https://hooks.example.com/macp",
|
||||
retry_count: int = 1,
|
||||
timeout_seconds: float = 2.0,
|
||||
auth_token: str = "token-123",
|
||||
) -> dict[str, Any]:
|
||||
return {
|
||||
"macp": {
|
||||
"watch_poll_interval_seconds": 0.1,
|
||||
"webhook": {
|
||||
"enabled": enabled,
|
||||
"url": url,
|
||||
"event_filter": list(event_filter or []),
|
||||
"retry_count": retry_count,
|
||||
"timeout_seconds": timeout_seconds,
|
||||
"auth_token": auth_token,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def write_ndjson(path: pathlib.Path, events: list[dict[str, Any]], extra_lines: list[str] | None = None) -> None:
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
lines = [json.dumps(event) for event in events]
|
||||
if extra_lines:
|
||||
lines.extend(extra_lines)
|
||||
path.write_text("\n".join(lines) + "\n", encoding="utf-8")
|
||||
|
||||
|
||||
def append_ndjson(path: pathlib.Path, events: list[dict[str, Any]]) -> None:
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
with path.open("a", encoding="utf-8") as handle:
|
||||
for event in events:
|
||||
handle.write(json.dumps(event))
|
||||
handle.write("\n")
|
||||
Reference in New Issue
Block a user