diff --git a/docs/work-items/ORCH-114/13-test-report.md b/docs/work-items/ORCH-114/13-test-report.md new file mode 100644 index 0000000..56e85ce --- /dev/null +++ b/docs/work-items/ORCH-114/13-test-report.md @@ -0,0 +1,85 @@ +--- +result: PASS # PASS | FAIL — машинный вердикт, UPPERCASE +work_item: ORCH-114 +stage: testing +author_agent: tester +status: pass +created_at: 2026-06-15 +model_used: claude-opus-4-8 +type: test-report +work_item_id: ORCH-114 +--- + +# Test Report — ORCH-114 + +Durable transition-ownership lease + expected-stage CAS для side-effectful переходов стадий +(закрытие корневого класса инцидент-цепочки ORCH-110/111/112/113). + +## Окружение +- Python: 3.12.13 +- pytest: 8.3.3 (plugins: cov-5.0.0, anyio-4.13.0, asyncio-0.23.8) +- Worktree: `/repos/_wt/orchestrator/feature_ORCH-114-bug-pipeline-stage-transitions/` +- Branch: `feature/ORCH-114-bug-pipeline-stage-transitions` +- Дата: 2026-06-15 + +## Предусловия +- Review-вердикт `12-review.md`: **APPROVED** (цикл 2, нет P0/P1/P2; только два P3-наблюдения). +- Тесты прогнаны в worktree ветки задачи (не в общем `/repos/orchestrator`) — анти-гонка checkout. + +## Smoke API (read-only, prod 8500) +- `GET /health` → `{"status":"ok","service":"orchestrator"}` — **OK**. +- `GET /status` → активная задача 103 (ORCH-114, stage=testing) видна — **OK**. +- `GET /queue` → блок `serial_gate` присутствует (ORCH-088), блок `auto_labels` присутствует + (ORCH-089) — **OK** (смок-инвариант соблюдён). +- Блок `transition_lease` в `/queue` прод-инстанса (8500) **отсутствует** — это **ожидаемо**, не + регресс: новый код ORCH-114 живёт в ветке/worktree и ещё не задеплоен в прод (стадия testing + предшествует deploy-staging/deploy). Наблюдаемость блока `transition_lease` покрыта unit-тестами + TC-12 (`test_tc12_queue_block_wired`). + +## Результаты — покрытие каждого TC из 04-test-plan.yaml + +| TC ID | Тип | Описание (кратко) | AC | Результат | +|-------|-----|-------------------|----|-----------| +| TC-01 | integration | ОБЯЗ. РЕГРЕСС: конкурентный вход в `advance_stage(deploy-staging)` — каждый side-effect ровно раз; красный до фикса, зелёный после | AC-1 | PASS | +| TC-02 | unit | CAS-запись стадии: первый writer rowcount=1, второй lost-race rowcount=0, без мутации | AC-2 | PASS | +| TC-03 | unit | Жизненный цикл владения: acquire/release в `try/finally` (норм + исключение), durable-видимость | AC-3 | PASS | +| TC-04 | integration | Reaper defer при живом владении за пределами Tier-2/deploy-staging; rowcount-guard сохранён | AC-4 | PASS | +| TC-05 | unit/integration | Reaper добивает мёртвое/устаревшее владение в Tier-3 backstop; бюджет-инвариант сохранён | AC-5 | PASS | +| TC-06 | integration | Умное восстановление при рестарте: сходимость к единственному исходу без повторного эффекта | AC-6 | PASS | +| TC-07 | integration | Reconciler F-1 defer/skip при активном lease; fail-safe консервативный skip | AC-7 | PASS | +| TC-08 | integration | Webhook-путь (Approved/Confirm Deploy) defer при активном lease; поздний сигнал не теряется | AC-8 | PASS | +| TC-09 | integration | Kill-switch off: lease инертен, CAS вырождается в безусловный write — байт-в-байт | AC-9 | PASS | +| TC-10 | unit | never-raise + fail-open (hot-path) / fail-closed (prod-safety) на ошибках БД/lease | AC-10 | PASS | +| TC-11 | unit | Структурный аудит: `STAGE_TRANSITIONS`/`QG_CHECKS`/`check_*`/вердикт-ключи байт-в-байт; хранилище аддитивно | AC-11 | PASS | +| TC-12 | integration | Наблюдаемость: блок `/queue`, Telegram-алерт на форсированный реклейм | AC-12 | PASS | +| TC-13 | unit | Self-hosting безопасность: нет рестарта прода / push в `main` / detached-вмешательства | AC-13 | PASS | +| TC-14 | integration | Полный регресс конвейера зелёный; happy-path deploy-staging/finalizer без двойных эффектов | BR-8 | PASS | + +**Сопоставление с `03-acceptance-criteria.md`:** все 13 AC покрыты соответствующими TC (см. колонку +AC). Каждый TC из `04-test-plan.yaml` (TC-01…TC-14) выполнен и совпал с `expected: PASS`. + +Детализация по dedicated-модулю `tests/test_orch114_transition_ownership.py` (34 теста, разбивка +TC-01…TC-13 на под-кейсы) — все PASSED. TC-14 — полный регресс `tests/`. + +## Вывод pytest + +Dedicated-модуль: +``` +tests/test_orch114_transition_ownership.py — 34 passed, 1 warning in 3.84s +``` + +Полный регресс (TC-14 / AC-9 / CI-green): +``` +2052 passed, 1 warning in 106.62s (0:01:46) +``` +(единственный warning — `PydanticDeprecatedSince20` в `src/config.py:8`, преждесуществующий, +не связан с ORCH-114.) + +Обязательный регресс класса ORCH-111 присутствует и зелёный: +`test_tc01_concurrent_entry_no_double_effect` (PASS с lease) + +`test_tc01_red_before_fix_demonstration` (демонстрация красного при kill-switch off). + +## Итог +**PASS** — полный pytest зелёный (2052 passed), все 14 TC выполнены и сопоставлены с 13 AC, smoke +read-only (`/health`/`/status`/`/queue` c блоками `serial_gate` + `auto_labels`) OK. Задача готова +к переходу на `deploy-staging`.