"""Тесты для app/core/shutdown.py — кооперативный SIGTERM-флаг (#1182 Phase 2).""" from __future__ import annotations import asyncio import pytest from app.core import shutdown as sd @pytest.fixture(autouse=True) def _reset() -> None: """Event — module-global: сбрасываем до и после каждого теста для изоляции.""" sd.reset_shutdown() yield sd.reset_shutdown() def test_default_not_requested() -> None: """По умолчанию shutdown не запрошен.""" assert sd.shutdown_requested() is False def test_request_sets_flag() -> None: """request_shutdown() выставляет флаг.""" sd.request_shutdown() assert sd.shutdown_requested() is True def test_request_is_idempotent() -> None: """Повторный request_shutdown() безвреден — флаг остаётся True.""" sd.request_shutdown() sd.request_shutdown() assert sd.shutdown_requested() is True def test_reset_clears_flag() -> None: """reset_shutdown() (test-only) снимает флаг.""" sd.request_shutdown() assert sd.shutdown_requested() is True sd.reset_shutdown() assert sd.shutdown_requested() is False @pytest.mark.asyncio async def test_wait_for_shutdown_blocks_until_requested() -> None: """wait_for_shutdown() висит, пока не вызван request_shutdown().""" waiter = asyncio.create_task(sd.wait_for_shutdown()) await asyncio.sleep(0.02) assert not waiter.done(), "не должен завершиться до request_shutdown()" sd.request_shutdown() await asyncio.wait_for(waiter, timeout=1.0) assert waiter.done() @pytest.mark.asyncio async def test_wait_for_shutdown_returns_immediately_if_already_set() -> None: """Если флаг уже выставлен, wait_for_shutdown() возвращается сразу.""" sd.request_shutdown() await asyncio.wait_for(sd.wait_for_shutdown(), timeout=1.0)