Files
wiki/tasks/orchestrator/DEV_TASK_FIX_PLANE_MOCKS.md
2026-06-04 22:10:14 +03:00

8.7 KiB
Raw Permalink Blame History

DEV TASK — изолировать 3 теста от живого Plane API (сделать CI зелёным)

Проект: orchestrator | Сервер: slin@82.22.50.71 (pw motoZ@yaz2010, ConnectTimeout=15, StrictHostKeyChecking=no) | Репо (хост): /home/slin/repos/orchestrator | Контейнер: orchestrator (порт 8500) Ветка: fix/isolate-webhook-tests-from-plane из свежего origin/main (git fetch origin main && git checkout -B fix/isolate-webhook-tests-from-plane origin/main).

Контекст / зачем

В PR #26 мы впервые включили Gitea CI для orchestrator. CI прогнал тесты в чистом окружении (БЕЗ сети к Plane) и 3 теста упали — они дёргают живой Plane API и в CI получают Connection refused. Это дефект изоляции тестов (pre-existing), а не баг кода. Локально на хосте они «проходят» только потому что там живой Plane под боком. Нужно замокать сетевые вызовы Plane в этих 3 тестах → CI станет зелёным → гейт качества для self-hosting orchestrator заработает честно.

ВАЖНО: чинить ТОЛЬКО тесты (tests/test_webhooks.py). НЕ трогать src/, логику, поведение. Задача — добавить недостающие @patch, тесты по сути не переписывать.

Точная причина каждого падения (проверено на проде)

Тест 1 — test_plane_webhook_creates_task (tests/test_webhooks.py:59)

  • Путь work_item.createdhandle_work_item_created → внутри вызывается fetch_issue_sequence_id(plane_id, plane_project_id) (src/webhooks/plane.py:448-449) — сетевой вызов к Plane. В CI Connection refused → исключение прерывает цепочку ДО INSERT INTO tasksassert task is not None падает.
  • Код задуман с fallback: если fetch_issue_sequence_id вернёт None → берётся get_next_work_item_id (DB-инкремент). Но реальный сетевой сбой бросает exception, а не None.
  • Фикс теста: добавить @patch на src.webhooks.plane.fetch_issue_sequence_idreturn_value = None (штатный fallback на DB-инкремент, поведение кода НЕ меняется, просто без сети). Также замокать src.webhooks.plane.add_comment (вызывается на :534 после создания, тоже сетевой) — new_callable=MagicMock.
  • Образец: тест уже мокает _create_gitea_branch и _create_initial_docs (AsyncMock) — добавить ещё два @patch к этим.

Тест 2 — test_gitea_push_with_adr_advances_stage (tests/test_webhooks.py:206)

  • Путь gitea push → handle_push → после advance вызывается plane_notify_stage(work_item_id, ...) (src/webhooks/gitea.py:129) — сетевой вызов к Plane → Connection refused → исключение валит до mock_launcher.launch.assert_called_once() (launch вызывается 0 раз / падает раньше).
  • Фикс теста: добавить @patch("src.webhooks.gitea.plane_notify_stage") (MagicMock).

Тест 3 — test_gitea_ci_failure_on_development_notifies_qg_failure (tests/test_webhooks.py:278)

  • Тот же класс проблемы: путь gitea status=failure на development. Проверь точно, какой сетевой вызов Plane срабатывает на этом пути (вероятно plane_notify_stage или add_comment в gitea.py при notify_qg_failure-ветке ~:217-223). Замокать ровно тот, что лезет в сеть.
  • Фикс теста: добавить недостающий @patch на сетевой Plane-вызов в этом пути (src.webhooks.gitea.plane_notify_stage и/или соответствующий). НЕ трогать assert'ы про mock_notify/check_ci_green/stage.

Рабочие образцы моков (уже в этом файле, копировать стиль)

  • tests/test_webhooks.py:151-154@patch("src.webhooks.plane.httpx.get") (как мокают сеть в plane).
  • tests/test_webhooks.py:241-246@patch("src.webhooks.gitea.check_ci_green") + @patch("src.webhooks.gitea.launcher") (как мокают gitea-путь). Тест test_gitea_ci_success_advances_to_review рядом — успешный близнец, посмотри, что он мокает, и сделай по аналогии.
  • Импорты уже есть: from unittest.mock import patch, MagicMock, AsyncMock (строка 5).

Принцип (не нарушать)

  • Мокать НАДО место вызова (src.webhooks.plane.X / src.webhooks.gitea.X), а не источник в plane_sync, т.к. некоторые импорты локальные внутри функций — мок источника не перехватит. Смотри как сделано в conftest.py для send_telegram (там описано почему патчат именно место связывания).
  • Если функция импортируется ЛОКАЛЬНО внутри тела (from ..plane_sync import add_comment внутри функции) — патчить надо src.plane_sync.add_comment (источник), т.к. локальный импорт резолвится в рантайме из источника. Определи для каждого вызова: модульный импорт вверху файла → патчить место (src.webhooks.X.name); локальный импорт внутри функции → патчить источник (src.plane_sync.name). Это критично, проверь по факту, не угадывай.

Проверка (выполнить и приложить пруф)

  1. Прогнать ровно эти 3 теста как в CI (чистое окружение, read-only, без .env):
    docker run --rm -v /home/slin/repos/orchestrator:/code:ro -w /code -e PYTHONPATH=/code \
      --entrypoint python3 $(docker inspect orchestrator --format '{{.Config.Image}}') \
      -m pytest tests/test_webhooks.py::test_plane_webhook_creates_task \
      tests/test_webhooks.py::test_gitea_push_with_adr_advances_stage \
      tests/test_webhooks.py::test_gitea_ci_failure_on_development_notifies_qg_failure -q
    
    — должно быть 3 passed.
  2. Прогнать ВЕСЬ test_webhooks.py тем же способом — убедиться, что ничего не сломал (не появилось новых fail сверх известных 9 HMAC/401, которые из-за .env и в read-only без .env ведут себя стабильно — зафиксируй число).
  3. После push ветки: убедиться, что Gitea Actions прогнал workflow и job test → success (/api/v1/repos/admin/orchestrator/actions/tasks, токен docker exec orchestrator printenv ORCH_GITEA_TOKEN).
  4. git log origin/main..origin/fix/isolate-webhook-tests-from-plane показывает коммит ДО отчёта.

Ограничения / правила

  • ⚠️ PR в Gitea, push в main ЗАПРЕЩЁН (pre-receive hook). НЕ мержить самому — мержит ревьюер (Стрим). Только ветка + PR.
  • Менять ТОЛЬКО tests/test_webhooks.py. НЕ трогать src/, off-limits тесты (9 HMAC/401), conftest.py, workflow-файл.
  • Conventional Commits, один коммит: test: isolate webhook tests from live Plane API (fix CI).
  • ⚠️ НЕ регистрировать новых раннеров, НЕ запускать ничего через nohup. Раннер orchestrator уже есть (mva154-runner-orch). Если CI не подхватывает — СТОП, отчёт, НЕ плоди процессы.
  • Если факт ТЗ разошёлся с реальностью — СТОП, отчёт с вопросом.

Результат

  • PR с правкой только tests/test_webhooks.py, 3 целевых теста зелёные в чистом окружении, workflow прогнан и job test = success, отчёт с пруфом. Сохрани отчёт в tasks/orchestrator/reports/dev-2026-06-04-fix-plane-mocks.md.