refactor tests
Publish container image / Build and push (push) Successful in 32s

This commit is contained in:
2026-07-26 23:49:40 +02:00
parent 5ef10d28fe
commit ce9f1e3d20
32 changed files with 1546 additions and 1923 deletions
+49 -44
View File
@@ -1,7 +1,9 @@
import asyncio
import sqlite3
import threading
from collections.abc import Callable, Coroutine
from contextlib import closing
from pathlib import Path
from typing import Any
import pytest
@@ -9,14 +11,17 @@ from agentci.engine.events import PermissionDenied, PermissionGranted
from agentci.engine.model import IncomingCommand, QueueName, TaskKind
from agentci.engine.repository import Repository
MIGRATIONS = Path(__file__).parents[1] / "src" / "agentci" / "migrations"
async def run_concurrently[T](
*factories: Callable[[], Coroutine[Any, Any, T]],
) -> list[T]:
barrier = threading.Barrier(len(factories))
@pytest.fixture
async def repository(tmp_path: Path) -> Repository:
value = Repository(tmp_path / "state.sqlite3", MIGRATIONS)
await value.initialize()
return value
def run(factory: Callable[[], Coroutine[Any, Any, T]]) -> T:
barrier.wait()
return asyncio.run(factory())
return list(await asyncio.gather(*(asyncio.to_thread(run, factory) for factory in factories)))
def command(delivery: str, *, issue: int = 3) -> IncomingCommand:
@@ -33,91 +38,91 @@ def command(delivery: str, *, issue: int = 3) -> IncomingCommand:
async def test_concurrent_duplicate_accepts_create_one_job_and_event(
repository: Repository,
engine_repository: Repository,
) -> None:
results = await asyncio.gather(
repository.accept(command("delivery-1")),
repository.accept(command("delivery-1")),
results = await run_concurrently(
lambda: engine_repository.accept(command("delivery-1")),
lambda: engine_repository.accept(command("delivery-1")),
)
assert sorted(result.duplicate for result in results) == [False, True]
assert len({result.job.id for result in results}) == 1
with closing(sqlite3.connect(repository.database_path)) as connection, connection:
with closing(sqlite3.connect(engine_repository.database_path)) as connection, connection:
job_count = connection.execute("SELECT COUNT(*) FROM jobs").fetchone()
event_count = connection.execute("SELECT COUNT(*) FROM job_events").fetchone()
assert job_count == (1,)
assert event_count == (1,)
second = await repository.accept(command("delivery-2"))
second = await engine_repository.accept(command("delivery-2"))
assert second.job.receive_sequence == results[0].job.receive_sequence + 1
async def test_received_job_blocks_later_execute_task_for_same_target(
repository: Repository,
engine_repository: Repository,
) -> None:
first = (await repository.accept(command("delivery-1"))).job
second = (await repository.accept(command("delivery-2"))).job
await repository.apply("grant-2", PermissionGranted(job_id=second.id))
first = (await engine_repository.accept(command("delivery-1"))).job
second = (await engine_repository.accept(command("delivery-2"))).job
await engine_repository.apply("grant-2", PermissionGranted(job_id=second.id))
assert await repository.claim_task(QueueName.JOBS) is None
assert await engine_repository.claim_task(QueueName.JOBS) is None
await repository.apply("deny-1", PermissionDenied(job_id=first.id))
task = await repository.claim_task(QueueName.JOBS)
await engine_repository.apply("deny-1", PermissionDenied(job_id=first.id))
task = await engine_repository.claim_task(QueueName.JOBS)
assert task is not None
assert task.job_id == second.id
assert task.kind is TaskKind.EXECUTE
async def test_received_job_does_not_block_a_different_target(
repository: Repository,
engine_repository: Repository,
) -> None:
await repository.accept(command("delivery-1", issue=3))
second = (await repository.accept(command("delivery-2", issue=4))).job
await repository.apply("grant-2", PermissionGranted(job_id=second.id))
await engine_repository.accept(command("delivery-1", issue=3))
second = (await engine_repository.accept(command("delivery-2", issue=4))).job
await engine_repository.apply("grant-2", PermissionGranted(job_id=second.id))
task = await repository.claim_task(QueueName.JOBS)
task = await engine_repository.claim_task(QueueName.JOBS)
assert task is not None
assert task.job_id == second.id
async def test_claims_multiple_eligible_targets_without_duplicates(
repository: Repository,
engine_repository: Repository,
) -> None:
first = (await repository.accept(command("delivery-1", issue=3))).job
second = (await repository.accept(command("delivery-2", issue=4))).job
await repository.apply("grant-1", PermissionGranted(job_id=first.id))
await repository.apply("grant-2", PermissionGranted(job_id=second.id))
first = (await engine_repository.accept(command("delivery-1", issue=3))).job
second = (await engine_repository.accept(command("delivery-2", issue=4))).job
await engine_repository.apply("grant-2", PermissionGranted(job_id=second.id))
await engine_repository.apply("grant-1", PermissionGranted(job_id=first.id))
claimed = [
await repository.claim_task(QueueName.JOBS),
await repository.claim_task(QueueName.JOBS),
await engine_repository.claim_task(QueueName.JOBS),
await engine_repository.claim_task(QueueName.JOBS),
]
assert [task.job_id for task in claimed if task is not None] == [first.id, second.id]
assert await repository.claim_task(QueueName.JOBS) is None
assert await engine_repository.claim_task(QueueName.JOBS) is None
async def test_concurrent_claims_do_not_duplicate_task(repository: Repository) -> None:
await repository.accept(command("delivery-1"))
async def test_concurrent_claims_do_not_duplicate_task(engine_repository: Repository) -> None:
await engine_repository.accept(command("delivery-1"))
claims = await asyncio.gather(
repository.claim_task(QueueName.CONTROL),
repository.claim_task(QueueName.CONTROL),
claims = await run_concurrently(
lambda: engine_repository.claim_task(QueueName.CONTROL),
lambda: engine_repository.claim_task(QueueName.CONTROL),
)
claimed = [task for task in claims if task is not None]
assert len(claimed) == 1
assert claimed[0].kind is TaskKind.AUTHORIZE
assert claimed[0].queue is QueueName.CONTROL
assert await repository.claim_task(QueueName.CONTROL) is None
assert await engine_repository.claim_task(QueueName.CONTROL) is None
async def test_duplicate_event_id_cannot_be_reused_for_another_job(
repository: Repository,
engine_repository: Repository,
) -> None:
first = (await repository.accept(command("delivery-1", issue=3))).job
second = (await repository.accept(command("delivery-2", issue=4))).job
await repository.apply("permission", PermissionGranted(job_id=first.id))
first = (await engine_repository.accept(command("delivery-1", issue=3))).job
second = (await engine_repository.accept(command("delivery-2", issue=4))).job
await engine_repository.apply("permission", PermissionGranted(job_id=first.id))
with pytest.raises(RuntimeError):
await repository.apply("permission", PermissionGranted(job_id=second.id))
await engine_repository.apply("permission", PermissionGranted(job_id=second.id))