89 lines
2.6 KiB
Python
89 lines
2.6 KiB
Python
import anyio
|
|
import pytest
|
|
|
|
from takopi.exec_bridge import CodexExecRunner, EventCallback
|
|
|
|
|
|
@pytest.mark.anyio
|
|
async def test_run_serialized_serializes_same_session() -> None:
|
|
runner = CodexExecRunner(codex_cmd="codex", extra_args=[])
|
|
gate = anyio.Event()
|
|
in_flight = 0
|
|
max_in_flight = 0
|
|
|
|
async def run_stub(*_args, **_kwargs):
|
|
nonlocal in_flight, max_in_flight
|
|
in_flight += 1
|
|
max_in_flight = max(max_in_flight, in_flight)
|
|
await gate.wait()
|
|
in_flight -= 1
|
|
return ("sid", "ok", True)
|
|
|
|
runner.run = run_stub # type: ignore[assignment]
|
|
|
|
async with anyio.create_task_group() as tg:
|
|
tg.start_soon(runner.run_serialized, "a", "sid")
|
|
tg.start_soon(runner.run_serialized, "b", "sid")
|
|
await anyio.sleep(0)
|
|
gate.set()
|
|
|
|
assert max_in_flight == 1
|
|
|
|
|
|
@pytest.mark.anyio
|
|
async def test_run_serialized_allows_parallel_new_sessions() -> None:
|
|
runner = CodexExecRunner(codex_cmd="codex", extra_args=[])
|
|
gate = anyio.Event()
|
|
in_flight = 0
|
|
max_in_flight = 0
|
|
|
|
async def run_stub(*_args, **_kwargs):
|
|
nonlocal in_flight, max_in_flight
|
|
in_flight += 1
|
|
max_in_flight = max(max_in_flight, in_flight)
|
|
await gate.wait()
|
|
in_flight -= 1
|
|
return ("sid", "ok", True)
|
|
|
|
runner.run = run_stub # type: ignore[assignment]
|
|
|
|
async with anyio.create_task_group() as tg:
|
|
tg.start_soon(runner.run_serialized, "a", None)
|
|
tg.start_soon(runner.run_serialized, "b", None)
|
|
with anyio.move_on_after(1):
|
|
while max_in_flight < 2:
|
|
await anyio.sleep(0)
|
|
gate.set()
|
|
|
|
assert max_in_flight == 2
|
|
|
|
|
|
@pytest.mark.anyio
|
|
async def test_new_session_holds_lock_for_resumes() -> None:
|
|
runner = CodexExecRunner(codex_cmd="codex", extra_args=[])
|
|
finish = anyio.Event()
|
|
resume_started = anyio.Event()
|
|
|
|
async def run_stub(
|
|
_prompt: str,
|
|
session_id: str | None,
|
|
on_event: EventCallback | None = None,
|
|
) -> tuple[str, str, bool]:
|
|
if session_id is None:
|
|
if on_event:
|
|
await on_event({"type": "thread.started", "thread_id": "sid"})
|
|
await finish.wait()
|
|
return ("sid", "ok", True)
|
|
resume_started.set()
|
|
return ("sid", "ok", True)
|
|
|
|
runner.run = run_stub # type: ignore[assignment]
|
|
|
|
async with anyio.create_task_group() as tg:
|
|
tg.start_soon(runner.run_serialized, "first", None)
|
|
await anyio.sleep(0)
|
|
tg.start_soon(runner.run_serialized, "resume", "sid")
|
|
await anyio.sleep(0)
|
|
assert not resume_started.is_set()
|
|
finish.set()
|