201 lines
9.0 KiB
YAML
201 lines
9.0 KiB
YAML
work_item: ORCH-053
|
||
description: >
|
||
Тесты sweeper/reconciler потерянных webhook. Вся сеть (Plane API, Gitea API, QG)
|
||
мокируется (monkeypatch), как в существующих tests/. Telegram заглушён autouse-фикстурой
|
||
conftest. Используется временная SQLite БД (ORCH_DB_PATH / фикстура setup_db по образцу
|
||
test_webhooks.py / test_queue.py). Реальные агенты/CLI не запускаются.
|
||
|
||
tests:
|
||
# ---- F-1: gate-side sweeper -------------------------------------------------
|
||
- id: TC-01
|
||
type: unit
|
||
description: >
|
||
reconcile_gate_once продвигает застрявшую development-задачу: нет активных job,
|
||
updated_at старше grace, check_ci_green замокан в (True, "CI green") →
|
||
advance_stage вызван, стадия стала review, заenqueuen reviewer.
|
||
module: tests/test_reconciler.py
|
||
expected: PASS
|
||
|
||
- id: TC-02
|
||
type: unit
|
||
description: >
|
||
Источник истины — гейт: reconciler НЕ содержит собственного update_task_stage/
|
||
enqueue_job для advance — продвижение идёт строго через stage_engine.advance_stage
|
||
(проверка через мок/spy advance_stage, вызван с finished_agent=None).
|
||
module: tests/test_reconciler.py
|
||
expected: PASS
|
||
|
||
- id: TC-03
|
||
type: unit
|
||
description: >
|
||
Задача с активным job (has_active_job_for_task=True) пропускается: гейт не дёргается,
|
||
advance_stage не вызывается, нотификаций нет.
|
||
module: tests/test_reconciler.py
|
||
expected: PASS
|
||
|
||
- id: TC-04
|
||
type: unit
|
||
description: >
|
||
Per-stage grace: задача с updated_at свежее grace своей стадии не трогается;
|
||
ровно на границе age>=grace и без активного job — становится кандидатом.
|
||
module: tests/test_reconciler.py
|
||
expected: PASS
|
||
|
||
- id: TC-05
|
||
type: unit
|
||
description: >
|
||
grace_for_stage читает reconcile_grace_overrides_json (per-stage), при отсутствии
|
||
ключа — reconcile_grace_default_s; невалидный JSON → дефолт, не падает.
|
||
module: tests/test_reconciler.py
|
||
expected: PASS
|
||
|
||
- id: TC-06
|
||
type: unit
|
||
description: >
|
||
Нет спама: при стабильно красном гейте (check_ci_green=(False,...)) несколько проходов
|
||
подряд НЕ вызывают notify_qg_failure повторно на каждом тике; задача не продвигается.
|
||
module: tests/test_reconciler.py
|
||
expected: PASS
|
||
|
||
- id: TC-07
|
||
type: unit
|
||
description: >
|
||
Тишина при синхронности: когда все задачи done / имеют активный job / в пределах grace —
|
||
проход не вызывает advance_stage и не пишет INFO-логов о разблокировке.
|
||
module: tests/test_reconciler.py
|
||
expected: PASS
|
||
|
||
- id: TC-08
|
||
type: unit
|
||
description: >
|
||
AC-16: задача на analysis с артефактами на диске, но Plane НЕ Approved — F-1
|
||
(reconcile_gate_once) НЕ продвигает analysis→architecture.
|
||
module: tests/test_reconciler.py
|
||
expected: PASS
|
||
|
||
- id: TC-09
|
||
type: unit
|
||
description: >
|
||
Never-raise: если обработка одной задачи кидает исключение (advance_stage замокан на
|
||
raise), проход ловит его и продолжает обрабатывать остальные задачи; поток не падает.
|
||
module: tests/test_reconciler.py
|
||
expected: PASS
|
||
|
||
- id: TC-10
|
||
type: unit
|
||
description: >
|
||
Kill-switch: при reconcile_enabled=False reconcile_gate_once/plane_once не выполняют
|
||
действий (no-op); при reconcile_plane_enabled=False гасится только F-2.
|
||
module: tests/test_reconciler.py
|
||
expected: PASS
|
||
|
||
# ---- F-2: plane-side reconciler --------------------------------------------
|
||
- id: TC-11
|
||
type: unit
|
||
description: >
|
||
In Progress без задачи: list_issues_by_state возвращает issue в In Progress, в БД задачи
|
||
нет → reconcile_plane_once вызывает handle_status_start (мок) ровно один раз с корректным
|
||
issue_data (id/state/project).
|
||
module: tests/test_reconciler_plane.py
|
||
expected: PASS
|
||
|
||
- id: TC-12
|
||
type: unit
|
||
description: >
|
||
Approved без advance: issue=Approved, task существует, нет активного job → вызван
|
||
handle_verdict(approved=True) (мок) один раз.
|
||
module: tests/test_reconciler_plane.py
|
||
expected: PASS
|
||
|
||
- id: TC-13
|
||
type: unit
|
||
description: >
|
||
Rejected без rollback: issue=Rejected, task существует, нет активного job → вызван
|
||
handle_verdict(approved=False) (мок) один раз.
|
||
module: tests/test_reconciler_plane.py
|
||
expected: PASS
|
||
|
||
- id: TC-14
|
||
type: unit
|
||
description: >
|
||
Идемпотентность F-2: issue в требующем-действия статусе, но у task есть активный job →
|
||
handle_status_start/handle_verdict НЕ вызываются (живой webhook в работе).
|
||
module: tests/test_reconciler_plane.py
|
||
expected: PASS
|
||
|
||
- id: TC-15
|
||
type: integration
|
||
description: >
|
||
AC-4 анти-дубль на создании: одновременная реконсиляция + обработка реального In Progress
|
||
webhook для одного plane_id создают ровно ОДИН task row и один стартовый analyst-job
|
||
(реальная временная БД, мок Gitea/Plane сетевых вызовов).
|
||
module: tests/test_reconciler_plane.py
|
||
expected: PASS
|
||
|
||
- id: TC-16
|
||
type: unit
|
||
description: >
|
||
list_issues_by_state never-raise: при ошибке Plane API (httpx бросает / non-2xx) →
|
||
возвращает [], тик не падает; при успехе — обходит пагинацию и фильтрует по state.
|
||
module: tests/test_reconciler_plane.py
|
||
expected: PASS
|
||
|
||
- id: TC-17
|
||
type: unit
|
||
description: >
|
||
F-2 опрашивает все проекты реестра projects.PROJECTS и резолвит state-uuid через
|
||
get_project_states per-project (enduro + orchestrator), не хардкодит uuid.
|
||
module: tests/test_reconciler_plane.py
|
||
expected: PASS
|
||
|
||
# ---- F-3: sha→branch резолв -------------------------------------------------
|
||
- id: TC-18
|
||
type: unit
|
||
description: >
|
||
handle_ci_status: при отсутствии branches и неразрезолвленном sha срабатывает БД-fallback
|
||
и однозначно находит единственную development-задачу repo; продвижение идёт штатно.
|
||
module: tests/test_gitea_sha_resolve.py
|
||
expected: PASS
|
||
|
||
- id: TC-19
|
||
type: unit
|
||
description: >
|
||
handle_ci_status: при неоднозначности (несколько development-задач repo) БД-fallback не
|
||
делает ложный матч (branch остаётся неразрезолвленным, лог INFO), success/failure-семантика
|
||
гейта не изменена.
|
||
module: tests/test_gitea_sha_resolve.py
|
||
expected: PASS
|
||
|
||
# ---- F-4 / интеграция фонового потока --------------------------------------
|
||
- id: TC-20
|
||
type: unit
|
||
description: >
|
||
Наблюдаемость: при разблокировке reconciler пишет явную лог-строку с work_item_id и
|
||
stage; при reconcile_notify_unblock=True вызывается send_telegram (замокан).
|
||
module: tests/test_reconciler.py
|
||
expected: PASS
|
||
|
||
- id: TC-21
|
||
type: integration
|
||
description: >
|
||
Restart-safe поток: Reconciler.start() поднимает daemon-поток, stop() завершает его
|
||
в пределах таймаута; повторный start идемпотентен (не плодит второй поток).
|
||
module: tests/test_reconciler.py
|
||
expected: PASS
|
||
|
||
- id: TC-22
|
||
type: unit
|
||
description: >
|
||
Конфиг: новые поля reconcile_* присутствуют в Settings с заявленными дефолтами и
|
||
читаются из env с префиксом ORCH_ (по образцу tests/test_config.py).
|
||
module: tests/test_config.py
|
||
expected: PASS
|
||
|
||
- id: TC-23
|
||
type: unit
|
||
description: >
|
||
Регресс реестров: STAGE_TRANSITIONS и QG_CHECKS не изменены ORCH-053
|
||
(snapshot-тест проходит как раньше).
|
||
module: tests/test_qg_registry_snapshot.py
|
||
expected: PASS
|