87 lines
4.8 KiB
YAML
87 lines
4.8 KiB
YAML
work_item: ORCH-099
|
||
stage: analysis
|
||
author_agent: analyst
|
||
status: ready-for-review
|
||
created_at: 2026-06-10
|
||
model_used: claude-opus-4-8
|
||
title: "FND/F1a — лёгкий read-only /metrics: стадии/очередь/agent-liveness/cost"
|
||
framework: pytest
|
||
scope: >
|
||
Покрывается: структура ответа GET /metrics (4 раздела + конверт), never-raise по полям,
|
||
read-only инвариант, agent-liveness сырьё (pid/runtime/cpu-тики), агрегаты cost/токенов,
|
||
аддитивность (не сломаны /health//status//queue). Вне покрытия: сам sidecar (F1b),
|
||
хостовые/контейнерные метрики, пороги/алерты/Telegram. Полный регресс tests/ остаётся зелёным.
|
||
notes: >
|
||
Тесты идут в новый tests/test_metrics.py. Используется существующий паттерн conftest.py
|
||
(autouse fresh_db на tmp_path + init_db, monkeypatch send_telegram). Эндпоинт зовётся как
|
||
корутина через asyncio.run(main.metrics()) по образцу tests/test_queue_endpoint.py
|
||
(asyncio.run(main.queue())). Read-only проверяется сравнением снимка БД до/после вызова.
|
||
Never-raise — monkeypatch источника (worker / helper БД / чтения /proc) на бросающий стаб.
|
||
|
||
tests:
|
||
- id: TC-01
|
||
type: unit
|
||
description: "build_metrics() возвращает dict с ключами schema_version, generated_at, stages, queue, agents, cost (конверт FR-5)."
|
||
module: tests/test_metrics.py
|
||
expected: PASS
|
||
|
||
- id: TC-02
|
||
type: unit
|
||
description: "Раздел stages: для задачи со stage!=done/cancelled элемент содержит work_item, stage, age_in_stage_s (int), repo; терминальные задачи (done/cancelled) исключены."
|
||
module: tests/test_metrics.py
|
||
expected: PASS
|
||
|
||
- id: TC-03
|
||
type: unit
|
||
description: "Раздел queue: counts (queued/running/failed), max_concurrency, сырьё ретраев и breaker-снимок (state/consecutive_transient/pause_remaining_s) присутствуют."
|
||
module: tests/test_metrics.py
|
||
expected: PASS
|
||
|
||
- id: TC-04
|
||
type: unit
|
||
description: "Раздел agents: по running-job отдаются agent, run_id, job_id, pid, runtime_s и поле CPU-liveness сырья (cpu_ticks или эквивалент)."
|
||
module: tests/test_metrics.py
|
||
expected: PASS
|
||
|
||
- id: TC-05
|
||
type: unit
|
||
description: "agent-liveness never-raise: при pid=None или отсутствующем /proc/<pid> CPU-поле = null, остальные поля агента и весь ответ целы (без исключения)."
|
||
module: tests/test_metrics.py
|
||
expected: PASS
|
||
|
||
- id: TC-06
|
||
type: unit
|
||
description: "Раздел cost.aggregate: суммы cost_usd/input_tokens/output_tokens/cache_read_tokens/cache_creation_tokens из agent_runs; пустая таблица -> нули, не ошибка."
|
||
module: tests/test_metrics.py
|
||
expected: PASS
|
||
|
||
- id: TC-07
|
||
type: unit
|
||
description: "Never-raise по разделу: если источник раздела (напр. job_status_counts/worker.status) бросает, раздел получает null/дефолт, build_metrics() не пробрасывает исключение."
|
||
module: tests/test_metrics.py
|
||
expected: PASS
|
||
|
||
- id: TC-08
|
||
type: integration
|
||
description: "GET /metrics через ASGI/обработчик возвращает 200 и валидный JSON со всеми разделами на засеянной БД (задача + running-job + agent_run)."
|
||
module: tests/test_metrics.py
|
||
expected: PASS
|
||
|
||
- id: TC-09
|
||
type: integration
|
||
description: "Read-only: снимок всех таблиц БД (tasks/jobs/agent_runs) до и после вызова /metrics идентичен; повторный вызов не меняет состояние."
|
||
module: tests/test_metrics.py
|
||
expected: PASS
|
||
|
||
- id: TC-10
|
||
type: integration
|
||
description: "Аддитивность: GET /health, /status, /queue сохраняют прежний контракт (ключи на месте) при наличии /metrics; существующие тесты эндпоинтов зелёные."
|
||
module: tests/test_metrics.py
|
||
expected: PASS
|
||
|
||
- id: TC-11
|
||
type: unit
|
||
description: "Пустое состояние: при отсутствии активных задач/running-jobs/agent_runs ответ валиден — stages=[], agents=[], cost.aggregate=нули, queue.counts с нулями; 200/без исключений."
|
||
module: tests/test_metrics.py
|
||
expected: PASS
|