test: проверка остановки воркера по снятым задачам и устойчивый teardown uploads (T10.1, T10.2)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Andrey Epifancev 2026-10-04 03:29:28 +04:00
parent 5c96189146
commit 6491fdd538

View File

@ -15,6 +15,7 @@ Spec tabular-recognition-service: «Ack раньше результата», «
"""
import asyncio
import contextlib
import copy
import importlib
import io
@ -166,9 +167,13 @@ async def uploads() -> AsyncIterator[Uploads]:
try:
yield store
finally:
for bucket, key in store.keys:
await client.remove_object(bucket, key)
await client.close_session()
try:
for bucket, key in store.keys:
# сбой удаления одного объекта не должен оставлять в MinIO остальные
with contextlib.suppress(Exception):
await client.remove_object(bucket, key)
finally:
await client.close_session()
@pytest.fixture
@ -176,13 +181,17 @@ async def service(monkeypatch: pytest.MonkeyPatch) -> AsyncIterator[None]:
"""Приложение в процессе теста: lifespan с `NATS_ENABLED=True` (в `.env.test` — false); выход — остановка."""
monkeypatch.setattr(app_module.settings, "NATS_ENABLED", True)
application = app_module.app
tasks: list[asyncio.Task[None]] = []
async with application.router.lifespan_context(application):
if not await application.state.nats.wait_ready(READY_TIMEOUT):
pytest.fail(
f"NATS недоступен ({app_module.settings.OPENBAO.NATS.NATS_URL}, .env.test; make up)", pytrace=False
)
tasks = list(application.state.worker._tasks)
yield
assert application.state.worker._tasks == [], "рабочие корутины воркера не остановлены"
# `_tasks` обнуляется в `stop()` безусловно — проверяем сами задачи, снятые до выхода из lifespan
assert tasks, "воркер не запустил рабочие корутины"
assert all(t.done() for t in tasks), "рабочие корутины воркера не остановлены"
@pytest.fixture