phase: 12_nut_self_test_verdict
Final state verified. Report: **Verified (phase 12 — all 3 tasks already complete; this was the verification pass)** - Re-ran the wire capture live: `ups.test.result` = `No test initiated` (apc) / `Done and passed` (cyberpower) — matches `LIVE_SELF_TEST_WORDS` + both fixtures; `/api/summary` has **no** self-test row, `/api/ups/snapshot` reads `cyberpower ok | Done and passed`, `apc unknown | …run a battery test`; both screenshots read back correct. - Fixed a defect found in prior work while checking the "unrelated live noise" note: `NutMonitor.collect()` reused one upsd socket after a *partially-read* reply, so a 4 s stall produced bogus `expected 'BEGIN LIST VAR', got 'RW apc battery.charge.low "10"'` errors (same hazard on `INSTCMD`, where a late `OK` could be read as a different command's success). `NutClient` now marks a socket whose reply stopped early as `UNUSABLE`, naming the command that stalled; a complete `ERR …` line still leaves it usable (the per-UPS tolerance `collect()` depends on). +3 hermetic pins against the fake upsd; live re-check (09:33–09:44) now logs one line per stall, no cascade. **Tests / lint / coverage (all green)** - `bash .agents/validate.sh` → **exit 0**; `uv run pytest --cov --cov-fail-under=94` → **1172 passed, 11 skipped**, coverage **98.63 %** (floor 94); `uv run ruff check src tests agent` clean; `uv run pyright` 0 errors; `node --check` clean. Modified modules: `sources/nut.py` 95 %, `collectors.py` 97 % (no new line uncovered). - `uv run pytest -m live --live` → **8 passed / 3 failed**, all three the pre-existing `driveripper` agent-transport failures AGENTS.md records (verified still true: unit `inactive`, no installed file, nothing on `:9120`). - `./scripts/dev-server.sh status`: `nut ok`, `llm:* ok`, `host/disks:deskwork|gateway ok`; the two `driveripper` jobs DOWN. **Completion criteria** - Live capture recorded + asserts `ok` — met (re-confirmed from the wire today). - `/ups` renders `ok`, overview silent, screenshots present — met. - pytest / cov / ruff / pyright / validate — met (above). - No other `health.checks[]` behaviour changed — met (diff confined to the `test_result` branch; all prior nut/ups-contract tests unmodified). **Documentation**: README verified consistent (self-test wording, config table cross-checked against `config.py`, all documented commands/flags exist) — no changes needed beyond phase tasks' edit. AGENTS.md fixes: stale test count (1140 → 1172), `nvme0n1` power-on hours 19 158 → 19 160, gap 4 store-error claim corrected (last stored `store-error` 2026-10-18 06:33, none in the previous 24 h), new `collectors.py`/`sources/nut.py` socket-hygiene note, new gap-1 bullet on the upsd stall, plus live evidence appended to `data/logs/NOTES-self-test.md`. **Deviations**: made no live *changes* (read-only probes only) — `driveripper`'s agent install needs root (`ops` has no installer/visudo grant) and a battery test stays the operator's call; the upsd 4 s stall itself is upstream-side. `uv pip list --outdated` still advisory (certifi/fastapi/starlette) — dependencies untouched this phase. **Next pending phase**: `13_llm_page_and_decode_rate`.
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
Final state verified. Report:
|
||||
|
||||
**Verified (phase 12 — all 3 tasks already complete; this was the verification pass)**
|
||||
- Re-ran the wire capture live: `ups.test.result` = `No test initiated` (apc) / `Done and passed` (cyberpower) — matches `LIVE_SELF_TEST_WORDS` + both fixtures; `/api/summary` has **no** self-test row, `/api/ups/snapshot` reads `cyberpower ok | Done and passed`, `apc unknown | …run a battery test`; both screenshots read back correct.
|
||||
- Fixed a defect found in prior work while checking the "unrelated live noise" note: `NutMonitor.collect()` reused one upsd socket after a *partially-read* reply, so a 4 s stall produced bogus `expected 'BEGIN LIST VAR', got 'RW apc battery.charge.low "10"'` errors (same hazard on `INSTCMD`, where a late `OK` could be read as a different command's success). `NutClient` now marks a socket whose reply stopped early as `UNUSABLE`, naming the command that stalled; a complete `ERR …` line still leaves it usable (the per-UPS tolerance `collect()` depends on). +3 hermetic pins against the fake upsd; live re-check (09:33–09:44) now logs one line per stall, no cascade.
|
||||
|
||||
**Tests / lint / coverage (all green)**
|
||||
- `bash .agents/validate.sh` → **exit 0**; `uv run pytest --cov --cov-fail-under=94` → **1172 passed, 11 skipped**, coverage **98.63 %** (floor 94); `uv run ruff check src tests agent` clean; `uv run pyright` 0 errors; `node --check` clean. Modified modules: `sources/nut.py` 95 %, `collectors.py` 97 % (no new line uncovered).
|
||||
- `uv run pytest -m live --live` → **8 passed / 3 failed**, all three the pre-existing `driveripper` agent-transport failures AGENTS.md records (verified still true: unit `inactive`, no installed file, nothing on `:9120`).
|
||||
- `./scripts/dev-server.sh status`: `nut ok`, `llm:* ok`, `host/disks:deskwork|gateway ok`; the two `driveripper` jobs DOWN.
|
||||
|
||||
**Completion criteria**
|
||||
- Live capture recorded + asserts `ok` — met (re-confirmed from the wire today).
|
||||
- `/ups` renders `ok`, overview silent, screenshots present — met.
|
||||
- pytest / cov / ruff / pyright / validate — met (above).
|
||||
- No other `health.checks[]` behaviour changed — met (diff confined to the `test_result` branch; all prior nut/ups-contract tests unmodified).
|
||||
|
||||
**Documentation**: README verified consistent (self-test wording, config table cross-checked against `config.py`, all documented commands/flags exist) — no changes needed beyond phase tasks' edit. AGENTS.md fixes: stale test count (1140 → 1172), `nvme0n1` power-on hours 19 158 → 19 160, gap 4 store-error claim corrected (last stored `store-error` 2026-10-18 06:33, none in the previous 24 h), new `collectors.py`/`sources/nut.py` socket-hygiene note, new gap-1 bullet on the upsd stall, plus live evidence appended to `data/logs/NOTES-self-test.md`.
|
||||
|
||||
**Deviations**: made no live *changes* (read-only probes only) — `driveripper`'s agent install needs root (`ops` has no installer/visudo grant) and a battery test stays the operator's call; the upsd 4 s stall itself is upstream-side. `uv pip list --outdated` still advisory (certifi/fastapi/starlette) — dependencies untouched this phase.
|
||||
|
||||
**Next pending phase**: `13_llm_page_and_decode_rate`.
|
||||
+1
@@ -0,0 +1 @@
|
||||
ok
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
== uv run pytest --cov (hermetic: no network, live tests skip) ==
|
||||
........................................................................ [ 6%]
|
||||
........................................................................ [ 12%]
|
||||
........................................................................ [ 18%]
|
||||
........................................................................ [ 24%]
|
||||
........................................................................ [ 30%]
|
||||
........................................................................ [ 36%]
|
||||
........................................................................ [ 42%]
|
||||
........................................................................ [ 48%]
|
||||
........................................................................ [ 54%]
|
||||
........................................................................ [ 60%]
|
||||
........................................................................ [ 66%]
|
||||
...................sssssssssss.......................................... [ 73%]
|
||||
........................................................................ [ 79%]
|
||||
........................................................................ [ 85%]
|
||||
........................................................................ [ 91%]
|
||||
........................................................................ [ 97%]
|
||||
............................... [100%]
|
||||
=============================== warnings summary ===============================
|
||||
.venv/lib64/python3.14/site-packages/fastapi/testclient.py:1
|
||||
/var/home/ducoterra/Projects/Personal/dashboards/.venv/lib64/python3.14/site-packages/fastapi/testclient.py:1: StarletteDeprecationWarning: Using `httpx` with `starlette.testclient` is deprecated; install `httpx2` instead.
|
||||
from starlette.testclient import TestClient as TestClient # noqa
|
||||
|
||||
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
|
||||
================================ tests coverage ================================
|
||||
_______________ coverage: platform linux, python 3.14.4-final-0 ________________
|
||||
|
||||
Name Stmts Miss Cover Missing
|
||||
------------------------------------------------------------------
|
||||
src/dashboards/__init__.py 3 0 100%
|
||||
src/dashboards/__main__.py 14 1 93% 32
|
||||
src/dashboards/alerts.py 176 0 100%
|
||||
src/dashboards/api.py 348 0 100%
|
||||
src/dashboards/app.py 178 0 100%
|
||||
src/dashboards/auth.py 265 0 100%
|
||||
src/dashboards/collectors.py 155 5 97% 141-142, 146-147, 164
|
||||
src/dashboards/config.py 120 0 100%
|
||||
src/dashboards/debug.py 14 0 100%
|
||||
src/dashboards/poller.py 165 3 98% 192-194, 279
|
||||
src/dashboards/prom.py 105 5 95% 107, 144, 158, 161, 164
|
||||
src/dashboards/rates.py 37 1 97% 51
|
||||
src/dashboards/severity.py 49 0 100%
|
||||
src/dashboards/sources/__init__.py 0 0 100%
|
||||
src/dashboards/sources/disks.py 130 0 100%
|
||||
src/dashboards/sources/host.py 199 1 99% 147
|
||||
src/dashboards/sources/llm.py 150 1 99% 228
|
||||
src/dashboards/sources/nut.py 413 20 95% 153, 172, 186, 198, 204, 217, 225, 241, 319-320, 322, 579, 591, 626, 657, 661, 718-719, 724, 736
|
||||
src/dashboards/sources/nut_sim.py 134 0 100%
|
||||
src/dashboards/store.py 188 2 99% 255-256
|
||||
------------------------------------------------------------------
|
||||
TOTAL 2843 39 99%
|
||||
Required test coverage of 94% reached. Total coverage: 98.63%
|
||||
1172 passed, 11 skipped, 1 warning in 94.23s (0:01:34)
|
||||
== uv run ruff check src tests agent ==
|
||||
All checks passed!
|
||||
== uv run pyright ==
|
||||
0 errors, 0 warnings, 0 informations
|
||||
== node --check src/dashboards/web/static/*.js ==
|
||||
advisory: dependencies are out of date (AGENTS.md rule 8 — update on purpose):
|
||||
certifi 2026.7.22 2026.10.18 wheel
|
||||
fastapi 0.143.5 0.148.0 wheel
|
||||
starlette 1.8.0 1.9.0 wheel
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
**Implemented (task 12/01 — pin the self-test wording)**
|
||||
- Captured `ups.test.result` from the live upsd (`10.1.0.126:3051`, 2026-10-19, direct from the dev box): `apc` = `No test initiated`, **`cyberpower` = `Done and passed`** (a test has run since the phase-05 capture).
|
||||
- `tests/test_nut.py`: new `LIVE_SELF_TEST_WORDS` table + 3 tests — fixture/capture drift pin (green), and two bug pins asserting the correct verdicts (`ok` for a pass, `unknown` for never-initiated).
|
||||
- Re-captured `tests/fixtures/nut_apc.vars` / `nut_cyberpower.vars` with the script's own NUT+scrub blocks, since the live CyberPower word differed from the fixture.
|
||||
- Confirmed the symptom live against the running dev server: `/api/summary` shows `warn cyberpower | Last self-test: Done and passed` and `warn apc | Last self-test: No test initiated`; `/api/ups/snapshot` `health.checks[]` carries both `warn` entries. Evidence in `data/logs/NOTES-self-test.md`.
|
||||
|
||||
**Tests / lint / coverage**
|
||||
- `uv run pytest --cov --cov-fail-under=94` → **1141 passed, 11 skipped, 2 xfailed**, coverage 98.62% (floor 94%).
|
||||
- `uv run ruff check src tests agent` clean · `uv run pyright` 0 errors · `bash .agents/validate.sh` **exit 0**.
|
||||
- `uv run pytest tests/test_nut.py -k self_test` → `2 passed, 2 xfailed`; with `--runxfail` both fail as intended: `assert 'warn' == 'ok'` and `assert 'warn' == 'unknown'`.
|
||||
- `uv run pytest -m live --live` → only the 3 pre-existing `driveripper` agent-transport failures recorded in AGENTS.md; UPS/engine live tests pass.
|
||||
|
||||
**Docs**: AGENTS.md fleet fact corrected — `ups.test.result` is no longer "the factory state on both"; it names each box's captured word and the `LIVE_SELF_TEST_WORDS` pin. No README impact (no behaviour change yet).
|
||||
|
||||
**Decisions / deviations**
|
||||
- The two pinning tests use `xfail(strict=True)` instead of being left red: the pipeline gate requires a green suite per task, and strict xfail becomes a hard failure the moment `assess()` is fixed, so task 02 must delete the marker as part of the fix (`--runxfail` is the recorded "it fails today" evidence).
|
||||
- Re-captured only the NUT fixtures; the scrub pass also wanted to normalise `Local Time is:` in the 16 `smartctl_driveripper_*.txt` captures (they predate that rule) — reverted as unrelated churn.
|
||||
- Not touched (out of scope, deps unmoved): `uv pip list --outdated` currently reports certifi/fastapi/starlette updates — worth a dependency pass, not a NUT-verdict task.
|
||||
|
||||
**Next pending task**: `.agents/phases/todo/12_nut_self_test_verdict/02_verdict_map_for_test_results.md`.
|
||||
+1
@@ -0,0 +1 @@
|
||||
ok
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
== uv run pytest --cov (hermetic: no network, live tests skip) ==
|
||||
........................................................................ [ 6%]
|
||||
........................................................................ [ 12%]
|
||||
........................................................................ [ 18%]
|
||||
........................................................................ [ 24%]
|
||||
........................................................................ [ 31%]
|
||||
........................................................................ [ 37%]
|
||||
........................................................................ [ 43%]
|
||||
........................................................................ [ 49%]
|
||||
........................................................................ [ 56%]
|
||||
........................................................................ [ 62%]
|
||||
........................................................................ [ 68%]
|
||||
...............sssssssssss.............................................. [ 74%]
|
||||
.......................................................xx............... [ 81%]
|
||||
........................................................................ [ 87%]
|
||||
........................................................................ [ 93%]
|
||||
........................................................................ [ 99%]
|
||||
.. [100%]
|
||||
=============================== warnings summary ===============================
|
||||
.venv/lib64/python3.14/site-packages/fastapi/testclient.py:1
|
||||
/var/home/ducoterra/Projects/Personal/dashboards/.venv/lib64/python3.14/site-packages/fastapi/testclient.py:1: StarletteDeprecationWarning: Using `httpx` with `starlette.testclient` is deprecated; install `httpx2` instead.
|
||||
from starlette.testclient import TestClient as TestClient # noqa
|
||||
|
||||
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
|
||||
================================ tests coverage ================================
|
||||
_______________ coverage: platform linux, python 3.14.4-final-0 ________________
|
||||
|
||||
Name Stmts Miss Cover Missing
|
||||
------------------------------------------------------------------
|
||||
src/dashboards/__init__.py 3 0 100%
|
||||
src/dashboards/__main__.py 14 1 93% 32
|
||||
src/dashboards/alerts.py 176 0 100%
|
||||
src/dashboards/api.py 348 0 100%
|
||||
src/dashboards/app.py 178 0 100%
|
||||
src/dashboards/auth.py 265 0 100%
|
||||
src/dashboards/collectors.py 155 5 97% 141-142, 146-147, 164
|
||||
src/dashboards/config.py 120 0 100%
|
||||
src/dashboards/debug.py 14 0 100%
|
||||
src/dashboards/poller.py 165 3 98% 192-194, 279
|
||||
src/dashboards/prom.py 105 5 95% 107, 144, 158, 161, 164
|
||||
src/dashboards/rates.py 37 1 97% 51
|
||||
src/dashboards/severity.py 49 0 100%
|
||||
src/dashboards/sources/__init__.py 0 0 100%
|
||||
src/dashboards/sources/disks.py 130 0 100%
|
||||
src/dashboards/sources/host.py 199 1 99% 147
|
||||
src/dashboards/sources/llm.py 150 1 99% 228
|
||||
src/dashboards/sources/nut.py 390 20 95% 137, 151, 157, 169, 175, 187, 195, 208, 279-280, 282, 498, 510, 545, 578, 582, 639-640, 645, 657
|
||||
src/dashboards/sources/nut_sim.py 134 0 100%
|
||||
src/dashboards/store.py 188 2 99% 255-256
|
||||
------------------------------------------------------------------
|
||||
TOTAL 2820 39 99%
|
||||
Required test coverage of 94% reached. Total coverage: 98.62%
|
||||
1141 passed, 11 skipped, 2 xfailed, 1 warning in 61.73s (0:01:01)
|
||||
== uv run ruff check src tests agent ==
|
||||
All checks passed!
|
||||
== uv run pyright ==
|
||||
0 errors, 0 warnings, 0 informations
|
||||
== node --check src/dashboards/web/static/*.js ==
|
||||
advisory: dependencies are out of date (AGENTS.md rule 8 — update on purpose):
|
||||
certifi 2026.7.22 2026.10.18 wheel
|
||||
fastapi 0.143.5 0.147.0 wheel
|
||||
starlette 1.8.0 1.9.0 wheel
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
Done — all green.
|
||||
|
||||
**Implemented**
|
||||
- `src/dashboards/sources/nut.py`: new explicit outcome map `SELF_TEST_OUTCOMES` + `self_test_outcome()` + `NEVER_TESTED_DETAIL`; the `assess()` `Last self-test` branch now grades the *outcome* — pass words → `ok` (incl. the captured live `Done and passed`), fail words → `fail`, `No test initiated`/empty/no variable → `unknown` with the existing "run a battery test" sentence, unrecognised word → `warn` printing the driver's raw word (+ `test_date` suffix kept).
|
||||
- `src/dashboards/collectors.py`: the UPS self-test **event** severity now calls `nut.self_test_outcome()` instead of its own duplicate pass tuple (same bug: a passed test was logged `warn` while the card beside it read green).
|
||||
- `tests/test_nut.py`: dropped the two task-01 `xfail(strict)` markers (now assert `ok` / `unknown` + exact detail), added `SELF_TEST_WORD_MAP` parametrized table (pass/fail/unknown/warn tiers incl. both live words), case/whitespace variants, unset-vs-never-initiated same-sentence, "no live driver word lands in warn", map-verdict sanity, simulator-word test.
|
||||
- `tests/test_collectors.py`: added `Done and passed` → `info` event case.
|
||||
- Docs: AGENTS.md (`sources/nut.py`, `collectors.py` bullets), README.md (`/ups` health-check paragraph + fixture-quirks paragraph).
|
||||
|
||||
**Verification**
|
||||
- `uv run pytest` → **1165 passed, 11 skipped**; `bash .agents/validate.sh` → **EXIT=0**, coverage **98.62%** (gate 94%), `nut.py` 95 % with the new `self_test_outcome()`/map lines fully covered, `ruff` "All checks passed!", `pyright` "0 errors, 0 warnings".
|
||||
- Live **read-only** check (dev server restarted, signed-in curl against real upsd): `cyberpower → ok | Done and passed`, `apc → unknown | no self-test result reported — run a battery test`; `/api/summary` emits **no** `Last self-test` alert anymore (only apc's legitimate `Battery age: 5.3 years` warn). No live writes.
|
||||
|
||||
**Notes / deviations**
|
||||
- Fixed the duplicate word list in `collectors.py` rather than special-casing the simulator; `nut_sim.py` needed no change (its `PASSED`/`FAILED` land in the right tiers, now asserted).
|
||||
- A word outside the map (e.g. an in-progress phrasing) stays `warn` by design, per the task spec.
|
||||
- validate.sh prints an advisory that certifi/fastapi/starlette are outdated; dependencies were not touched by this task.
|
||||
|
||||
**Next pending task:** `.agents/phases/todo/12_nut_self_test_verdict/03_no_false_warning_overview_and_ups.md` (API-level alert-absence test + the two screenshots).
|
||||
+1
@@ -0,0 +1 @@
|
||||
ok
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
== uv run pytest --cov (hermetic: no network, live tests skip) ==
|
||||
........................................................................ [ 6%]
|
||||
........................................................................ [ 12%]
|
||||
........................................................................ [ 18%]
|
||||
........................................................................ [ 24%]
|
||||
........................................................................ [ 30%]
|
||||
........................................................................ [ 36%]
|
||||
........................................................................ [ 42%]
|
||||
........................................................................ [ 48%]
|
||||
........................................................................ [ 55%]
|
||||
........................................................................ [ 61%]
|
||||
........................................................................ [ 67%]
|
||||
...............sssssssssss.............................................. [ 73%]
|
||||
........................................................................ [ 79%]
|
||||
........................................................................ [ 85%]
|
||||
........................................................................ [ 91%]
|
||||
........................................................................ [ 97%]
|
||||
........................ [100%]
|
||||
=============================== warnings summary ===============================
|
||||
.venv/lib64/python3.14/site-packages/fastapi/testclient.py:1
|
||||
/var/home/ducoterra/Projects/Personal/dashboards/.venv/lib64/python3.14/site-packages/fastapi/testclient.py:1: StarletteDeprecationWarning: Using `httpx` with `starlette.testclient` is deprecated; install `httpx2` instead.
|
||||
from starlette.testclient import TestClient as TestClient # noqa
|
||||
|
||||
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
|
||||
================================ tests coverage ================================
|
||||
_______________ coverage: platform linux, python 3.14.4-final-0 ________________
|
||||
|
||||
Name Stmts Miss Cover Missing
|
||||
------------------------------------------------------------------
|
||||
src/dashboards/__init__.py 3 0 100%
|
||||
src/dashboards/__main__.py 14 1 93% 32
|
||||
src/dashboards/alerts.py 176 0 100%
|
||||
src/dashboards/api.py 348 0 100%
|
||||
src/dashboards/app.py 178 0 100%
|
||||
src/dashboards/auth.py 265 0 100%
|
||||
src/dashboards/collectors.py 155 5 97% 141-142, 146-147, 164
|
||||
src/dashboards/config.py 120 0 100%
|
||||
src/dashboards/debug.py 14 0 100%
|
||||
src/dashboards/poller.py 165 3 98% 192-194, 279
|
||||
src/dashboards/prom.py 105 5 95% 107, 144, 158, 161, 164
|
||||
src/dashboards/rates.py 37 1 97% 51
|
||||
src/dashboards/severity.py 49 0 100%
|
||||
src/dashboards/sources/__init__.py 0 0 100%
|
||||
src/dashboards/sources/disks.py 130 0 100%
|
||||
src/dashboards/sources/host.py 199 1 99% 147
|
||||
src/dashboards/sources/llm.py 150 1 99% 228
|
||||
src/dashboards/sources/nut.py 395 20 95% 137, 151, 157, 169, 175, 187, 195, 208, 279-280, 282, 539, 551, 586, 617, 621, 678-679, 684, 696
|
||||
src/dashboards/sources/nut_sim.py 134 0 100%
|
||||
src/dashboards/store.py 188 2 99% 255-256
|
||||
------------------------------------------------------------------
|
||||
TOTAL 2825 39 99%
|
||||
Required test coverage of 94% reached. Total coverage: 98.62%
|
||||
1165 passed, 11 skipped, 1 warning in 60.54s (0:01:00)
|
||||
== uv run ruff check src tests agent ==
|
||||
All checks passed!
|
||||
== uv run pyright ==
|
||||
0 errors, 0 warnings, 0 informations
|
||||
== node --check src/dashboards/web/static/*.js ==
|
||||
advisory: dependencies are out of date (AGENTS.md rule 8 — update on purpose):
|
||||
certifi 2026.7.22 2026.10.18 wheel
|
||||
fastapi 0.143.5 0.148.0 wheel
|
||||
starlette 1.8.0 1.9.0 wheel
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
**Implemented (task 12/03 — no false warning on the overview and `/ups`)**
|
||||
- `tests/test_api.py`: new `self_test_app` harness (swaps the `nut` job's collector so it keeps serving the *same* payload the test mutates — no poll race) plus 4 pins: passed word → **no** `/api/summary` alert row *and* an `ok`/verbatim-word `health.checks[]` entry on `/api/ups/snapshot`; never-tested (`unknown`) → also silent; `FAILED` → exactly one `fail` row per UPS, `href=/ups`, id `<ups>:health:Last self-test`, check named once.
|
||||
- 4th pin proves **no page/CSS change was needed**: `<li class="${check.status}">` + `ul.checks li.ok .mark { color: var(--ok) }` is the whole render path, and no page/CSS rule names one check.
|
||||
- Live verification (dev server pid 960540, real upsd, `nut ok` before *and* after): `/api/summary` alerts = driveripper unreachable, apc battery age, deskwork memory — **no self-test row**; `/api/ups/snapshot` reads `cyberpower ok | Done and passed`, `apc unknown | …run a battery test`.
|
||||
- Screenshots read and confirmed: `data/logs/self-test-passed-overview.png`, `data/logs/self-test-passed-ups.png`; evidence appended to `data/logs/NOTES-self-test.md`.
|
||||
|
||||
**Tests / lint / coverage**
|
||||
- `uv run pytest` → **1169 passed, 11 skipped** (exit 0). `bash .agents/validate.sh` → **exit 0**: coverage **98.62%** (floor 94%), `ruff check src tests agent` clean, `pyright` 0 errors, `node --check` clean.
|
||||
- `uv run pytest -m live --live` → 8 passed / 3 failed, all three the pre-existing `driveripper` agent-transport failures AGENTS.md already records; every UPS/engine live test passes.
|
||||
|
||||
**Docs**: AGENTS.md testing-policy bullet (verdicts pinned on the surface that shows them, both directions; the no-new-markup rule). No README change — task 02's `/ups` paragraph already stated the behaviour and this task changed none.
|
||||
|
||||
**Decisions / deviations**: no `page-ups.js`/`ups.html`/`dash.css` edit (task said don't restyle — pinned instead); no battery test run on live hardware (phase assumption), so the APC screenshot shows the `unknown` dim state; live upsd emitted unrelated transient `did not answer in 4s` events before the pass — poller handled them per invariant 4, noted in NOTES, not a phase-12 regression; left `uv pip list --outdated` advisory (certifi/fastapi/starlette) untouched since dependencies were not moved here.
|
||||
|
||||
**Next pending task**: `.agents/phases/todo/13_llm_page_and_decode_rate/01_fleet_strip_spacing.md`.
|
||||
+1
@@ -0,0 +1 @@
|
||||
ok
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
== uv run pytest --cov (hermetic: no network, live tests skip) ==
|
||||
........................................................................ [ 6%]
|
||||
........................................................................ [ 12%]
|
||||
........................................................................ [ 18%]
|
||||
........................................................................ [ 24%]
|
||||
........................................................................ [ 30%]
|
||||
........................................................................ [ 36%]
|
||||
........................................................................ [ 42%]
|
||||
........................................................................ [ 48%]
|
||||
........................................................................ [ 54%]
|
||||
........................................................................ [ 61%]
|
||||
........................................................................ [ 67%]
|
||||
...................sssssssssss.......................................... [ 73%]
|
||||
........................................................................ [ 79%]
|
||||
........................................................................ [ 85%]
|
||||
........................................................................ [ 91%]
|
||||
........................................................................ [ 97%]
|
||||
............................ [100%]
|
||||
=============================== warnings summary ===============================
|
||||
.venv/lib64/python3.14/site-packages/fastapi/testclient.py:1
|
||||
/var/home/ducoterra/Projects/Personal/dashboards/.venv/lib64/python3.14/site-packages/fastapi/testclient.py:1: StarletteDeprecationWarning: Using `httpx` with `starlette.testclient` is deprecated; install `httpx2` instead.
|
||||
from starlette.testclient import TestClient as TestClient # noqa
|
||||
|
||||
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
|
||||
================================ tests coverage ================================
|
||||
_______________ coverage: platform linux, python 3.14.4-final-0 ________________
|
||||
|
||||
Name Stmts Miss Cover Missing
|
||||
------------------------------------------------------------------
|
||||
src/dashboards/__init__.py 3 0 100%
|
||||
src/dashboards/__main__.py 14 1 93% 32
|
||||
src/dashboards/alerts.py 176 0 100%
|
||||
src/dashboards/api.py 348 0 100%
|
||||
src/dashboards/app.py 178 0 100%
|
||||
src/dashboards/auth.py 265 0 100%
|
||||
src/dashboards/collectors.py 155 5 97% 141-142, 146-147, 164
|
||||
src/dashboards/config.py 120 0 100%
|
||||
src/dashboards/debug.py 14 0 100%
|
||||
src/dashboards/poller.py 165 3 98% 192-194, 279
|
||||
src/dashboards/prom.py 105 5 95% 107, 144, 158, 161, 164
|
||||
src/dashboards/rates.py 37 1 97% 51
|
||||
src/dashboards/severity.py 49 0 100%
|
||||
src/dashboards/sources/__init__.py 0 0 100%
|
||||
src/dashboards/sources/disks.py 130 0 100%
|
||||
src/dashboards/sources/host.py 199 1 99% 147
|
||||
src/dashboards/sources/llm.py 150 1 99% 228
|
||||
src/dashboards/sources/nut.py 395 20 95% 137, 151, 157, 169, 175, 187, 195, 208, 279-280, 282, 539, 551, 586, 617, 621, 678-679, 684, 696
|
||||
src/dashboards/sources/nut_sim.py 134 0 100%
|
||||
src/dashboards/store.py 188 2 99% 255-256
|
||||
------------------------------------------------------------------
|
||||
TOTAL 2825 39 99%
|
||||
Required test coverage of 94% reached. Total coverage: 98.62%
|
||||
1169 passed, 11 skipped, 1 warning in 62.95s (0:01:02)
|
||||
== uv run ruff check src tests agent ==
|
||||
All checks passed!
|
||||
== uv run pyright ==
|
||||
0 errors, 0 warnings, 0 informations
|
||||
== node --check src/dashboards/web/static/*.js ==
|
||||
advisory: dependencies are out of date (AGENTS.md rule 8 — update on purpose):
|
||||
certifi 2026.7.22 2026.10.18 wheel
|
||||
fastapi 0.143.5 0.148.0 wheel
|
||||
starlette 1.8.0 1.9.0 wheel
|
||||
Reference in New Issue
Block a user