gendesign/backend/tests/api/v1/conftest.py
bot-backend 98a582e242
All checks were successful
Deploy / changes (push) Successful in 7s
Deploy / build-frontend (push) Has been skipped
Deploy / deploy-caddy (push) Has been skipped
Deploy / build-backend (push) Successful in 39s
Deploy / build-worker (push) Successful in 40s
Deploy / deploy (push) Successful in 1m12s
Deploy / deploy-status (push) Successful in 1s
Deploy / perimeter-smoke (push) Successful in 1m41s
perf(tests): убрать фиксированные ожидания из analyze-тестов Site Finder (#3502)
Co-authored-by: bot-backend <bot-backend@gendsgn.local>
Co-committed-by: bot-backend <bot-backend@gendsgn.local>
2026-09-12 14:09:23 +00:00

80 lines
5.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Общие фикстуры для api/v1 analyze-тестов.
PR-A (#1891) сделал geoportal зон-резолвер (``get_or_fetch_zone_regulation``)
БЕЗУСЛОВНЫМ в ``analyze_parcel`` — раньше он был gated за наличием dump-зоны
(``_nspd_zoning is not None``), теперь вызывается для любого ЕКБ-участка с centroid.
Analyze-тесты с ПОЗИЦИОННЫМ DB-моком (``_make_db_for_analyze`` + ``call_idx``/
``responses[...]``) НЕ мокали резолвер (до PR-A он не вызывался). Новый безусловный
вызов добавляет ``db.execute`` (get_cached) → сдвигает последовательность ответов
мока → последующие запросы (напр. ``parcel_meta``) получают чужой/пустой ответ и
становятся ``None``. Локально проходило (резолвер мог не разрезолвить точку), в CI
падало (``test_parcel_meta_found_in_cad_parcels``).
Авто-фикстура по умолчанию глушит резолвер в no-op (``return None``) для ВСЕХ тестов
в этом каталоге → блок 9e-bis ничего не синтезирует и не трогает БД (поведение
идентично до-PR-A). Тесты, которые проверяют САМ резолвер
(``test_analyze_zoning_regulation.py``), переопределяют этот же target своим
per-test ``patch`` — он применяется ПОВЕРХ авто-фикстуры (вложенный mock-scope), так
что их ожидаемые значения резолвера сохраняются.
Perf-fix (2026-09-12): в конце ``analyze_parcel`` — безусловный best-effort
``forecast_site_finder_report.delay(...)`` (§22-форсайт enqueue, см. app/api/v1/parcels.py).
В песочнице тестов Celery-брокер (Redis) недоступен → ``.delay()`` синхронно ждёт
kombu-реконнект с растущим backoff (~69с) ДО того как try/except его проглотит —
эта пауза оказалась внутри КАЖДОГО теста, который дергает ``POST /analyze`` и не
мокал форсайт-таску. Авто-фикстура ниже глушит ``.delay`` в no-op-мок для ВСЕХ
тестов каталога (как и с резолвером выше) — тесты самого enqueue
(``test_parcels_forecast.py``, ``test_run_history_and_response_contract.py``)
переопределяют тот же target своим per-test ``patch`` поверх авто-фикстуры.
"""
from __future__ import annotations
from collections.abc import Iterator
from unittest.mock import MagicMock, patch
import pytest
@pytest.fixture(autouse=True)
def _stub_zone_regulation_resolver() -> Iterator[None]:
"""No-op geoportal зон-резолвер по умолчанию (без сети, без desync DB-мока).
``return None`` → ``analyze`` не синтезирует ``nspd_zoning`` и не делает лишних
``db.execute``. Тесты резолвера переопределяют ``get_or_fetch_zone_regulation``
своим ``patch`` per-test.
"""
with patch("app.api.v1.parcels.get_or_fetch_zone_regulation", return_value=None):
yield
@pytest.fixture(autouse=True)
def _stub_forecast_enqueue() -> Iterator[None]:
"""No-op форсайт-enqueue по умолчанию (без реального Celery/Redis round-trip).
``.delay(...)`` в проде — fire-and-forget (best-effort, обёрнут в try/except в
``analyze_parcel``), тестам сам форсайт не нужен, а живой брокер в CI/локальной
песочнице недоступен и держит запрос ~69с на реконнект-backoff.
"""
with patch("app.workers.tasks.forecast.forecast_site_finder_report.delay", MagicMock()):
yield
@pytest.fixture(autouse=True)
def _fast_inline_fetch_wait(monkeypatch: pytest.MonkeyPatch) -> None:
"""Схлопнуть inline-ожидание NSPD-фетча (#93 graceful fallback) до миллисекунд.
В ``analyze_parcel`` ветка «участка нет в БД» ждёт появления геометрии циклом
``sleep(_INLINE_FETCH_POLL_INTERVAL_S)`` до ``_INLINE_FETCH_WAIT_S`` (15с прод-
значение). В тестах фетч замокан и геометрия не появится никогда → каждый такой
тест честно спал 16с (``test_market_price_invalid_cad_returns_404``,
``test_recent_permits_invalid_cad_no_regression``).
Оставляем цикл РАБОЧИМ (несколько итераций по 10мс), а не выключаем его нулём:
тесты, проверяющие сам fast-path «строка появилась на N-м опросе», продолжают
видеть опросы. Тесты с собственным ``patch`` того же имени (напр.
``test_run_history_and_response_contract.py``) переопределяют это поверх.
"""
monkeypatch.setattr("app.api.v1.parcels._INLINE_FETCH_WAIT_S", 0.05)
monkeypatch.setattr("app.api.v1.parcels._INLINE_FETCH_POLL_INTERVAL_S", 0.01)