perf(tests): заглушить форсайт-enqueue в analyze-тестах Site Finder #3502
1 changed files with 42 additions and 1 deletions
|
|
@ -17,12 +17,22 @@ Analyze-тесты с ПОЗИЦИОННЫМ DB-моком (``_make_db_for_analy
|
||||||
(``test_analyze_zoning_regulation.py``), переопределяют этот же target своим
|
(``test_analyze_zoning_regulation.py``), переопределяют этот же target своим
|
||||||
per-test ``patch`` — он применяется ПОВЕРХ авто-фикстуры (вложенный mock-scope), так
|
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 __future__ import annotations
|
||||||
|
|
||||||
from collections.abc import Iterator
|
from collections.abc import Iterator
|
||||||
from unittest.mock import patch
|
from unittest.mock import MagicMock, patch
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
|
@ -37,3 +47,34 @@ def _stub_zone_regulation_resolver() -> Iterator[None]:
|
||||||
"""
|
"""
|
||||||
with patch("app.api.v1.parcels.get_or_fetch_zone_regulation", return_value=None):
|
with patch("app.api.v1.parcels.get_or_fetch_zone_regulation", return_value=None):
|
||||||
yield
|
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)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue