fix(tests): изолировать тесты от instance_settings в общей dev-БД
Тесты читали ту же instance_settings, что и dev-стенд: выключение chat/hand_queue в админке роняло пачку тестов, не связанных с самим переключением (наступила сессия 0.0.28). Фикстура clean_instance_settings (явная, не autouse — DELETE в savepoint держит блокировку строки до конца внешней транзакции теста, автовключение на тестах с отдельными подключениями к БД дало саморазблокировку) удаляет управляемые ключи перед тестом, чтение конфигурации падает на дефолты pydantic-моделей. Подключена в test_chat_ws.py и test_hand_queue_ws.py. MANAGED_KEYS в services/instance_settings.py — единый список управляемых ключей вместо локальной копии в тестовом файле.
This commit is contained in:
@@ -12,15 +12,12 @@
|
||||
видеть реально закоммиченную строку (см. docstring `test_pipeline.py`),
|
||||
поэтому там запись делается через отдельное подключение к `core.db.engine`.
|
||||
|
||||
Тесты, которым нужен «чистый стол» по управляемым ключам `instance_settings`
|
||||
(бутстрап дефолтов, дефолтные значения после патча), используют фикстуру
|
||||
`clean_instance_settings` — она сохраняет текущие строки этих ключей в
|
||||
рамках транзакции теста и восстанавливает их после (не `TRUNCATE`): в общей
|
||||
dev-БД эти строки могут быть легитимными данными разработчика, тест не
|
||||
должен от них зависеть, но и не должен их безвозвратно стирать. Тест с
|
||||
`run_pipeline_async` не может использовать эту фикстуру (пишет через
|
||||
отдельное подключение) — там то же сохранение/восстановление сделано вручную
|
||||
через реальный коннекшн.
|
||||
«Чистый стол» по управляемым ключам `instance_settings` обеспечивает общая (НЕ
|
||||
autouse — см. её докстринг про само-дедлок с тестами на реальных подключениях)
|
||||
фикстура `tests.conftest.clean_instance_settings` — тесты, которым нужен чистый
|
||||
стол, запрашивают её явно параметром. Тест с `run_pipeline_async` пишет через
|
||||
отдельное подключение (мимо savepoint) и её не запрашивает — там сохранение/
|
||||
восстановление сделано вручную через реальный коннекшн, см. его докстринг.
|
||||
"""
|
||||
|
||||
import uuid
|
||||
@@ -61,24 +58,6 @@ from workers.tasks.pipeline import run_pipeline_async
|
||||
PLUGINS_YAML = "../config/plugins.yaml"
|
||||
NOW = datetime.now(UTC)
|
||||
|
||||
# Все ключи, которыми управляет `InstanceSettingsService` (см. `_KEY_*` там же).
|
||||
_MANAGED_KEYS = (
|
||||
"transcriber",
|
||||
"summarizer",
|
||||
"chat",
|
||||
"hand_queue",
|
||||
"ai_level",
|
||||
"summary_recipients",
|
||||
"display_timezone",
|
||||
"registration_team_choice",
|
||||
"registration_email_domain",
|
||||
"contact_email",
|
||||
"media_limits",
|
||||
"consent_policy",
|
||||
"device_check",
|
||||
"virtual_background",
|
||||
)
|
||||
|
||||
|
||||
class _FakeTask:
|
||||
"""Минимальная заглушка bound-задачи Celery (см. `test_pipeline.py`)."""
|
||||
@@ -87,32 +66,6 @@ class _FakeTask:
|
||||
self.retry = MagicMock()
|
||||
|
||||
|
||||
@pytest_asyncio.fixture
|
||||
async def clean_instance_settings(db_session: AsyncSession) -> AsyncGenerator[None, None]:
|
||||
"""Изолировать тест от уже существующих строк управляемых ключей `instance_settings`.
|
||||
|
||||
Сохраняет текущие значения (если есть) в рамках `db_session` (savepoint,
|
||||
никогда не коммитится в реальную БД — см. `conftest.py`), удаляет их,
|
||||
отдаёт управление тесту, затем восстанавливает исходные значения —
|
||||
точечно, только эти ключи, не `TRUNCATE`.
|
||||
"""
|
||||
result = await db_session.execute(
|
||||
select(InstanceSetting).where(InstanceSetting.key.in_(_MANAGED_KEYS))
|
||||
)
|
||||
saved: dict[str, Any] = {row.key: row.value for row in result.scalars().all()}
|
||||
await db_session.execute(delete(InstanceSetting).where(InstanceSetting.key.in_(_MANAGED_KEYS)))
|
||||
await db_session.commit()
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
await db_session.execute(
|
||||
delete(InstanceSetting).where(InstanceSetting.key.in_(_MANAGED_KEYS))
|
||||
)
|
||||
for key, value in saved.items():
|
||||
db_session.add(InstanceSetting(key=key, value=value))
|
||||
await db_session.commit()
|
||||
|
||||
|
||||
async def test_ensure_bootstrapped_imports_yaml_defaults(
|
||||
db_session: AsyncSession, clean_instance_settings: None
|
||||
) -> None:
|
||||
|
||||
Reference in New Issue
Block a user