197 lines
8.0 KiB
YAML
197 lines
8.0 KiB
YAML
work_item: ORCH-065
|
||
description: >
|
||
Тест-план для фикса zombie jobs (job-reaper), залипшего merge-lease
|
||
(проактивный реклейм dead/stale lease) и идемпотентной финализации merge.
|
||
Все новые фоновые механизмы — never-raise, restart-safe, kill-switch.
|
||
Модуль reaper и точные имена функций уточнит архитектор; в module указаны
|
||
кандидатные пути (tests/test_job_reaper.py / tests/test_merge_lease_reclaim.py).
|
||
|
||
tests:
|
||
# ---- A. Job-reaper ----
|
||
- id: TC-01
|
||
type: unit
|
||
description: >
|
||
Reaper переводит running-job с мёртвым исполнителем в корректный статус
|
||
без рестарта процесса (pid не существует / exit_code записан, job всё ещё
|
||
running). Покрывает AC-1.
|
||
module: tests/test_job_reaper.py
|
||
expected: PASS
|
||
|
||
- id: TC-02
|
||
type: unit
|
||
description: >
|
||
Анти-ложноположительность: running-job с ЖИВЫМ процессом в пределах
|
||
agent_timeout НЕ реапится (ни по одному тику, ни в пределах reaper_max_running_s).
|
||
Покрывает AC-3.
|
||
module: tests/test_job_reaper.py
|
||
expected: PASS
|
||
|
||
- id: TC-03
|
||
type: unit
|
||
description: >
|
||
Устойчивость: job помечается зомби только после reaper_dead_ticks
|
||
последовательных тиков смерти pid (>=2), а не на первом тике. Покрывает FR-1.3.
|
||
module: tests/test_job_reaper.py
|
||
expected: PASS
|
||
|
||
- id: TC-04
|
||
type: unit
|
||
description: >
|
||
Backstop по потолку: job, висящий running дольше reaper_max_running_s,
|
||
реапится даже если liveness определить нельзя. Покрывает FR-1.1/AC-1.
|
||
module: tests/test_job_reaper.py
|
||
expected: PASS
|
||
|
||
- id: TC-05
|
||
type: unit
|
||
description: >
|
||
Корректный исход: exit_code==0 -> успешное завершение без дублирования
|
||
stage-advance; неуспех при attempts<max -> queued; исчерпан бюджет -> failed
|
||
+ Telegram. Покрывает AC-4.
|
||
module: tests/test_job_reaper.py
|
||
expected: PASS
|
||
|
||
- id: TC-06
|
||
type: unit
|
||
description: >
|
||
Атомарность reap-UPDATE с guard status='running': параллельная обработка
|
||
одной строки (стартовый requeue_running_jobs + reaper) не приводит к двойному
|
||
reap. Покрывает AC-5.
|
||
module: tests/test_job_reaper.py
|
||
expected: PASS
|
||
|
||
- id: TC-07
|
||
type: unit
|
||
description: >
|
||
Kill-switch reaper_enabled=false -> reaper не трогает ни одной строки
|
||
(строго прежнее поведение). Покрывает AC-14.
|
||
module: tests/test_job_reaper.py
|
||
expected: PASS
|
||
|
||
- id: TC-08
|
||
type: unit
|
||
description: >
|
||
never-raise: ошибка БД/ОС внутри одного тика reaper не пробрасывается и не
|
||
останавливает поток (изоляция per-job, образец reconciler). Покрывает AC-9.
|
||
module: tests/test_job_reaper.py
|
||
expected: PASS
|
||
|
||
- id: TC-09
|
||
type: integration
|
||
description: >
|
||
Очередь разблокируется: после reap зомби-строки при max_concurrency=1
|
||
следующий queued-job успешно claim'ится (claim_next_job + count_running_jobs).
|
||
Покрывает AC-2.
|
||
module: tests/test_queue.py
|
||
expected: PASS
|
||
|
||
# ---- B. Stale/dead merge-lease reclaim ----
|
||
- id: TC-10
|
||
type: unit
|
||
description: >
|
||
Реклейм lease с мёртвым pid (os.kill(pid,0) -> ProcessLookupError)
|
||
проактивно, не дожидаясь TTL и чужого acquire. Покрывает AC-6.
|
||
module: tests/test_merge_lease_reclaim.py
|
||
expected: PASS
|
||
|
||
- id: TC-11
|
||
type: unit
|
||
description: >
|
||
Реклейм по TTL (age >= merge_lock_timeout_s) сохранён, с logger.warning.
|
||
Покрывает AC-7. (расширяет существующий stale-lease сценарий merge_gate.)
|
||
module: tests/test_merge_lease_reclaim.py
|
||
expected: PASS
|
||
|
||
- id: TC-12
|
||
type: unit
|
||
description: >
|
||
Живой lease (pid жив, age < TTL) НЕ освобождается — защита легитимного merge.
|
||
Покрывает AC-8.
|
||
module: tests/test_merge_lease_reclaim.py
|
||
expected: PASS
|
||
|
||
- id: TC-13
|
||
type: unit
|
||
description: >
|
||
Условность: реклейм реален только для merge_gate_repos/self-hosting; для
|
||
прочих репо no-op. Покрывает AC-9.
|
||
module: tests/test_merge_lease_reclaim.py
|
||
expected: PASS
|
||
|
||
- id: TC-14
|
||
type: unit
|
||
description: >
|
||
never-raise: ошибка чтения/удаления lease-файла не валит реклейм-поток.
|
||
Покрывает AC-9.
|
||
module: tests/test_merge_lease_reclaim.py
|
||
expected: PASS
|
||
|
||
- id: TC-15
|
||
type: unit
|
||
description: >
|
||
Kill-switch lease_reclaim_enabled=false -> проактивный реклейм отключён,
|
||
остаётся лишь прежний ленивый TTL-реклейм в acquire_merge_lease.
|
||
Покрывает AC-14.
|
||
module: tests/test_merge_lease_reclaim.py
|
||
expected: PASS
|
||
|
||
# ---- C. Идемпотентная финализация merge ----
|
||
- id: TC-16
|
||
type: unit
|
||
description: >
|
||
Идемпотентность финализации: повторный вызов при уже слитом PR / уже
|
||
актуальном main (branch_is_behind_main == False) — no-op, без ошибки и без
|
||
второго merge. Покрывает AC-11.
|
||
module: tests/test_merge_gate.py
|
||
expected: PASS
|
||
|
||
- id: TC-17
|
||
type: integration
|
||
description: >
|
||
Восстановление: сценарий "rebase+re-test зелёные, merge не состоялся,
|
||
процесс умер" -> job доводится до queued reaper'ом и merge докатывается
|
||
штатным путём без повторного дорогого re-test, когда безопасно. Покрывает AC-10.
|
||
module: tests/test_merge_gate_race.py
|
||
expected: PASS
|
||
|
||
# ---- D/E. Инварианты и наблюдаемость ----
|
||
- id: TC-18
|
||
type: integration
|
||
description: >
|
||
GET /queue содержит блок reaper (enabled, interval, last_run_ts,
|
||
reaped_total, last_reaped, lease_reclaimed_total). Покрывает AC-15.
|
||
module: tests/test_queue.py
|
||
expected: PASS
|
||
|
||
- id: TC-19
|
||
type: unit
|
||
description: >
|
||
Контракты неизменны: STAGE_TRANSITIONS и реестр QG_CHECKS не получили новых
|
||
стадий/чеков; check_branch_mergeable сигнатурно не изменён. Покрывает AC-13.
|
||
module: tests/test_config.py
|
||
expected: PASS
|
||
|
||
- id: TC-20
|
||
type: unit
|
||
description: >
|
||
Новые настройки reaper_*/lease_reclaim_* присутствуют в config с дефолтами и
|
||
читаются из ORCH_* env. Покрывает §5 ТЗ / AC-14.
|
||
module: tests/test_config.py
|
||
expected: PASS
|
||
|
||
- id: TC-21
|
||
type: unit
|
||
description: >
|
||
Стартовый реклейм stale/dead lease вызывается в lifespan рядом с
|
||
requeue_running_jobs (smoke на регистрацию старт/стоп reaper-потока).
|
||
Покрывает FR-2.1 / AC-6.
|
||
module: tests/test_job_reaper.py
|
||
expected: PASS
|
||
|
||
regression:
|
||
- command: pytest tests/ -q
|
||
expected: PASS
|
||
note: >
|
||
Полный прогон не должен ломать существующие тесты merge_gate / queue /
|
||
reconciler / deploy.
|