--- result: PASS work_item: ORCH-093 stage: testing author_agent: tester status: pass created_at: 2026-06-09 model_used: claude-opus-4-8 type: test-report work_item_id: ORCH-093 --- # Test Report — ORCH-093 merge-актор ретраит транзиентные ошибки Gitea (405/5xx/таймаут) + гард «ветка уже в main». ## Окружение - Python: 3.12.13 - pytest: 8.3.3 - Worktree: `/repos/_wt/orchestrator/feature_ORCH-093-bug-merge-gitea-405-5xx-hold-p` - Branch: `feature/ORCH-093-bug-merge-gitea-405-5xx-hold-p` - Дата: 2026-06-09 ## Предусловия - Review verdict: **APPROVED** (`12-review.md`, P0/P1 нет; единственный P2 — косметический дубль секции README, не блокирует). ## Smoke API (read-only, prod 8500) | Эндпоинт | Результат | |----------|-----------| | `GET /health` | `{"status":"ok","service":"orchestrator"}` — OK | | `GET /status` | OK (active_tasks отдаётся; ORCH-093 task#78 в `testing`) | | `GET /queue` | OK — блок `serial_gate` **присутствует** (ORCH-088), `auto_labels` **присутствует** (ORCH-089), `stop` присутствует (ORCH-090). Регресса смока нет. | ## Результаты (покрытие ТЗ — каждый TC из 04-test-plan.yaml) | TC ID | Описание (AC) | Тест | Результат | |-------|---------------|------|-----------| | TC-01 | merge_pr: 405,405,200 → (True, …); ровно 3 POST; ложного False нет (AC-1) | `test_merge_gate.py::test_tc01_merge_retries_405_then_succeeds` | PASS | | TC-02 | merge_pr: 503 (5xx)→200 → ретрай → (True, …) (AC-1) | `test_merge_gate.py::test_tc02_merge_retries_5xx_then_succeeds` | PASS | | TC-03 | merge_pr: httpx Timeout/сетевая→200 → ретрай; never-raise (AC-1, AC-6) | `test_merge_gate.py::test_tc03_merge_retries_network_error_then_succeeds` | PASS | | TC-04 | merge_pr: 409 + GET mergeable=False → (False, …) без доп. POST (терминал) (AC-2) | `test_merge_gate.py::test_tc04_real_conflict_terminal_no_retry` | PASS | | TC-05 | merge_pr: ambiguous 409 + GET mergeable=True → транзиент → ретрай → 200 (AC-2) | `test_merge_gate.py::test_tc05_ambiguous_409_mergeable_true_retries` | PASS | | TC-06 | merge_pr: 403 → немедленно (False, …) без ретрая (терминал) (AC-2) | `test_merge_gate.py::test_tc06_403_terminal_no_retry` | PASS | | TC-07 | merge_pr: 405 на всех N → (False, 'merge failed after N attempts…') понятный reason (AC-3) | `test_merge_gate.py::test_tc07_exhausts_retries_clear_reason` | PASS | | TC-08 | merge_pr: kill-switch off → ровно один POST (one-shot) при 405 (AC-5, AC-3) | `test_merge_gate.py::test_tc08_killswitch_off_one_shot` | PASS | | TC-09 | ensure_open_pr: count==0 → ('already-in-main', …); POST /pulls НЕ вызван (AC-4) | `test_merge_gate.py::test_tc09_ensure_already_in_main_no_post` | PASS | | TC-10 | ensure_open_pr: count>0 → создаёт PR (регресс прежнего поведения) (AC-4) | `test_merge_gate.py::test_tc10_ensure_creates_when_commits_beyond_main` | PASS | | TC-11 | ensure_open_pr: git-ошибка гарда → never-raise, fail-open (AC-6) | `test_merge_gate.py::test_tc11_ensure_guard_git_error_fail_open`, `::test_tc11_branch_fully_in_main_never_raises` | PASS | | TC-12 | merge_pr/ensure_open_pr: любая httpx/parse ошибка → безопасный кортеж, never-raise (AC-6) | `test_merge_gate.py::test_tc12_merge_pr_never_raises`, `::test_tc12_ensure_open_pr_never_raises` | PASS | | TC-13 | config: дефолты merge_retry_* + чтение ORCH_MERGE_RETRY_* env (AC-5) | `test_config.py::test_merge_retry_settings_defaults`, `::test_merge_retry_settings_env_override` | PASS | | TC-14 | _handle_merge_verify: 'already-in-main' пропускает merge_pr, SHA-in-main → done (AC-4) | `test_merge_verify.py::test_tc14_already_in_main_skips_merge_pr_then_done` | PASS | | TC-15 | _handle_merge_verify: merge_pr исчерпал ретраи + SHA не подтверждён → HOLD+alert (ORCH-071/081) (AC-3) | `test_merge_verify.py::test_tc15_merge_failed_and_not_in_main_holds` | PASS | | TC-16 | _handle_merge_verify happy-path: 405x2→200 → SHA-in-main → done без ложного HOLD (AC-1) | `test_merge_verify.py::test_tc16_transient_retry_success_then_done` | PASS | **Сопоставление с `03-acceptance-criteria.md`:** AC-1 (TC-01/02/03/16), AC-2 (TC-04/05/06), AC-3 (TC-07/15), AC-4 (TC-09/10/14), AC-5 (TC-08/13), AC-6 (TC-11/12 + зелёный регресс), AC-7 (`STAGE_TRANSITIONS`/`QG_CHECKS`/сигнатуры неизменны — `test_config.py::test_tc19_*` зелёные). Все 16 TC выполнены и сопоставлены. ## Вывод pytest Полный регресс из worktree ветки задачи: ``` $ cd /repos/_wt/orchestrator/feature_ORCH-093-bug-merge-gitea-405-5xx-hold-p && pytest tests/ -v --tb=short ... ======================= 1389 passed, 1 warning in 44.62s ======================= ``` Целевые сьюты ORCH-093 (`test_merge_gate.py`, `test_config.py`, `test_merge_verify.py`, `test_orch082_ensure_pr.py`): ``` ======================== 72 passed, 1 warning in 1.84s ========================= ``` Единственный warning — `PydanticDeprecatedSince20` (class-based config, существующий, не связан с ORCH-093). Падений и регрессов `test_merge_gate*/test_merge_verify*/test_orch08*/test_config*` нет. ## Итог PASS — все 1389 тестов зелёные, целевые TC-01…TC-16 PASS и сопоставлены с AC-1…AC-7, smoke read-only OK (`serial_gate`/`auto_labels` присутствуют в `/queue`). Задача переходит на `deploy-staging`.