All checks were successful
CI Trade-In / changes (pull_request) Successful in 10s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI Trade-In / browser-tests (pull_request) Has been skipped
CI / changes (pull_request) Successful in 12s
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Successful in 2m9s
CI / backend-tests (pull_request) Successful in 6m46s
analyze_parcel() в конце безусловно дёргает forecast_site_finder_report.delay(...) (best-effort §22-форсайт, обёрнут в try/except). В тестовой песочнице Celery-брокер (Redis) недоступен, и .delay() синхронно ждёт kombu reconnect-backoff (~69с) прежде чем исключение будет проглочено — эта пауза сидела внутри КАЖДОГО теста, дёргающего POST /analyze без мока форсайт-таски (9 файлов tests/api/v1/test_analyze_*.py, test_2464*.py — 32 теста, ~2218 из 2503с полного прогона). Добавлена autouse-фикстура в tests/api/v1/conftest.py по образцу уже существующей _stub_zone_regulation_resolver — глушит .delay в no-op MagicMock для всех тестов каталога. Тесты самого enqueue (test_parcels_forecast.py, test_run_history_and_response_contract.py) переопределяют тот же target своим per-test patch поверх авто-фикстуры (nested mock-scope), их проверки не затронуты. Проверено: 7 целевых файлов (32 теста) — 36.7с суммарно вместо таймаутов по 90с на файл, все зелёные. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JY6iWDnGDthdvsMWgK1BMG
61 lines
4.1 KiB
Python
61 lines
4.1 KiB
Python
"""Общие фикстуры для 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
|