tester(ET): auto-commit from tester run_id=758
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
---
|
||||
result: PASS
|
||||
result: PASS # PASS | FAIL — машинный вердикт, UPPERCASE
|
||||
work_item: ORCH-116
|
||||
stage: testing
|
||||
author_agent: tester
|
||||
@@ -10,63 +10,142 @@ type: test-report
|
||||
work_item_id: ORCH-116
|
||||
---
|
||||
|
||||
# Test Report — ORCH-116
|
||||
# Test Report — ORCH-116 — детерминированный test-раннер вместо LLM-тестера
|
||||
|
||||
Детерминированный test-раннер вместо LLM-тестера (стадия `testing`).
|
||||
> Машинный вердикт читается ТОЛЬКО из frontmatter (`result:`; равнорангово `verdict:`/`status:`,
|
||||
> ORCH-047). Любой негативный токен авторитетен.
|
||||
|
||||
## Окружение
|
||||
- Python: 3.12.13
|
||||
- pytest: 8.3.3 (plugins: cov-5.0.0, anyio-4.14.0, asyncio-0.23.8)
|
||||
- Worktree: `/repos/_wt/orchestrator/feature_ORCH-116-orch-replace-llm-tester-with-d`
|
||||
- Ветка: `feature/ORCH-116-orch-replace-llm-tester-with-d`
|
||||
- pytest: 8.3.3
|
||||
- Дата: 2026-06-16
|
||||
- Worktree: `/repos/_wt/orchestrator/feature_ORCH-116-orch-replace-llm-tester-with-d`
|
||||
(ветка `feature/ORCH-116-orch-replace-llm-tester-with-d`) — регресс прогнан в worktree ветки
|
||||
задачи, НЕ в общем `/repos/orchestrator` (анти checkout-гонка).
|
||||
- Прод-контейнер 8500 не трогался; smoke — строго read-only GET.
|
||||
- Review-гейт: `12-review.md` → `verdict: APPROVED` ✔ (предусловие стадии выполнено).
|
||||
|
||||
## Smoke API (read-only)
|
||||
- `GET /health` → `{"status":"ok","service":"orchestrator"}` — **OK**
|
||||
- `GET /status` → активные задачи отданы (ORCH-116 на `testing`) — **OK**
|
||||
- `GET /queue` → отдан; блок `serial_gate` присутствует (ORCH-088), блок `auto_labels` присутствует,
|
||||
блок `test_runner` присутствует (ORCH-116 наблюдаемость) — **OK**
|
||||
|
||||
## Результаты по тест-плану (04-test-plan.yaml)
|
||||
| Эндпоинт | Результат |
|
||||
|----------|-----------|
|
||||
| `GET /health` | `{"status":"ok","service":"orchestrator"}` — **OK** |
|
||||
| `GET /status` | 200, активные задачи отдаются (вкл. ORCH-116, stage=testing) — **OK** |
|
||||
| `GET /queue` | 200; блок `serial_gate` присутствует ✔ (ORCH-088); блок `auto_labels` присутствует ✔ — **OK** |
|
||||
|
||||
| TC ID | Описание | Тест(ы) | Результат |
|
||||
|-------|----------|---------|-----------|
|
||||
| TC-01 | `applies(repo)`: kill-switch/скоуп/тест-контракт (BR-9), never-raise | `test_tc01_applies_killswitch_scope_and_contract`, `test_tc01_applies_never_raises` | PASS |
|
||||
| TC-02 | Маппинг exit-кода 0→PASS / иначе/None→FAIL (fail-closed, единый контракт) | `test_tc02_map_exit_code` | PASS |
|
||||
| TC-03 | Рендер `13-test-report.md`: `result:` UPPERCASE + 52c-схема + хвост stdout/smoke | `test_tc03_report_render_schema_and_status_alignment` | PASS |
|
||||
| TC-04 | Артефакт читается неизменённым `_parse_tests_verdict` для PASS/FAIL | `test_tc04_gate_parser_unchanged`, `test_tc04_status_field_never_false_negatives_a_pass` | PASS |
|
||||
| TC-05 | `launch_job` перехватывает tester-джоб до `_spawn`; `agent_runs` не создаётся, None | `test_tc05_launch_job_intercepts_before_spawn` | PASS |
|
||||
| TC-06 | Дискриминатор: не-`testing`/не-tester/не-self не перехватываются; never-raise→False | `test_tc06_*` (4 теста) | PASS |
|
||||
| TC-07 | PASS→advance(`tester`)→`deploy-staging`; FAIL→откат `testing→development` + retry | `test_tc07_advance_initiated_like_llm[0-PASS]`, `[1-FAIL]` | PASS |
|
||||
| TC-08 | Kill-switch `test_runner_enabled=False` → `_spawn` (LLM-путь байт-в-байт) | `test_tc08_killswitch_falls_back_to_spawn` | PASS |
|
||||
| TC-09 | Анти-дрейф NFR-1: `STAGE_TRANSITIONS`/`QG_CHECKS`/`check_tests_passed`/токены/схема БД целы | `test_tc09_pipeline_contract_unchanged` | PASS |
|
||||
| TC-10 | Two-level (анти-ORCH-110): tool-error→bounded DEFER; исчерпание→fail-closed FAIL+alert | `test_tc10_nonzero_exit_is_fail_and_advances`, `test_tc10_timeout_defers_without_advance`, `test_tc10_tool_error_budget_exhausted_fails_closed` | PASS |
|
||||
| TC-11 | never-raise/fail-safe: pytest-бросок/таймаут/worktree-ошибка → FAIL/DEFER, не клинит | `test_tc11_run_gate_never_raises`, `test_tc11_launcher_contains_runner_fault` | PASS |
|
||||
| TC-12 | Изоляция/таймаут: proc_group tree-kill в worktree; малформ→дефолт 900+WARNING | `test_tc12_resolve_timeout_default_on_bad_value`, `test_tc12_pytest_runs_in_worktree_via_proc_group` | PASS |
|
||||
| TC-13 | Self-hosting safety: нет опасных литералов; smoke строго read-only GET; push в фичеветку | `test_tc13_*` (5 тестов) | PASS |
|
||||
| TC-14 | Наблюдаемость+гибрид: блок `test_runner` в `/queue`; структурный лог; LLM вне control-path | `test_tc14_*` (4 теста) | PASS |
|
||||
| TC-15 | Анти-дрейф LLM-карты: `llm-call-sites`/roadmap/policy зелёные после правок | `test_tc15_llm_map_anti_drift_green`, `test_llm_call_site_inventory.py`, `test_llm_determinization_docs.py` | PASS |
|
||||
Примечание: блок `test_runner` (ORCH-116) в `/queue` прод-инстанса отсутствует — ожидаемо, т.к.
|
||||
прод исполняет до-ORCH-116 код (эта ветка ещё не задеплоена). Это не регресс смока: контрактные
|
||||
блоки `serial_gate`/`auto_labels` на месте.
|
||||
|
||||
Каждый TC из `04-test-plan.yaml` выполнен и сопоставлен с критериями `03-acceptance-criteria.md`.
|
||||
## Результаты
|
||||
|
||||
## Вывод pytest
|
||||
### Полный регресс (`pytest tests/ -v --tb=short`, worktree ветки)
|
||||
- **2162 passed, 1 failed** (105.31s).
|
||||
- Профильная сюита `tests/test_orch116_test_runner.py` — **32 passed** (в изоляции, 2.64s).
|
||||
- Анти-дрейф LLM-карты `tests/test_llm_call_site_inventory.py` + `test_llm_determinization_docs.py`
|
||||
— зелёные (в составе полного регресса).
|
||||
|
||||
### Единственный красный — pre-existing flake ORCH-123, НЕ дефект ORCH-116
|
||||
|
||||
`tests/test_orch123_staging_runner_exec.py::test_r2_held_deploy_staging_not_rolled_back`.
|
||||
|
||||
Доказано независимым воспроизведением, что фейл **полностью независим** от ORCH-116 и пред-существует
|
||||
в `main` (анти-ложная-маршрутизация инфра/чужого фейла как код-фейла — класс ORCH-110):
|
||||
|
||||
1. **Изоляция:** `pytest …::test_r2_held_deploy_staging_not_rolled_back` отдельно → **1 passed**.
|
||||
2. **Профильный файл ORCH-116:** `tests/test_orch116_test_runner.py` → **32 passed** (зелёный).
|
||||
3. **Полный регресс БЕЗ файла ORCH-116** (`--ignore=tests/test_orch116_test_runner.py`) → всё равно
|
||||
**1 failed, 2130 passed** — тот же тест красный без участия нового кода тестов ORCH-116.
|
||||
4. **Чистый `origin/main` (`9c88fdd`), полный регресс** во временном worktree → **1 failed, 2130
|
||||
passed**, падает РОВНО тот же тест. → флейк пред-существует в `main`, идентичный счётчик фейлов.
|
||||
5. **Граница правки:** `git diff origin/main...HEAD` НЕ затрагивает `src/staging_runner.py`,
|
||||
`src/stages.py`, `src/qg/`, `src/stage_engine.py`. ORCH-116 физически не может влиять на этот тест.
|
||||
|
||||
Итог сопоставления: ветка ORCH-116 = `2162 passed / 1 failed`; `main` = `2130 passed / 1 failed`.
|
||||
ORCH-116 добавляет **32 зелёных** теста и **не делает красным ни один ранее зелёный** — это
|
||||
кросс-тестовое загрязнение глобального состояния в коде ORCH-123 (недавно влит в `main`).
|
||||
**AC-15 FAIL-условие** («любой ранее зелёный тест становится красным / новые тесты падают») —
|
||||
**не наступило**; AC-15-интент NFR-1/NFR-5 («существующий конвейер не сломан») — выполнен.
|
||||
Рекомендация: завести отдельный bug на изоляцию `test_orch123_staging_runner_exec.py` (вне области
|
||||
ORCH-116, не должен блокировать этот PR). Согласуется с вердиктом reviewer (P2, APPROVED).
|
||||
|
||||
### Сопоставление с тест-планом (`04-test-plan.yaml`)
|
||||
|
||||
| TC ID | Тип | Описание (кратко) | Тест-функция / проверка | Результат |
|
||||
|-------|-----|-------------------|--------------------------|-----------|
|
||||
| TC-01 | unit | `applies(repo)`: kill-switch/CSV/контракт (BR-9)/never-raise | `test_tc01_*` | PASS |
|
||||
| TC-02 | unit | Маппинг exit→verdict (0→PASS, иначе/None→FAIL, единый контракт) | `test_tc02_map_exit_code` | PASS |
|
||||
| TC-03 | unit | Рендер `13-test-report.md`: `result:` UPPERCASE + 52c-схема | `test_tc03_report_render_schema_and_status_alignment` | PASS |
|
||||
| TC-04 | integration | Артефакт читается **неизменённым** `_parse_tests_verdict` | `test_tc04_gate_parser_unchanged`, `test_tc04_status_field_never_false_negatives_a_pass` | PASS |
|
||||
| TC-05 | integration | Перехват tester на `testing` до `_spawn`, нет `agent_runs`, `None` | `test_tc05_launch_job_intercepts_before_spawn` | PASS |
|
||||
| TC-06 | integration | Дискриминатор: не-`testing`/не-`tester` не перехват; never-raise→`False` | `test_tc06_*` | PASS |
|
||||
| TC-07 | integration | PASS→`advance_stage(finished_agent='tester')`; FAIL→откат+retry | `test_tc07_advance_initiated_like_llm[0-PASS]`, `[1-FAIL]` | PASS |
|
||||
| TC-08 | integration | Kill-switch off → `_spawn` (LLM-путь байт-в-байт) | `test_tc08_killswitch_falls_back_to_spawn` | PASS |
|
||||
| TC-09 | unit | Анти-дрейф NFR-1: STAGE_TRANSITIONS/QG_CHECKS/парсер/токены/схема БД целы | `test_tc09_pipeline_contract_unchanged` | PASS |
|
||||
| TC-10 | integration | Two-level outcome: tool-error→bounded DEFER→fail-closed FAIL+alert | `test_tc10_*` | PASS |
|
||||
| TC-11 | unit | never-raise/fail-safe: pytest бросает/таймаут→FAIL/DEFER, не клинит | `test_tc11_run_gate_never_raises`, `test_tc11_launcher_contains_runner_fault` | PASS |
|
||||
| TC-12 | unit | Изоляция/таймаут: proc_group tree-kill в worktree; малформ→дефолт 900+WARN | `test_tc12_*` | PASS |
|
||||
| TC-13 | unit | Self-hosting safety: нет запрещённых литералов; smoke read-only GET | `test_tc13_*` | PASS |
|
||||
| TC-14 | integration | Наблюдаемость: блок `test_runner` в `/queue`, структурный лог, гибрид | `test_tc14_*` | PASS |
|
||||
| TC-15 | integration | Анти-дрейф LLM-карты (A5/rank 2, «ровно один first_slice=yes») | `test_llm_call_site_inventory.py` / `test_llm_determinization_docs.py` | PASS |
|
||||
|
||||
**Все 15 TC выполнены и сопоставлены; все PASS.**
|
||||
|
||||
### Сопоставление с критериями приёмки (`03-acceptance-criteria.md`)
|
||||
|
||||
| AC | Покрыт | Результат |
|
||||
|----|--------|-----------|
|
||||
| AC-1 Перехват на `testing` без `_spawn`/LLM | TC-05 | PASS |
|
||||
| AC-2 Контракт `13-test-report.md` неизменен | TC-03, TC-04 | PASS |
|
||||
| AC-3 exit-code→verdict маппинг (fail-closed) | TC-02 | PASS |
|
||||
| AC-4 Эквивалентность маршрутизации PASS/FAIL | TC-07 | PASS |
|
||||
| AC-5 Two-level outcome (tool-error ≠ code-fail) | TC-10 | PASS |
|
||||
| AC-6 Скоуп: гейты/стадии/схема БД не тронуты | TC-09 + `git diff` | PASS |
|
||||
| AC-7 Kill-switch и скоуп (обратимость) | TC-01, TC-08 | PASS |
|
||||
| AC-8 Backward-compat для репо без контракта | TC-01 | PASS |
|
||||
| AC-9 never-raise / fail-safe | TC-11 | PASS |
|
||||
| AC-10 Self-hosting safety | TC-13 | PASS |
|
||||
| AC-11 Изоляция процесса/таймаут (proc_group) | TC-12 | PASS |
|
||||
| AC-12 Гибрид: LLM не в control-path вердикта | TC-14 | PASS |
|
||||
| AC-13 Наблюдаемость | TC-14 | PASS |
|
||||
| AC-14 Норматив LLM-карты/политики/витрины | TC-15 + ревью оси 4 | PASS |
|
||||
| AC-15 Полный регресс зелёный | полный регресс | PASS* |
|
||||
|
||||
\* AC-15: новые тесты зелёные, ни один ранее зелёный тест не покраснел из-за ORCH-116. Единственный
|
||||
красный — pre-existing flake ORCH-123 (идентичен на чистом `main`), вне области ORCH-116.
|
||||
|
||||
## Вывод pytest (хвост полного регресса)
|
||||
|
||||
### Полный регресс
|
||||
```
|
||||
$ python -m pytest tests/ -q --tb=short
|
||||
........................................................................ [ 97%]
|
||||
................................................. [100%]
|
||||
2137 passed, 1 warning in 84.57s (0:01:24)
|
||||
=================================== FAILURES ===================================
|
||||
_________________ test_r2_held_deploy_staging_not_rolled_back __________________
|
||||
tests/test_orch123_staging_runner_exec.py:462: in test_r2_held_deploy_staging_not_rolled_back
|
||||
assert result is None # red gate -> stay, no advance call
|
||||
E AssertionError: assert <MagicMock name='mock()' id='...'> is None
|
||||
=========================== short test summary info ============================
|
||||
FAILED tests/test_orch123_staging_runner_exec.py::test_r2_held_deploy_staging_not_rolled_back
|
||||
============ 1 failed, 2162 passed, 1 warning in 105.31s (0:01:45) =============
|
||||
```
|
||||
(единственный warning — несвязанный Pydantic V2 deprecation в `src/config.py:8`)
|
||||
|
||||
### Тесты ORCH-116 (verbose)
|
||||
Контрольные прогоны (доказательство независимости от ORCH-116):
|
||||
```
|
||||
$ python -m pytest tests/test_orch116_test_runner.py tests/test_llm_call_site_inventory.py tests/test_llm_determinization_docs.py -v
|
||||
45 passed, 1 warning in 2.20s
|
||||
# тест в изоляции
|
||||
1 passed
|
||||
# профильный файл ORCH-116
|
||||
32 passed
|
||||
# полный регресс БЕЗ файла ORCH-116 (--ignore)
|
||||
1 failed, 2130 passed (тот же тест красный)
|
||||
# чистый origin/main (9c88fdd), полный регресс
|
||||
1 failed, 2130 passed (тот же тест красный)
|
||||
```
|
||||
|
||||
## Итог
|
||||
PASS — полный регресс зелёный (2137 passed), smoke read-only OK (`/health`/`/status`/`/queue`,
|
||||
блок `serial_gate` присутствует), все 15 TC выполнены и сопоставлены с критериями приёмки.
|
||||
Задача переходит на `deploy-staging`.
|
||||
|
||||
**PASS.** Smoke OK (read-only `/health`/`/status`/`/queue`; `serial_gate` + `auto_labels` на месте).
|
||||
Профильная сюита (32) и анти-дрейф LLM-карты зелёные. Все 15 TC и 15 AC сопоставлены и пройдены.
|
||||
Единственный красный тест полного регресса — **pre-existing flake ORCH-123**
|
||||
(`test_r2_held_deploy_staging_not_rolled_back`), доказанно идентичный на чистом `origin/main`
|
||||
(`2130 passed / 1 failed`) и полностью независимый от ORCH-116 (граница правки не затрагивает
|
||||
`src/staging_runner.py`); ORCH-116 не делает красным ни один ранее зелёный тест и добавляет 32
|
||||
зелёных. AC-15-интент «существующий конвейер не сломан» выполнен. Рекомендован отдельный bug на
|
||||
изоляцию теста ORCH-123 (вне области этой задачи). Задача переходит на `deploy-staging`.
|
||||
|
||||
Reference in New Issue
Block a user