From 12e2a9949d9aa316871e556b790d986f085886da Mon Sep 17 00:00:00 2001 From: bot-backend Date: Sat, 12 Sep 2026 16:53:09 +0300 Subject: [PATCH] =?UTF-8?q?perf(tests):=20=D0=B7=D0=B0=D0=B3=D0=BB=D1=83?= =?UTF-8?q?=D1=88=D0=B8=D1=82=D1=8C=20=D1=84=D0=BE=D1=80=D1=81=D0=B0=D0=B9?= =?UTF-8?q?=D1=82-enqueue=20=D0=B2=20analyze-=D1=82=D0=B5=D1=81=D1=82?= =?UTF-8?q?=D0=B0=D1=85=20Site=20Finder?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Claude-Session: https://claude.ai/code/session_01JY6iWDnGDthdvsMWgK1BMG --- backend/tests/api/v1/conftest.py | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/backend/tests/api/v1/conftest.py b/backend/tests/api/v1/conftest.py index 463d56ea..f5741b19 100644 --- a/backend/tests/api/v1/conftest.py +++ b/backend/tests/api/v1/conftest.py @@ -17,12 +17,22 @@ Analyze-тесты с ПОЗИЦИОННЫМ DB-моком (``_make_db_for_analy (``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 patch +from unittest.mock import MagicMock, patch import pytest @@ -37,3 +47,15 @@ def _stub_zone_regulation_resolver() -> Iterator[None]: """ 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