- conformance.py: declarative scenario runner (subset matcher, $kind/$gt/ $enum/$required assertions, call_id/session_id echo checks), reference bridge, CLI entry (python -m aicc.conformance) - bridge.py: protocol version check before parsing (protocol_mismatch), session expiry handling (session_expired), malformed tool_call -> invalid_input, emit_event() for async events - client.py: Self return type - in_process.py: drain bridge event queue after response (event delivery), Self return type - websocket.py: Self return type, best-effort shutdown - tests: 14 passing (incl. conformance scenarios, 9/9 core scenarios) - ruff: all checks pass
34 lines
1.1 KiB
Python
34 lines
1.1 KiB
Python
"""Conformance runner tests: runs the declarative scenarios from the spec repo."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from aicc.conformance import reference_bridge, run_scenarios, summarize
|
|
|
|
SCENARIOS = Path(__file__).resolve().parents[1] / ".." / "aicc-spec" / "conformance" / "scenarios"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_core_scenarios_pass():
|
|
if not SCENARIOS.exists():
|
|
pytest.skip("AICC-Protocol conformance scenarios not found on this machine")
|
|
bridge = reference_bridge()
|
|
results = await run_scenarios(bridge, SCENARIOS)
|
|
report = summarize(results)
|
|
assert all(r.passed for r in results), report
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_runner_rejects_unknown_tool():
|
|
"""A bridge missing a required tool fails the corresponding scenario."""
|
|
from aicc import Bridge
|
|
|
|
bridge = Bridge(name="incomplete")
|
|
results = await run_scenarios(bridge, SCENARIOS)
|
|
by_id = {r.id: r for r in results}
|
|
# echo tool missing -> core-03 must fail
|
|
assert not by_id["core-03-tool-call-ok"].passed
|