Files
dashboards/tests/test_deploy_scripts.py
T
ducoterra 219d7a7c3b phase: 34_radiance_llm_engine
Everything is verified and green. Final report:

**Phase 34 final verification pass — complete**

- Verified all 6 completed tasks' work against the live fleet and hermetic suite: `llm:radiance` job registered, `llm_engines()` registry drives 404 gate / history defaults / `/api/config` (additive, byte-identical gufo/vllm keys), radiance field map + `/stats` sidecar + 7-position spec curve, `/llm` strip/curve/rows.
- **Defect found & fixed (pre-existing, task 05):** the vLLM-only sentence "vLLM exposes no per-slot JSON…" rendered on the **radiance** panel (`slotSection`'s non-gufo branch). Fix: vLLM line gated to `engine === 'vllm'`; radiance's panel slot section renders nothing (its session home is the strip) — `page-llm.js` + the served-byte pin in `tests/test_api.py` (now asserts the radiance branch is empty and the sentence can't leak). Browser-verified; re-shot `data/logs/34-llm-radiance-rest.png` (the 4.5-min wait found no in-flight request, so the busy shot remains the earlier pass's — its strip rows still stand; only the panel text predates the fix).
- Tests: `uv run pytest` → **2031 passed, 19 skipped** (100%); `uv run pytest --cov` → **98.73%** (floor 94%; config 100%, llm 99%, collectors 98%, api 99%); `uv run ruff check src tests agent && uv run pyright` → clean; `node --check` OK; `uv pip list --outdated` → empty.
- `uv run pytest -m live --live` → **13 passed, 2 skipped** (vLLM unset — correct; live-write opt-in — correct); the read-only radiance test passed.
- Completion criteria: (1) engines `gufo`+`radiance`, `fleet.engines_live` 2, `config.llm.radiance.enabled` true — **pass (live curl)**; (2) unset → 404 no-dial + no job — **pass (spy-pinned, green)**; (3) fixtures present, both families (79 `radiance:` / 198 `vllm:` lines), drift pin — **pass**; (4) panel/curve/rows — **pass (re-shot rest screenshot)**; (5) live radiance test — **pass**; (6) suite/coverage/lint/`bash .agents/validate.sh` (exit 0) — **pass**; (7) docs — below; (8) gufo/vLLM behaviour unchanged — **pass (existing pins untouched)**.
- Documentation: **README.md** full review — env table, LLM-engines section, architecture diagram, capture-script and `/llm` section all name radiance correctly; no inconsistencies found, no changes needed. **AGENTS.md** — the three task-06 fixes (fleet line, route row, module bullets) are in place and all other statements match reality; no changes needed.
- Dev server healthy (`./scripts/dev-server.sh status`: all sources ok, `llm:radiance` answering); all changes left in the working tree for the harness.
- Next pending phase: none — 34 was the last phase in `todo/`.
2026-11-01 18:53:46 -05:00

3575 lines
182 KiB
Python

"""Contract tests for the scripts an operator runs: `deploy/`, `scripts/dev-*.sh`/`.py`, and
`scripts/capture-gateway-config.sh`.
The capture script gets the same treatment as the installer because it can do the same kind of
damage quietly: pointed at a gateway it cannot read, it is six empty files where six verbatim
captures were, and every parser test that reads them then passes against nothing. So it is run
here, against a stub `ssh` and a fake remote tree, and the assertions are about what lands on
disk — including the one edit it makes (a globally routable socket address becomes documentation
space) and the thing it never does (rewrite a config).
There is no shell test framework here — and adding one would buy nothing a subprocess does
not — but phase 10 rests on a sentence that lives in **two** files: the sudoers grant in
`deploy/agent-sudoers`, and the hint `deploy/install-agent.sh` prints when it is run without
root by the unprivileged `ops` account. Two copies of one instruction is exactly what drifts
silently, and the failure is an install that cannot happen on a host nobody is sitting at.
So these tests read the file, run the script the way the operator does (unprivileged, which
exits before the script can touch anything), and require the two lines to be the same line
apart from the path the script was invoked through.
The same reasoning covers `scripts/dev-certs-export.py` and the `scripts/dev-server.sh` call that
runs it (phase 24): the exporter is what turns the durable CA into a file an operator can `scp`,
and the composition — *after* the readiness probe, *as* a warning line — is as much of the
contract as the bytes it writes. So both files are run here and read here.
"""
from __future__ import annotations
import difflib
import importlib.util
import ipaddress
import json
import os
import pwd
import re
import shutil
import socket
import stat
import subprocess
import sys
import threading
import time
from collections.abc import Iterator
from contextlib import contextmanager
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
from pathlib import Path
from typing import Any
import httpx
import pytest
import uvicorn
from auth_contract import ADMIN_PASSWORD, FAST_PBKDF2
from dashboards import auth, certs
from dashboards.app import create_app
from dashboards.config import Settings, Target
from dashboards.store import SampleStore
ROOT = Path(__file__).resolve().parent.parent
DEPLOY = ROOT / "deploy"
SCRIPTS = ROOT / "scripts"
INSTALLER = DEPLOY / "install-agent.sh"
SUDOERS = DEPLOY / "agent-sudoers"
BASH = shutil.which("bash") or "/bin/bash"
#: The grant as the file documents it. `/home/ops/agent-install` is the canonical staging
#: path: a monitored host has no repo checkout, so `deploy/` and `agent/` are copied there
#: (phase 10 task 02) and every host ends up with the same absolute path to grant.
CANONICAL_GRANT = "ops ALL=(root) NOPASSWD: /home/ops/agent-install/deploy/install-agent.sh"
#: The prefix a correct hint line starts with — user, run-as, and NOPASSWD, everything but
#: the path, which is the one thing the installer is allowed to substitute.
GRANT_PREFIX = "ops ALL=(root) NOPASSWD: "
#: Everything a non-root operator needs to hear, besides the grant line itself.
HINT_MUST_SAY = (
"visudo -cf", # check the syntax before installing it
"install -m 0440 -o root -g root", # and install it the way sudoers files are installed
"/etc/sudoers.d/dashboards-agent", # the destination both files name
"deploy/agent-sudoers", # the pointer back to the documented file
)
def _run(args: list[str], cwd: Path | None = None) -> subprocess.CompletedProcess[str]:
return subprocess.run(args, capture_output=True, text=True, cwd=cwd, check=False)
def _grant_lines(text: str) -> list[str]:
"""The sudoers *rules* in a file — comments start with `#`, so this never matches prose."""
return [line for line in text.splitlines() if line.startswith(GRANT_PREFIX)]
def _installer_without_root(*flags: str) -> subprocess.CompletedProcess[str]:
"""Run the installer the way `ops` does.
Skipped as root on purpose: root would go past `need_root` and really install a systemd
unit on the machine running pytest.
"""
if hasattr(os, "geteuid") and os.geteuid() == 0:
pytest.skip("running as root — the installer would install a real unit here")
return _run([BASH, str(INSTALLER), *flags])
# --- deploy/agent-sudoers ---------------------------------------------------------------
def test_agent_sudoers_exists_and_is_a_config_file_not_a_script() -> None:
assert SUDOERS.is_file(), "deploy/agent-sudoers is missing (phase 10 task 01)"
assert not os.access(SUDOERS, os.X_OK), "a sudoers file is data; only install-agent.sh runs"
def test_agent_sudoers_is_exactly_one_grant_line_at_the_canonical_path() -> None:
"""One rule, the installer, the staging path — nothing else may be granted."""
lines = _grant_lines(SUDOERS.read_text())
assert lines == [CANONICAL_GRANT], (
"deploy/agent-sudoers must grant exactly one command, the staged installer:\n" + "\n".join(lines)
)
assert "/home/ops/agent-install" in SUDOERS.read_text()
def test_agent_sudoers_grants_no_shell_editor_or_second_path() -> None:
"""The 'deliberately NOT granted' block has to stay a comment, not become a rule."""
text = SUDOERS.read_text()
not_granted = text.split("deliberately NOT granted", 1)[-1]
for never in ("visudo", "sh", "tee", "systemctl", "usermod", "upscmd", "upsrw"):
assert never in not_granted, f"the file must name {never!r} as deliberately not granted"
assert not_granted.lstrip().startswith("-"), "the block heading is followed by the list"
# Every line of that block is a comment: a stray rule there would be a second grant.
assert _grant_lines(not_granted) == []
# And it names the token file, because "we did not grant reading it" is the point.
assert "/etc/dashboards-agent.token" in not_granted
def test_agent_sudoers_documents_the_why_and_the_two_stage_install() -> None:
"""House style (deploy/nut-sudoers): why it is needed, then check-first install steps."""
text = SUDOERS.read_text()
assert "WHY THIS IS NEEDED" in text
for step in HINT_MUST_SAY:
assert step in text, f"deploy/agent-sudoers must document {step!r}"
# The installed copy is checked too — the file being valid is not the same as the
# installed file being valid (nut-sudoers' third step, and the reason stays).
assert text.count("visudo -cf") >= 2
@pytest.mark.skipif(shutil.which("visudo") is None, reason="visudo is not installed on this box")
def test_agent_sudoers_passes_the_syntax_check_it_documents() -> None:
"""The file tells the operator to run `visudo -cf` on it, so it must survive that."""
result = _run([shutil.which("visudo") or "/usr/sbin/visudo", "-cf", str(SUDOERS)])
assert result.returncode == 0, f"visudo -cf failed:\n{result.stdout}{result.stderr}"
# --- deploy/install-agent.sh without root -----------------------------------------------
def test_installer_without_root_exits_1_and_prints_the_grant_line() -> None:
result = _installer_without_root("--bind", "127.0.0.1")
assert result.returncode == 1, "the non-root refusal keeps its exit code (1)"
assert result.stdout == "", "the refusal is a failure: it goes to stderr, not stdout"
lines = _grant_lines(result.stderr)
assert lines == [f"{GRANT_PREFIX}{Path(os.path.realpath(INSTALLER))}"], (
"the hint must print one grant line naming this script's resolved path:\n" + result.stderr
)
def test_hint_and_the_sudoers_file_are_the_same_line_apart_from_the_path() -> None:
"""The pinned version of the diff in data/logs/NOTES-sudoers.md."""
printed = _installer_without_root("--bind", "127.0.0.1").stderr
hint = _grant_lines(printed)[0]
canonical = _grant_lines(SUDOERS.read_text())[0]
assert hint.startswith(GRANT_PREFIX) and canonical.startswith(GRANT_PREFIX)
assert hint.removeprefix(GRANT_PREFIX).endswith("/deploy/install-agent.sh")
assert hint.removeprefix(GRANT_PREFIX).removeprefix(str(DEPLOY.parent)) == (
canonical.removeprefix(GRANT_PREFIX).removeprefix("/home/ops/agent-install")
), "same user, same (root), same NOPASSWD, same script — only the checkout path differs"
def test_hint_resolves_a_relative_invocation_to_an_absolute_path() -> None:
"""`bash deploy/install-agent.sh` from the repo root still prints a path sudo can match."""
result = _run([BASH, "deploy/install-agent.sh", "--bind", "10.0.0.5"], cwd=ROOT)
assert result.returncode == 1
assert _grant_lines(result.stderr) == [f"{GRANT_PREFIX}{Path(os.path.realpath(INSTALLER))}"]
def test_installer_names_the_two_stage_install_and_points_at_the_file() -> None:
stderr = _installer_without_root("--bind", "127.0.0.1").stderr
for phrase in HINT_MUST_SAY:
assert phrase in stderr, f"the non-root hint must say {phrase!r}, not just 'run as root'"
# The pointer is the file next to *this* script, wherever the checkout lives.
assert str(Path(os.path.realpath(SUDOERS))) in stderr
def test_installer_hint_repeats_the_command_that_was_asked_for() -> None:
"""Copy-pasteable: the hint ends with the same invocation, with the flags it was given."""
stderr = _installer_without_root("--uninstall").stderr
assert f"sudo {Path(os.path.realpath(INSTALLER))} --uninstall" in stderr
def test_installer_help_points_at_the_sudoers_grant() -> None:
"""The header comment *is* the help text, so the grant is discoverable from --help."""
result = _run([BASH, str(INSTALLER), "--help"])
assert result.returncode == 0
assert "deploy/agent-sudoers" in result.stdout
# --- the tunnel machinery stays retired (phase 10) ---------------------------------------
#: Names and ports that only ever existed to serve the ssh-tunnel dev transport, which phase
#: 10 deleted. Every pattern is written as a character class (`[d]ev-…`) so that **this file
#: cannot match its own grep**: the phase criterion demands the repo stay free of those
#: literals, and a guard that reintroduces one to forbid it is the oldest trick there is.
#: Scope excludes `.agents/` (phase files and run reports are history — rewriting a finished
#: phase's record to satisfy a grep would falsify it) and `tests/fixtures/` (verbatim
#: upstream captures: a sector counter or a wheel hash may contain those digits by accident,
#: and rule 7 forbids editing a capture to please a grep).
TUNNEL_PATTERNS = ("[d]ev-tunnels", "DEV_[T]UNNELS", "DEV_[F]ORWARDS", r"912[123]\b", r"[3]494\b")
#: Where those names must not appear: every file that *tells someone what to run*.
#: `tests/fixtures/` is excluded (verbatim captures, see above) and so is `.agents/` —
#: phase files and run reports are history, and rewriting a finished phase's record to
#: satisfy a grep would falsify it.
TUNNEL_FREE_ROOTS = ("scripts", "deploy", "src", "agent", "web")
def _tunnel_scope_files() -> list[Path]:
files: list[Path] = []
for top in TUNNEL_FREE_ROOTS:
for path in (ROOT / top).rglob("*"):
if path.is_file() and path.suffix in (".py", ".sh", ".md", ".css", ".js", ".html"):
files.append(path)
files.append(ROOT / "README.md")
files.append(ROOT / "AGENTS.md")
files.append(ROOT / ".env.example")
files.append(ROOT / ".env.dev.example")
for path in (ROOT / "tests").glob("*.py"):
files.append(path)
return files
def test_dev_tunnel_script_is_deleted() -> None:
"""The tunnel script is gone, not shelved: git history keeps it if it is ever needed."""
# Name built at runtime so this file never carries the literal the grep forbids.
script = ROOT / "scripts" / ("dev-" + "tunnels.sh")
assert not script.exists(), (
"the retired ssh-tunnel dev script is back — phase 10 deleted it deliberately"
)
def test_no_operational_file_mentions_the_tunnel_machinery() -> None:
"""A stale tunnel-env instruction is a setup step nobody can complete any more."""
offenders: list[str] = []
for path in _tunnel_scope_files():
text = path.read_text(errors="replace")
for pattern in TUNNEL_PATTERNS:
if re.search(pattern, text):
offenders.append(f"{path.relative_to(ROOT)}: /{pattern}/")
assert not offenders, "tunnel-era names/ports are back:\n" + "\n".join(offenders)
# --- the mTLS registration is the documented default (phase 24) ---------------------------
#: The three flags that make a host's **install** its registration moment: the run that installs
#: the agent also pulls that host's bundle from the dashboard that owns the authority. The
#: token-mode install is still supported (a host nobody has bundled keeps its bearer token), but
#: it is the compatibility path now, and a setup file that leads with it is a recipe for a fleet
#: of `http://` agents — which is the exact state `TODO.md:3` asked to be rid of.
REGISTRATION_FLAGS = ("--fetch-bundle", "--cert-name", "--session")
#: The files that tell an operator what to type, per host.
REGISTRATION_DOCS = ("README.md", "AGENTS.md", ".env.example", ".env.dev.example")
def _host_target_lines(path: Path) -> list[str]:
"""Every `HOST_TARGETS` assignment line in a file, comments included.
The commented example in `.env.example` counts, because it is the line a reader copies.
"""
return [line for line in path.read_text().splitlines()
if re.search(r"^\s*#?\s*(export\s+)?HOST_TARGETS\s*=", line)]
@pytest.mark.parametrize("name", REGISTRATION_DOCS)
def test_the_setup_docs_teach_registration_with_a_bundle(name: str) -> None:
"""The per-host recipe a reader copies is the bundle fetch, not the bearer token."""
text = (ROOT / name).read_text()
for flag in REGISTRATION_FLAGS:
assert flag in text, f"{name} stopped naming {flag} — the fetch is no longer documented"
@pytest.mark.parametrize("name", (".env.example", ".env.dev.example"))
def test_the_template_target_urls_are_https_and_credential_free(name: str) -> None:
"""A `HOST_TARGETS` line an operator copies is `https://` with no userinfo.
Pinning the *example* is what keeps this true: prose can and should still document the
token-mode shape (it is a supported dial, `collectors.fetch_snapshot` keeps its path byte-for-
byte), but the line that gets pasted into a real config must not seed a non-mTLS fleet. The
empty `HOST_TARGETS=` is allowed — unconfigured is a different fact from misconfigured.
"""
lines = _host_target_lines(ROOT / name)
assert lines, f"{name} lost its HOST_TARGETS documentation entirely"
for line in lines:
value = line.split("=", 1)[1]
urls = re.findall(r"\w+://[^\s\"']+", value)
if not urls:
continue # the empty assignment
bad = [u for u in urls if not u.startswith("https://") or "@" in u]
assert not bad, f"{name} seeds a non-mTLS or userinfo-bearing target: {bad}"
# --- shell syntax (the only gate these scripts get) -------------------------------------
#: Names a shell function must never take. Bash resolves a **function** before an external
#: command of the same name, so defining `install()` in a script that then calls
#: `install -d /somewhere` is not a directory creation — it is the function calling itself,
#: forever. That is not hypothetical: `deploy/install-agent.sh` did exactly this, and the
#: first real install of phase 10 spun on the SMART block for two minutes and installed
#: nothing (no unit, no agent file, no token) while looking like a working script to `bash -n`.
SHADOW_FORBIDDEN = frozenset(
{
"install",
"test",
"time",
"date",
"sort",
"grep",
"sed",
"tee",
"type",
"ulimit",
"wait",
"kill",
"cd",
"pwd",
}
)
_FUNCTION_DEF_RE = r"^([A-Za-z_][A-Za-z0-9_]*)\s*\(\)"
def _function_names(script: Path) -> list[str]:
return re.findall(_FUNCTION_DEF_RE, script.read_text(), flags=re.MULTILINE)
@pytest.mark.parametrize(
"script",
sorted([*DEPLOY.glob("*.sh"), *(ROOT / "scripts").glob("*.sh")]),
ids=lambda p: str(p.relative_to(ROOT)),
)
def test_shell_script_has_valid_syntax(script: Path) -> None:
result = _run([BASH, "-n", str(script)])
assert result.returncode == 0, f"bash -n failed for {script}:\n{result.stderr}"
@pytest.mark.parametrize(
"script",
sorted([*DEPLOY.glob("*.sh"), *(ROOT / "scripts").glob("*.sh")]),
ids=lambda p: str(p.relative_to(ROOT)),
)
def test_no_shell_function_is_named_after_a_coreutil_it_could_be_asked_to_run(script: Path) -> None:
"""`install()` + `install -d` is infinite recursion, and `bash -n` cannot see it."""
shadowed = SHADOW_FORBIDDEN.intersection(_function_names(script))
assert not shadowed, (
f"{script.relative_to(ROOT)} defines function(s) {sorted(shadowed)} that shadow an "
"external command: bash runs the function, so any call meant for the program recurses"
)
# --- the install path, run for real against a sandboxed root boundary --------------------
#: The commands of `install()` that would touch the machine running pytest. Each one is a
#: PATH stub that records its arguments and succeeds — the same trick `ScriptedNutClient` is
#: for the UPS wire: fake the privileged boundary, run the real logic.
ROOT_BOUNDARY_STUBS = ("id", "getent", "useradd", "usermod", "chown", "systemctl", "sudo")
#: The three absolute destinations the installer writes to, rewritten into a temp directory
#: so the test exercises the body instead of the operator's `/usr` and `/etc`.
SANDBOX_REWRITES = {
'AGENT_DIR="/usr/local/lib/dashboards-agent"': 'AGENT_DIR="{root}/lib"',
'TOKEN_FILE="/etc/dashboards-agent.token"': 'TOKEN_FILE="{root}/token"',
'CERT_FILE="/etc/dashboards-agent.certs"': 'CERT_FILE="{root}/certs"',
'UNIT="/etc/systemd/system/$SERVICE.service"': 'UNIT="{root}/dashboards-agent.service"',
'ROUTECTL_TARGET="/usr/local/sbin/dashboards-routectl.py"':
'ROUTECTL_TARGET="{root}/sbin/dashboards-routectl.py"',
'ROUTECTL_SOCKET_UNIT="/etc/systemd/system/dashboards-routectl.socket"':
'ROUTECTL_SOCKET_UNIT="{root}/dashboards-routectl.socket"',
'ROUTECTL_SERVICE_UNIT="/etc/systemd/system/dashboards-routectl@.service"':
'ROUTECTL_SERVICE_UNIT="{root}/dashboards-routectl@.service"',
'ROUTECTL_SOCKET_PATH="/run/dashboards-routectl.sock"':
'ROUTECTL_SOCKET_PATH="{root}/run/dashboards-routectl.sock"',
'ROUTECTL_STATE_DIR="/var/lib/dashboards-routectl"':
'ROUTECTL_STATE_DIR="{root}/var-lib/dashboards-routectl"',
}
def _sandbox_installer(tmp_path: Path) -> tuple[Path, Path, dict[str, str]]:
"""A copy of the installer whose writes land in `tmp_path`, plus a stubbed PATH.
Returns (script, stub call log, env). `agent/host_agent.py` is stubbed next to the copy
because the script resolves the agent as `../agent/host_agent.py`.
"""
text = INSTALLER.read_text()
target = tmp_path / "target"
for old, new in SANDBOX_REWRITES.items():
assert old in text, f"the installer moved {old!r} — update SANDBOX_REWRITES with it"
text = text.replace(old, new.format(root=target))
script = tmp_path / "deploy" / "install-agent.sh"
script.parent.mkdir(parents=True)
script.write_text(text)
(tmp_path / "agent").mkdir()
(tmp_path / "agent" / "host_agent.py").write_text("# stub agent source\n", encoding="utf-8")
# The routectl sources resolve as `$SCRIPT_DIR/…`, so the real files land next to the
# copy: the guard's `[ -f "$_src" ]` check and the re-run `cmp` both need them.
for _name in ("dashboards-routectl.py", "dashboards-routectl.socket",
"dashboards-routectl@.service"):
shutil.copyfile(DEPLOY / _name, script.parent / _name)
stubs = tmp_path / "stubs"
stubs.mkdir()
call_log = tmp_path / "stub-calls.log"
for name in ROOT_BOUNDARY_STUBS:
stub = stubs / name
# `id -u` must answer 0 or need_root() refuses before the body runs; every other call
# just records itself, which is what the assertions below read.
body = ['#!/bin/sh', f'printf "%s %s\\n" "{name}" "$*" >> "$STUB_LOG"']
if name == "id":
body.append('[ "$1" = "-u" ] && echo 0')
body.append("exit 0")
stub.write_text("\n".join(body) + "\n", encoding="utf-8")
stub.chmod(0o755)
env = {**os.environ, "PATH": f"{stubs}{os.pathsep}{os.environ['PATH']}", "STUB_LOG": str(call_log)}
return script, call_log, env
@pytest.mark.skipif(hasattr(os, "geteuid") and os.geteuid() == 0, reason="running as root")
def test_install_path_installs_into_its_own_paths_and_prints_the_token_once(tmp_path: Path) -> None:
"""The install body end to end: files, unit, token, and no recursion.
The exit code is the regression test for the `install()` shadow: while the function was
named after `/usr/bin/install`, this never returned at all.
"""
script, call_log, env = _sandbox_installer(tmp_path)
try:
result = subprocess.run(
[BASH, str(script), "--bind", "10.0.0.5", "--port", "9120"],
capture_output=True,
text=True,
env=env,
timeout=60,
check=False,
)
except subprocess.TimeoutExpired as exc:
pytest.fail(f"the installer did not return (recursion? partial output: {exc.stdout!r})")
assert result.returncode == 0, f"install failed:\n{result.stdout}\n{result.stderr}"
target = tmp_path / "target"
assert (target / "lib" / "host_agent.py").is_file(), "install -m never landed the agent"
unit = (target / "dashboards-agent.service").read_text()
token_path = target / "token"
token = token_path.read_text().strip()
assert "User=dashboards-agent" in unit
assert f"--token-file {token_path}" in unit, "the unit must use the file, never --token"
assert "--host 10.0.0.5 --port 9120" in unit
# A token-only install runs no TLS, so it gets neither the bundle flag nor the directory
# the bundle unpacks into (the agent falls back to a private mkdtemp without one).
assert "--cert-bundle" not in unit, "no bundle installed means no TLS flag on a token install"
assert "RuntimeDirectory=dashboards-agent" not in unit
# No device filter, on purpose (phase 17): a strict device policy denies every node the
# allow-list fails to match, and systemd matches those globs by *name* against
# /proc/devices — where kernel 7.2 lists NVMe as `blkext`, so the old `/dev/nvme*` entry
# locked the whole device namespace on driveripper. Device access is DAC (the `disk` group
# the installer grants) plus SELinux, the standard SMART-monitoring arrangement.
assert "DevicePolicy" not in unit, (
"a strict device policy with a name-matched allow-list is the deny-all device filter "
"that locked driveripper's SMART reads — the unit must carry none"
)
assert "DeviceAllow" not in unit, "no device filter means no allow-list either"
# PrivateDevices=false survives as the explicit statement of the systemd default: a
# private /dev with no device list dies at spawn (status 208/STDIN), because systemd
# opens /dev/null for the service stdin before it execs python.
assert "PrivateDevices=false" in unit, (
"the explicit default is what keeps a private-/dev sandbox from dying at STDIN"
)
assert token and len(token) >= 32, "a generated token is expected"
assert token in result.stdout, "first install prints the token, and never again"
assert f'HOST_TARGETS="hostname=http://{token}@10.0.0.5:9120"' in result.stdout
calls = call_log.read_text()
assert "systemctl daemon-reload" in calls
assert "systemctl enable --now dashboards-agent" in calls
assert "chown root:dashboards-agent" in calls, "the token file must become group-readable"
#: A line the unit heredoc may legitimately write: a comment, a `[Section]` header, or a
#: systemd directive assignment. Anything else is the unquoted heredoc having *expanded*
#: something — see `test_the_written_unit_is_only_comments_and_directives`.
_UNIT_LINE_RE = re.compile(r"^(?:#|\[[A-Za-z]+\]|[A-Za-z]+=)")
@pytest.mark.skipif(hasattr(os, "geteuid") and os.geteuid() == 0, reason="running as root")
def test_the_written_unit_is_only_comments_and_directives(tmp_path: Path) -> None:
"""The unit heredoc is unquoted so `$TLS_UNIT_LINES` and `$TLS_EXEC_ARGS` can expand.
That is also what executes its **comments**: writing the phase-17 rationale with backticks
around `disk`, `blkext` and `/dev/nvme*` made the install run them (`disk: command not
found`, smartctl's version banner) and paste the output into the unit file, with `bash -n`
and every text assertion still happy. Quote the heredoc and phase 15's interpolated lines
stop working, so the guard is on the *result*: a unit line is a comment, a section header,
or a directive assignment — never the output of something the prose mentioned.
"""
script, _call_log, env = _sandbox_installer(tmp_path)
result = subprocess.run(
[BASH, str(script), "--bind", "127.0.0.1", "--port", "9199"],
capture_output=True,
text=True,
env=env,
timeout=60,
check=False,
)
assert result.returncode == 0, f"install failed:\n{result.stdout}\n{result.stderr}"
unit = (tmp_path / "target" / "dashboards-agent.service").read_text()
offenders = [line for line in unit.splitlines() if line.strip() and not _UNIT_LINE_RE.match(line)]
assert not offenders, "the unit heredoc expanded its own text into the unit file:\n" + "\n".join(
offenders
)
assert result.stderr == "", "installing must not execute anything the unit's comments mention"
# --- the template's unit: no device filter, and the whole unit pinned (phase 17 task 04) ------
#: The ten lines the pre-phase template wrote between ``PrivateDevices=false`` and
#: ``ProtectSystem=strict`` — the device filter phase 17 removes. Pinned as the *old* text, in
#: order, because the fix is the absence of exactly these lines: re-adding
#: ``DeviceAllow=/dev/nvme* rw`` with ``DevicePolicy=strict`` is the deny-all returning, and a
#: test that only asserted "`DevicePolicy` is absent today" would pass while somebody added
#: the allow-list back under a default `auto` policy that ignores it.
DEVICE_FILTER_LINES = (
"DevicePolicy=strict",
"DeviceAllow=/dev/null rw",
"DeviceAllow=/dev/zero rw",
"DeviceAllow=/dev/full rw",
"DeviceAllow=/dev/random rw",
"DeviceAllow=/dev/urandom rw",
"DeviceAllow=/dev/nvme* rw",
"DeviceAllow=/dev/sd* rw",
"DeviceAllow=/dev/vd* rw",
"DeviceAllow=/dev/sg* rw",
)
#: The unit the template wrote **before** phase 17, rendered for a default token install
#: (bind `10.0.0.5`, port `9120`, no bundle), with the sandbox root spelled `<ROOT>`.
#:
#: This is the whole unit and not a highlight reel: it is the reference the default install is
#: compared against, so a template line added, dropped, reordered or reworded *outside* this
#: phase's remit fails a test instead of landing in the next host's service file. The comment
#: block is included verbatim (it is what the operator reads in `systemctl cat`) even though
#: phase 17 task 01 rewrote that prose on purpose — which is why the comparison below reads
#: directives, and the new rationale is pinned separately for the two facts it must carry.
PRE_PHASE_DEFAULT_UNIT = """[Unit]
Description=Homelab host agent (read-only system metrics)
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=dashboards-agent
ExecStart=/usr/bin/env python3 <ROOT>/target/lib/host_agent.py --host 10.0.0.5 --port 9120 --token-file <ROOT>/target/token
Restart=on-failure
RestartSec=5
Environment=PYTHONUNBUFFERED=1
SyslogIdentifier=dashboards-agent
# The agent reads /proc, /sys and statvfs() and writes nothing, so everything writable can
# be taken away. smartctl is the one thing that needs a real /dev node, so instead of
# PrivateDevices the unit closes all devices and reopens only the disk nodes, read/write
# at the cgroup layer while the code (and smartctl -i -A -H) stays read-only by design.
#
# The pseudo nodes are not decoration: DevicePolicy=strict denies every node that is not
# listed, and systemd needs /dev/null for the service's stdin before it ever execs python —
# without it the unit dies at spawn with "Failed at step STDIN" (status 208), which is how
# the first phase-10 install failed on a live host running systemd 257. /dev/zero, full,
# random and urandom are the rest of the set a PrivateDevices= sandbox would have provided,
# and none of them is a disk.
NoNewPrivileges=true
PrivateTmp=true
PrivateDevices=false
DevicePolicy=strict
DeviceAllow=/dev/null rw
DeviceAllow=/dev/zero rw
DeviceAllow=/dev/full rw
DeviceAllow=/dev/random rw
DeviceAllow=/dev/urandom rw
DeviceAllow=/dev/nvme* rw
DeviceAllow=/dev/sd* rw
DeviceAllow=/dev/vd* rw
DeviceAllow=/dev/sg* rw
ProtectSystem=strict
ProtectHome=read-only
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
RestrictSUIDSGID=true
RestrictNamespaces=true
RestrictRealtime=true
LockPersonality=true
MemoryDenyWriteExecute=true
CapabilityBoundingSet=
SystemCallFilter=@system-service
[Install]
WantedBy=multi-user.target
"""
def _unit_heredoc() -> str:
"""The template's unit heredoc, exactly as the script holds it.
Scoped on purpose: the rest of the script is prose about flags, and a pin that read the
whole file for `DeviceAllow` would be satisfied by deleting a sentence rather than by the
absence of a *unit line*.
"""
text = INSTALLER.read_text()
assert "<<UNIT_FILE" in text, "the unit is still written from a heredoc"
heredoc = text.split("<<UNIT_FILE\n", 1)[1].split("\nUNIT_FILE\n", 1)[0]
assert "[Service]" in heredoc and "CapabilityBoundingSet" in heredoc, (
"the heredoc region extracted from the script is not the unit"
)
return heredoc
def _unit_directives(unit: str) -> list[str]:
"""The lines systemd acts on — every line that is neither a comment nor blank.
Comments carry the phase's reasoning and *are* part of the file, but they are also the one
thing phase 17 task 01 rewrote deliberately (the old block justified the filter; the new
one explains its absence). Directives are what a host runs, so those are compared exactly.
"""
return [line for line in unit.splitlines() if line.strip() and not line.startswith("#")]
def test_the_template_unit_has_no_device_filter_lines() -> None:
"""The fix is the absence, so the absence is what is pinned.
Three layers, because the regression has three shapes: a `DevicePolicy=strict` or
`DeviceAllow=` line back in the heredoc (the deny-all returning on kernel 7.2, where
systemd matches those globs by *name* against `/proc/devices` and lists NVMe as `blkext`,
so `/dev/nvme*` matched nothing and strict denied the whole namespace);
`PrivateDevices=false` removed as "redundant" because it is the systemd default (a private
`/dev` with no device list dies at spawn with `status=208/STDIN`); and a rationale comment
that stops naming the mechanism, which is how the next operator re-adds the filter while
believing they are hardening the unit.
"""
text = INSTALLER.read_text()
# The phase's completion criterion is this exact grep, so it is pinned as one: neither
# directive may appear anywhere in the script, prose included.
assert "DevicePolicy" not in text, "no device policy line anywhere in the installer"
assert "DeviceAllow" not in text, "no device allow-list anywhere in the installer"
heredoc = _unit_heredoc()
offenders = [line for line in heredoc.splitlines() if re.match(r"^\s*(DevicePolicy|DeviceAllow)\s*=", line)]
assert offenders == [], "the unit heredoc grew a device filter line again:\n" + "\n".join(offenders)
assert "PrivateDevices=false" in heredoc, (
"the explicit default is the line that keeps the unit from dying at STDIN; the filter "
"going away does not make it redundant"
)
# The rewritten rationale has to be an explanation, not a shrug (task 01's own criterion).
comment = "\n".join(line for line in heredoc.splitlines() if line.startswith("#"))
assert "/proc/devices" in comment and "blkext" in comment, (
"the comment must name the mechanism, or the next reader cannot tell an omitted filter "
"from a forgotten one"
)
assert "208" in comment, "and the STDIN failure that PrivateDevices=false still prevents"
@pytest.mark.skipif(hasattr(os, "geteuid") and os.geteuid() == 0, reason="running as root")
def test_a_default_install_unit_is_the_pre_phase_unit_minus_the_filter_lines(tmp_path: Path) -> None:
"""No flags writes the unit this script has always written, minus exactly ten lines.
`AGENTS.md` invariant 3 in deployment clothes: a host that needs nothing new must not get a
new unit from an unrelated phase. The reference is the whole pre-phase unit recorded above,
so every directive is compared (not a keyword spot-check) and the only allowed difference is
the device filter's absence — asserted as the ordered list comparison *and* as each of the ten
lines being absent by name, so a filter line silently renamed rather than removed fails too.
"""
script, _call_log, env = _sandbox_installer(tmp_path)
result = _install(script, env, "--bind", "10.0.0.5", "--port", "9120")
assert result.returncode == 0, f"install failed:\n{result.stdout}\n{result.stderr}"
installed = (tmp_path / "target" / "dashboards-agent.service").read_text()
reference = PRE_PHASE_DEFAULT_UNIT.replace("<ROOT>", str(tmp_path))
expected = [line for line in _unit_directives(reference) if line not in DEVICE_FILTER_LINES]
assert len(expected) == len(_unit_directives(reference)) - len(DEVICE_FILTER_LINES), (
"DEVICE_FILTER_LINES must match ten real lines of the reference unit — a filter line "
"this list no longer names is a filter that would pass this test"
)
got = _unit_directives(installed)
drift = "\n".join(
difflib.unified_diff(
expected, got, fromfile="pre-phase unit minus the filter", tofile="installed", lineterm=""
)
)
assert got == expected, f"the default unit drifted from the pre-phase unit by more than the filter:\n{drift}"
# And the ten lines are gone rather than reworded into something equivalent.
assert not [line for line in installed.splitlines() if line.startswith(DEVICE_FILTER_LINES)]
# --- the kernel-gate unit: --as-root / --caps (phase 17 task 02) ---------------------------
#: The exact sentence `--as-root` alone prints. It is not a refusal — a capability-less root is
#: a legitimate if unusual choice — but it is the fact gap 10 paid for: the first root-user
#: attempt on the kernel-7.2 host still read `n/a` on all 16 drives, because the bounding set
#: bounds even root (`CapEff 0`). Pinned verbatim so a paraphrase that drops "not uid" is a
#: test failure rather than an operator rediscovering it.
AS_ROOT_NOTE = (
"note: --as-root with the default empty CapabilityBoundingSet leaves the process "
"capability-less (the kernel gates check capabilities, not uid); pair it with --caps "
"for a kernel-gated host"
)
#: `--caps` on the dedicated service user is not the kernel-gate fix (a non-root process cannot
#: hold these capabilities across exec), so the combination is refused rather than written.
CAPS_REFUSAL = "--caps needs --as-root: a capability grant on the service user is not the kernel-gate fix"
#: The two capabilities the kernel names for the two gates (NVMe SMART log / SG_IO), and the
#: `driveripper` recipe as `--help` must teach it (phase 17 completion criterion).
KERNEL_CAPS = "CAP_SYS_RAWIO,CAP_SYS_ADMIN"
KERNEL_GATE_RECIPE = f"--as-root --caps {KERNEL_CAPS}"
def _install(script: Path, env: dict[str, str], *flags: str) -> subprocess.CompletedProcess[str]:
"""One sandboxed installer run: fake root boundary, real script body."""
try:
return subprocess.run(
[BASH, str(script), *flags],
capture_output=True,
text=True,
env=env,
timeout=60,
check=False,
)
except subprocess.TimeoutExpired as exc: # pragma: no cover - the recursion regression
pytest.fail(f"the installer did not return (flags {flags}, partial output: {exc.stdout!r})")
def _directive(unit: str, key: str) -> list[str]:
"""Every line of the unit assigning `key` — a duplicate assignment is a heredoc bug."""
return [line for line in unit.splitlines() if line.split("=", 1)[0] == key]
@pytest.mark.skipif(hasattr(os, "geteuid") and os.geteuid() == 0, reason="running as root")
def test_the_default_unit_keeps_the_service_user_and_an_empty_bounding_set(tmp_path: Path) -> None:
"""No flags = the unit this script wrote before the flags existed, byte-for-byte.
`CapabilityBoundingSet=` with nothing after the `=` is the capability-less default and what
every host whose drives answer through the `disk` group runs; it is also the line
`--caps` replaces, so its exact spelling is pinned here rather than as `in unit`.
"""
script, _call_log, env = _sandbox_installer(tmp_path)
result = _install(script, env, "--bind", "127.0.0.1", "--port", "9199")
assert result.returncode == 0, f"install failed:\n{result.stdout}\n{result.stderr}"
unit = (tmp_path / "target" / "dashboards-agent.service").read_text()
assert _directive(unit, "User") == ["User=dashboards-agent"]
assert _directive(unit, "CapabilityBoundingSet") == ["CapabilityBoundingSet="]
assert AS_ROOT_NOTE not in result.stdout, "the note belongs to --as-root alone"
@pytest.mark.skipif(hasattr(os, "geteuid") and os.geteuid() == 0, reason="running as root")
def test_as_root_with_caps_writes_the_kernel_gate_unit(tmp_path: Path) -> None:
"""The two lines that reproduce the working `driveripper` unit, exactly.
Comma on the command line, space in the unit: that is systemd's own spelling for
`CapabilityBoundingSet`, and it is the whole reason the flag takes a list rather than the
line. Everything else in the unit — the token file, its `0640 root:dashboards-agent`, the
hardening block — is unchanged by these flags.
"""
script, call_log, env = _sandbox_installer(tmp_path)
kernel_gate = ["--bind", "10.0.0.5", "--port", "9120", "--as-root", "--caps", KERNEL_CAPS]
result = _install(script, env, *kernel_gate)
assert result.returncode == 0, f"install failed:\n{result.stdout}\n{result.stderr}"
unit = (tmp_path / "target" / "dashboards-agent.service").read_text()
assert _directive(unit, "User") == ["User=root"]
assert _directive(unit, "CapabilityBoundingSet") == ["CapabilityBoundingSet=CAP_SYS_RAWIO CAP_SYS_ADMIN"]
assert AS_ROOT_NOTE not in result.stdout, "--caps answers the note: the grant is there"
# The token file's logic is deliberately untouched by --as-root: root reads it either way,
# and re-deriving the mode per service user would be a second rule for no new safety.
token = tmp_path / "target" / "token"
assert stat.S_IMODE(token.stat().st_mode) == 0o640
assert "chown root:dashboards-agent" in call_log.read_text()
assert "--host 10.0.0.5 --port 9120" in unit
@pytest.mark.skipif(hasattr(os, "geteuid") and os.geteuid() == 0, reason="running as root")
def test_as_root_and_caps_write_the_kernel_gate_unit_lines(tmp_path: Path) -> None:
"""The whole flag contract in one place, plus the part only a comparison can pin.
The three flag shapes (`--as-root --caps LIST`, `--caps` alone, `--as-root` alone) each have
their own detailed pin nearby; what none of them shows is **how much** the recipe moves. So:
two installs in two sandboxes at the same bind and port, one default and one kernel-gated, and
their directive lists must differ by exactly the two lines this phase promises and nothing
else — the hardening block, the token file's path, the `ExecStart` and the `[Install]` section
are not these flags' business, and an `--as-root` that also slipped a `ProtectSystem` change in
would be a privilege change nobody asked for. The two half-recipes are then run in their own
sandboxes (one host re-run with different flags is the guard's decision, not the parser's).
"""
plain_script, _plain_log, plain_env = _sandbox_installer(tmp_path / "plain")
plain = _install(plain_script, plain_env, "--bind", "10.1.0.126", "--port", "9120")
assert plain.returncode == 0, f"default install failed:\n{plain.stdout}\n{plain.stderr}"
gate_script, gate_log, gate_env = _sandbox_installer(tmp_path / "gate")
recipe = _install(
gate_script, gate_env, "--bind", "10.1.0.126", "--port", "9120", "--as-root", "--caps", KERNEL_CAPS
)
assert recipe.returncode == 0, f"the driveripper recipe failed:\n{recipe.stdout}\n{recipe.stderr}"
def directives(where: str) -> list[str]:
root = tmp_path / where
unit = (root / "target" / "dashboards-agent.service").read_text()
return _unit_directives(unit.replace(str(root), "<ROOT>"))
changed = [
f"{a} -> {b}"
for a, b in zip(directives("plain"), directives("gate"), strict=True)
if a != b
]
assert changed == [
"User=dashboards-agent -> User=root",
"CapabilityBoundingSet= -> CapabilityBoundingSet=CAP_SYS_RAWIO CAP_SYS_ADMIN",
], "--as-root --caps may write these two lines and nothing else"
assert "chown root:dashboards-agent" in gate_log.read_text(), (
"--as-root leaves the token file's ownership alone: root reads it either way, and the "
"grant must not widen because of a flag that is about capabilities"
)
# The two half-recipes, in their own sandboxes (a differing re-run of one host is the
# guard's business, not the flag parser's).
caps_only_script, caps_only_log, caps_only_env = _sandbox_installer(tmp_path / "caps-only")
caps_only = _install(
caps_only_script, caps_only_env, "--bind", "127.0.0.1", "--port", "9199", "--caps", KERNEL_CAPS
)
assert caps_only.returncode == 1, "--caps without --as-root is refused"
assert CAPS_REFUSAL in caps_only.stderr
assert not caps_only_log.exists(), "and refused before a single privileged command"
root_only_script, _root_only_log, root_only_env = _sandbox_installer(tmp_path / "root-only")
root_only = _install(root_only_script, root_only_env, "--bind", "127.0.0.1", "--port", "9199", "--as-root")
assert root_only.returncode == 0, f"--as-root alone must proceed:\n{root_only.stderr}"
assert AS_ROOT_NOTE in root_only.stdout, "with the capability-less note"
root_unit = (tmp_path / "root-only" / "target" / "dashboards-agent.service").read_text()
assert _directive(root_unit, "User") == ["User=root"]
assert _directive(root_unit, "CapabilityBoundingSet") == ["CapabilityBoundingSet="]
@pytest.mark.skipif(hasattr(os, "geteuid") and os.geteuid() == 0, reason="running as root")
def test_as_root_alone_installs_and_prints_the_capability_note(tmp_path: Path) -> None:
"""A capability-less root proceeds — with the reminder, on stdout, and no refusal."""
script, _call_log, env = _sandbox_installer(tmp_path)
result = _install(script, env, "--bind", "127.0.0.1", "--port", "9199", "--as-root")
assert result.returncode == 0, f"--as-root alone must proceed:\n{result.stdout}\n{result.stderr}"
assert AS_ROOT_NOTE in result.stdout, "the note is the operator's only warning here"
unit = (tmp_path / "target" / "dashboards-agent.service").read_text()
assert _directive(unit, "User") == ["User=root"]
assert _directive(unit, "CapabilityBoundingSet") == ["CapabilityBoundingSet="], (
"--as-root alone writes no capability grant: the note is the whole effect"
)
@pytest.mark.parametrize(
("caps", "refusal"),
[
("CAP_SYS_RAWIO", CAPS_REFUSAL),
("CAP_SYS_RAWIO,CAP_SYS_ADMIN", CAPS_REFUSAL),
("", "--caps needs at least one capability name"),
(" , ", "--caps needs at least one capability name"),
],
ids=["one-cap", "two-caps", "empty", "punctuation-only"],
)
@pytest.mark.skipif(hasattr(os, "geteuid") and os.geteuid() == 0, reason="running as root")
def test_caps_without_as_root_is_refused_before_anything_is_written(
tmp_path: Path, caps: str, refusal: str
) -> None:
"""Exit 1, the reason on stderr, and no side effect at all.
The check sits *before* `need_root` (the `--cert-bundle` validator's reasoning): a wrong
flag combination gets its own sentence instead of a sudoers hint, and nothing after it —
user, group membership, token, unit — can have run.
"""
script, call_log, env = _sandbox_installer(tmp_path)
result = _install(script, env, "--bind", "127.0.0.1", "--port", "9199", "--caps", caps)
assert result.returncode == 1, "the refusal keeps exit 1"
assert result.stdout == "", "a refusal is a failure: nothing on stdout"
assert refusal in result.stderr
assert GRANT_PREFIX not in result.stderr, "a flag mistake is not a sudoers problem"
target = tmp_path / "target"
assert not (target / "dashboards-agent.service").exists(), "refused means nothing written"
assert not (target / "token").exists()
assert not call_log.exists(), "no privileged command ran either"
@pytest.mark.skipif(hasattr(os, "geteuid") and os.geteuid() == 0, reason="running as root")
def test_caps_without_an_argument_is_refused_rather_than_crashing(tmp_path: Path) -> None:
"""`--caps` last on the command line: exit 1 naming the flag, not an `unbound variable`."""
script, _call_log, env = _sandbox_installer(tmp_path)
result = _install(script, env, "--bind", "127.0.0.1", "--port", "9199", "--as-root", "--caps")
assert result.returncode == 1
assert result.stdout == ""
assert "--caps needs a capability list" in result.stderr
@pytest.mark.skipif(hasattr(os, "geteuid") and os.geteuid() == 0, reason="running as root")
def test_the_caps_list_is_normalised_to_systemd_spelling(tmp_path: Path) -> None:
"""Empty entries and stray whitespace never reach the unit as a double space…
…and a `*` stays a literal: the list is split with pathname expansion switched off, so an
operator typo cannot substitute the working directory's file names into `User=`'s partner.
"""
script, _call_log, env = _sandbox_installer(tmp_path)
messy = ["--bind", "127.0.0.1", "--port", "9199", "--as-root", "--caps", "CAP_SYS_RAWIO,, CAP_SYS_ADMIN "]
result = _install(script, env, *messy)
assert result.returncode == 0, f"install failed:\n{result.stdout}\n{result.stderr}"
unit = (tmp_path / "target" / "dashboards-agent.service").read_text()
assert _directive(unit, "CapabilityBoundingSet") == ["CapabilityBoundingSet=CAP_SYS_RAWIO CAP_SYS_ADMIN"]
script_glob, _log, env_glob = _sandbox_installer(tmp_path / "glob")
star = ["--bind", "127.0.0.1", "--port", "9199", "--as-root", "--caps", "*"]
result_glob = _install(script_glob, env_glob, *star)
assert result_glob.returncode == 0, f"install failed:\n{result_glob.stdout}\n{result_glob.stderr}"
unit_glob = (tmp_path / "glob" / "target" / "dashboards-agent.service").read_text()
assert _directive(unit_glob, "CapabilityBoundingSet") == ["CapabilityBoundingSet=*"], (
"the capability list is words, not a glob"
)
def test_help_teaches_the_kernel_gate_recipe() -> None:
"""Completion criterion: the `driveripper` flags are learnable from `--help` alone.
`--help` *is* the header comment, so the sentence that explains why a root service needs
its capabilities named is pinned here too — it is the one thing an executor on a fresh
clone cannot infer from a unit file.
"""
result = _run([BASH, str(INSTALLER), "--help"])
assert result.returncode == 0
assert KERNEL_GATE_RECIPE in result.stdout, "the recipe line must be copy-pasteable"
assert "--as-root run the service as root" in result.stdout
assert "--caps LIST CapabilityBoundingSet line for the unit" in result.stdout
assert "capabilities, not uid" in result.stdout, "the kernel gate is the why of both flags"
assert "capability-less" in result.stdout, "--as-root without --caps has to say what it is"
def test_the_status_probe_is_blind_to_who_the_service_runs_as() -> None:
"""`--status` probes the agent over the wire; the unit's user is invisible to it, on purpose.
A status path that read `AS_ROOT`/`CAPS` would make a health probe depend on flags the
operator may not have passed on this invocation — the probe answers about the port.
"""
status_body = INSTALLER.read_text().split("status() {", 1)[1].split("\n}", 1)[0]
assert "AS_ROOT" not in status_body
assert "CAPS" not in status_body
def test_token_file_is_readable_by_the_service_user_and_nobody_else(tmp_path: Path) -> None:
"""`--token-file` is a path the *agent* opens, as its own user.
systemd does not read the secret for the service, so a 0600 root-owned file makes the
agent exit before it binds. 0640 root:dashboards-agent is the smallest mode that works,
and it is still unreadable by `ops` (which is why deploy/agent-sudoers does not grant it).
"""
script, _call_log, env = _sandbox_installer(tmp_path)
result = subprocess.run(
[BASH, str(script), "--bind", "10.0.0.5"],
capture_output=True,
text=True,
env=env,
timeout=60,
check=False,
)
assert result.returncode == 0, f"install failed:\n{result.stdout}\n{result.stderr}"
mode = stat.S_IMODE((tmp_path / "target" / "token").stat().st_mode)
assert mode == 0o640, f"token file mode is {oct(mode)}, expected 0o640 (group = the agent user)"
assert not mode & 0o007, "the token file must never be world-readable"
# --- the re-run guard: no silent clobber (phase 17 task 03) ----------------------------------
def _refusal(unit: Path) -> str:
"""The sentence a refused re-run prints, with the unit path substituted.
Pinned verbatim because it is the operator's only explanation of why a routine re-run
stopped, and because the diff follows it on **stdout** rather than stderr: the diff is the
payload of the answer (an operator pipes it into a pager or a file), and splitting a
sentence from its diff across two streams only interleaves them.
"""
return f"refusing to overwrite {unit} (generated unit differs); run with --force to apply:"
#: One line the operator can plausibly have edited on the host — `RestartSec` is a real knob,
#: it is not a line any flag writes, and it sits far from every other assertion in these tests.
OPERATOR_EDIT = ("RestartSec=5", "RestartSec=7 # hand-tuned on the host after a flapping start")
def _hand_edit(unit_path: Path) -> str:
"""Edit the installed unit the way an operator does, and return what it now holds."""
text = unit_path.read_text()
assert OPERATOR_EDIT[0] in text, "the template unit lost the line the operator edits"
edited = text.replace(*OPERATOR_EDIT)
unit_path.write_text(edited, encoding="utf-8")
return edited
def _systemctl_calls(call_log: Path) -> list[str]:
"""Only the `systemctl` lines of the stub log — the ones that touch the running service.
The privileged calls before the guard (`id`, `getent`, `usermod`, `chown`) do run again on
a refused re-run: they are the idempotent ones the guard's reasoning accepts. `systemctl`
is what a refused run must not do — no `daemon-reload`, no `enable --now` — so that is the
half compared here.
"""
return [line for line in call_log.read_text().splitlines() if line.startswith("systemctl ")]
@pytest.mark.skipif(hasattr(os, "geteuid") and os.geteuid() == 0, reason="running as root")
def test_a_rerun_that_would_change_the_installed_unit_refuses(tmp_path: Path) -> None:
"""install → hand-edit → re-run: exit 1, the diff on stdout, nothing applied.
This is the incident the guard exists for: `driveripper`'s unit was fixed by hand, and the
installer rewrote it unconditionally. A refused run must leave the unit on disk as the
operator left it and must not reload or re-enable anything, or the refusal arrives after
the thing it is refusing.
"""
script, call_log, env = _sandbox_installer(tmp_path)
unit_path = tmp_path / "target" / "dashboards-agent.service"
token_path = tmp_path / "target" / "token"
first = _install(script, env, "--bind", "10.0.0.5", "--port", "9120")
assert first.returncode == 0, f"first install failed:\n{first.stdout}\n{first.stderr}"
edited = _hand_edit(unit_path)
token_before = token_path.read_bytes()
reloads_before = _systemctl_calls(call_log)
assert reloads_before, "the first install did reload and enable the service"
result = _install(script, env, "--bind", "10.0.0.5", "--port", "9120")
assert result.returncode == 1, "a differing re-run refuses with exit 1"
assert result.stderr == "", "the refusal and its diff are one answer: stdout, not split"
assert _refusal(unit_path) in result.stdout
assert "--- " in result.stdout and "+++ " in result.stdout, "the diff is unified"
assert f"-{OPERATOR_EDIT[1]}" in result.stdout, "the diff shows the operator's line going away"
assert "+RestartSec=5" in result.stdout, "and the template's line coming back"
assert unit_path.read_text() == edited, "a refused run leaves the installed unit byte-identical"
# The reuse path re-reads the existing secret and rewrites the same bytes with the same
# mode; its *value* — what invariant 6 and the HOST_TARGETS entry depend on — never moves,
# which is the guarantee here (mtime is not: the write happens before the guard).
assert token_path.read_bytes() == token_before, "the reused token must not change"
assert stat.S_IMODE(token_path.stat().st_mode) == 0o640
assert _systemctl_calls(call_log) == reloads_before, (
"a refused run must not daemon-reload or enable: that would restart the service the "
"refusal exists to leave alone"
)
@pytest.mark.skipif(hasattr(os, "geteuid") and os.geteuid() == 0, reason="running as root")
def test_force_prints_the_diff_then_writes_the_generated_unit(tmp_path: Path) -> None:
"""`--force` is the opt-in, and the diff still arrives: an operator approves what they saw."""
script, call_log, env = _sandbox_installer(tmp_path)
unit_path = tmp_path / "target" / "dashboards-agent.service"
_install(script, env, "--bind", "10.0.0.5", "--port", "9120")
_hand_edit(unit_path)
result = _install(script, env, "--bind", "10.0.0.5", "--port", "9120", "--force")
assert result.returncode == 0, f"--force must proceed:\n{result.stdout}\n{result.stderr}"
assert _refusal(unit_path) not in result.stdout, "--force is not a refusal"
assert f"-{OPERATOR_EDIT[1]}" in result.stdout and "+RestartSec=5" in result.stdout, (
"the diff is printed even when the answer is yes"
)
unit = unit_path.read_text()
assert "RestartSec=5" in unit and OPERATOR_EDIT[1] not in unit, "the generated unit is written"
assert _systemctl_calls(call_log).count("systemctl enable --now dashboards-agent") == 2, (
"the overwrite is followed by the usual reload/enable"
)
@pytest.mark.skipif(hasattr(os, "geteuid") and os.geteuid() == 0, reason="running as root")
def test_an_unchanged_rerun_is_silent_and_proceeds(tmp_path: Path) -> None:
"""Idempotence is the normal path: same flags, same unit, no diff, no complaint, exit 0."""
script, call_log, env = _sandbox_installer(tmp_path)
unit_path = tmp_path / "target" / "dashboards-agent.service"
first = _install(script, env, "--bind", "10.0.0.5", "--port", "9120")
assert first.returncode == 0, f"first install failed:\n{first.stdout}\n{first.stderr}"
installed = unit_path.read_text()
result = _install(script, env, "--bind", "10.0.0.5", "--port", "9120")
assert result.returncode == 0, f"an identical re-run must proceed:\n{result.stdout}\n{result.stderr}"
assert _refusal(unit_path) not in result.stdout
assert "+++ " not in result.stdout, "nothing differs, so nothing is printed about differences"
assert "reusing the existing token" in result.stdout, "the token idiom is unchanged"
assert unit_path.read_text() == installed
assert _systemctl_calls(call_log).count("systemctl enable --now dashboards-agent") == 2
@pytest.mark.skipif(hasattr(os, "geteuid") and os.geteuid() == 0, reason="running as root")
def test_a_re_run_that_differs_refuses_without_force_and_applies_with_it(tmp_path: Path) -> None:
"""The refuse → force → silent sequence on **one** host, in that order.
Each leg has its own detailed pin beside it; what those cannot show is the transition — a
guard that refuses correctly the first time and then never lets an identical re-run through
silently is the same bug seen from the other side (an operator who has to type `--force`
every deploy stops reading the diff). So: install, hand-edit, re-run (refused, unit left
exactly as edited, no new `systemctl` call), re-run with `--force` (diff first, generated
unit on disk, service re-enabled), then re-run plain once more (silent, unit unmoved).
"""
script, call_log, env = _sandbox_installer(tmp_path)
unit_path = tmp_path / "target" / "dashboards-agent.service"
flags = ["--bind", "10.1.0.126", "--port", "9120", "--as-root", "--caps", KERNEL_CAPS]
first = _install(script, env, *flags)
assert first.returncode == 0, f"first install failed:\n{first.stdout}\n{first.stderr}"
edited = _hand_edit(unit_path)
reloads = len(_systemctl_calls(call_log))
refused = _install(script, env, *flags)
assert refused.returncode == 1, "leg 1: a differing re-run refuses"
assert _refusal(unit_path) in refused.stdout and "+++ " in refused.stdout
assert unit_path.read_text() == edited, "leg 1: the hand edit survives"
assert len(_systemctl_calls(call_log)) == reloads, "leg 1: nothing was reloaded or re-enabled"
applied = _install(script, env, *flags, "--force")
assert applied.returncode == 0, f"leg 2: --force failed:\n{applied.stdout}\n{applied.stderr}"
assert "+++ " in applied.stdout, "leg 2: the diff is printed even on a yes"
assert unit_path.read_text() != edited, "leg 2: the generated unit replaced the hand edit"
assert "RestartSec=5" in unit_path.read_text()
generated = unit_path.read_text()
# three calls per applied install: daemon-reload, enable --now, and the is-active check
assert len(_systemctl_calls(call_log)) == reloads + 3, "leg 2: reload + enable, as a normal install"
settled = _install(script, env, *flags)
assert settled.returncode == 0, f"leg 3: a silent re-run failed:\n{settled.stdout}\n{settled.stderr}"
assert "refusing to overwrite" not in settled.stdout and "+++ " not in settled.stdout
assert "reusing the existing token" in settled.stdout
assert unit_path.read_text() == generated, "leg 3: the silent path leaves the applied unit in place"
@pytest.mark.skipif(hasattr(os, "geteuid") and os.geteuid() == 0, reason="running as root")
def test_a_fresh_install_never_meets_the_guard(tmp_path: Path) -> None:
"""No installed unit → no comparison, no output about one, and `--force` changes nothing.
The guard is about a *re*-run. A first install must stay exactly the run it was before this
task, with or without `--force` — hence the two sandboxes writing byte-identical units.
"""
plain_script, _plain_log, plain_env = _sandbox_installer(tmp_path / "plain")
forced_script, _forced_log, forced_env = _sandbox_installer(tmp_path / "forced")
plain = _install(plain_script, plain_env, "--bind", "10.0.0.5", "--port", "9120")
forced = _install(forced_script, forced_env, "--bind", "10.0.0.5", "--port", "9120", "--force")
assert plain.returncode == 0, f"a first install failed:\n{plain.stdout}\n{plain.stderr}"
assert forced.returncode == 0, f"--force broke a first install:\n{forced.stdout}\n{forced.stderr}"
for stdout in (plain.stdout, forced.stdout):
assert "refusing to overwrite" not in stdout
assert "+++ " not in stdout
def rendered(where: str) -> str:
"""The unit that sandbox wrote, with its own sandbox root name blanked out.
The two runs live in different directories, so the absolute paths in `ExecStart` and
`--token-file` differ while every *decision* in the unit is the same — and the decision
is what `--force` must not touch.
"""
root = tmp_path / where
return (
(root / "target" / "dashboards-agent.service")
.read_text()
.replace(str(root), "<sandbox>")
)
assert rendered("plain") == rendered("forced"), "--force writes the unit the default install writes"
@pytest.mark.skipif(hasattr(os, "geteuid") and os.geteuid() == 0, reason="running as root")
def test_the_kernel_gate_reproduction_refuses_once_and_then_holds(tmp_path: Path) -> None:
"""The `driveripper` case end to end: a token-mode unit is *not* the kernel-gate unit.
Switching a host to `--as-root --caps` is a real change to a real unit, so it asks first,
applies with `--force`, and is silent afterwards — the flag line in `--help` is a
reproduction command only if running it twice lands the same unit and says nothing twice.
"""
script, _call_log, env = _sandbox_installer(tmp_path)
unit_path = tmp_path / "target" / "dashboards-agent.service"
kernel_gate = ["--bind", "10.1.0.126", "--port", "9120", "--as-root", "--caps", KERNEL_CAPS]
_install(script, env, "--bind", "10.1.0.126", "--port", "9120")
token_mode = unit_path.read_text()
asked = _install(script, env, *kernel_gate)
assert asked.returncode == 1, "a flag change to an installed unit is a change, so it asks"
assert _refusal(unit_path) in asked.stdout
assert "-User=dashboards-agent" in asked.stdout and "+User=root" in asked.stdout
assert "+CapabilityBoundingSet=CAP_SYS_RAWIO CAP_SYS_ADMIN" in asked.stdout
assert unit_path.read_text() == token_mode, "the question must not also be the answer"
applied = _install(script, env, *kernel_gate, "--force")
assert applied.returncode == 0, f"--force failed:\n{applied.stdout}\n{applied.stderr}"
applied_unit = unit_path.read_text()
assert _directive(applied_unit, "User") == ["User=root"]
assert _directive(applied_unit, "CapabilityBoundingSet") == [
"CapabilityBoundingSet=CAP_SYS_RAWIO CAP_SYS_ADMIN"
]
again = _install(script, env, *kernel_gate, "--force")
assert again.returncode == 0, f"the same command twice failed:\n{again.stdout}\n{again.stderr}"
assert "+++ " not in again.stdout, "once applied, the same flags are the zero-noise path"
assert unit_path.read_text() == applied_unit
@pytest.mark.skipif(hasattr(os, "geteuid") and os.geteuid() == 0, reason="running as root")
def test_uninstall_is_still_deliberate_and_never_asks(tmp_path: Path) -> None:
"""The guard belongs to `do_install`: `--uninstall` removes a hand-edited unit without one.
A guard on the teardown path would be a guard that keeps a unit nobody wants, and
`uninstall()` does not render a unit at all.
"""
script, call_log, env = _sandbox_installer(tmp_path)
unit_path = tmp_path / "target" / "dashboards-agent.service"
_install(script, env, "--bind", "10.0.0.5", "--port", "9120")
_hand_edit(unit_path)
result = _install(script, env, "--uninstall")
assert result.returncode == 0, f"uninstall refused:\n{result.stdout}\n{result.stderr}"
assert "refusing to overwrite" not in result.stdout
assert not unit_path.exists(), "uninstall still removes the unit, edited or not"
assert "systemctl disable --now dashboards-agent" in _systemctl_calls(call_log)[-3:]
def test_the_guard_sits_between_the_render_and_the_unit_write() -> None:
"""Text pin for the ordering the behaviour depends on.
The comparison must read the *rendered* unit (every flag, bundle and capability decision
applied) and must come before the write, the `daemon-reload` and the `enable`; a `cat >
"$UNIT" <<UNIT_FILE` would put the clobber back while still passing every behavioural test
above on a host with no installed unit.
"""
text = INSTALLER.read_text()
assert "do_install() {" in text, "the install body is still the function that writes the unit"
# Scoped to do_install: `uninstall()` also reloads the daemon, and an unscoped index would
# compare offsets across two different functions.
body = text.split("do_install() {", 1)[1]
render = body.index('cat > "$TMP_UNIT" <<UNIT_FILE')
guard = body.index('! cmp -s "$UNIT" "$TMP_UNIT"')
write = body.index('cat "$TMP_UNIT" > "$UNIT"')
reload = body.index("systemctl daemon-reload")
enable = body.index('systemctl enable --now "$SERVICE"')
assert render < guard < write < reload < enable
assert 'cat > "$UNIT" <<' not in text, "the template may only write $UNIT after comparing it"
assert 'if [ "$FORCE" -eq 1 ]; then' in text, "--force is the guard's own opt-in branch"
assert "rm -f \"$TMP_UNIT\"" in text, "the rendered temp file is cleaned up on every path"
assert 'mktemp "${TMPDIR:-/tmp}/dashboards-agent-unit.XXXXXX"' in text, (
"the diff's +++ side must name the generated unit, not an anonymous temp file"
)
#: The `--force` help line's sentence (phase 17 completion criterion: the flags are learnable
#: from `--help`, and the diff-first promise is the reason an operator trusts `--force`).
FORCE_HELP_SENTENCE = "overwrite an existing unit even if the generated unit differs"
def test_help_documents_force_and_keeps_the_flag_block_aligned() -> None:
stdout = _run([BASH, str(INSTALLER), "--help"]).stdout
lines = [line for line in stdout.splitlines() if FORCE_HELP_SENTENCE in line]
assert len(lines) == 1, f"exactly one --force flag line is expected, got {lines}"
assert lines[0].lstrip().startswith("--force")
assert "(prints the" in lines[0] and "diff first)" in stdout
# One column for every flag's description: the block is a table, and `--force` landing at
# its own column is how `--help` stays readable as a reference rather than a paragraph.
as_root = next(line for line in stdout.splitlines() if line.lstrip().startswith("--as-root"))
assert lines[0].index(FORCE_HELP_SENTENCE) == as_root.index("run the service as root")
# --- the certificate bundle (phase 15 task 06) --------------------------------------------
#: Where the installed bundle lives — one constant in the script, pinned here so a rename
#: fails a test instead of stranding every already-written unit file.
CERT_FILE_PATH = "/etc/dashboards-agent.certs"
def _fake_bundle_text(revision: str = "3") -> str:
"""A syntactically real bundle: agent cert, agent key, root CA, and the rev line.
Shape only. The installer's validator greps PEM blocks by text exactly like
`resolve_bundle` does (a monitored host has no `cryptography`), so a well-formed *fake*
is all an unprivileged validation run needs; the functional probe tests below use a
real bundle minted by `dashboards.certs`.
"""
def block(kind: str, body: str) -> str:
return f"-----BEGIN {kind}-----\n{body}\n-----END {kind}-----\n"
return (
f"# BUNDLE-REV {revision}\n"
+ block("CERTIFICATE", "AGENTCERT")
+ block("PRIVATE KEY", "AGENTKEY")
+ block("CERTIFICATE", "ROOTCA")
)
def _installer_status(stdout: str) -> str:
"""The line `status()` prints as `health: …`, parsed as JSON when it is JSON."""
for line in stdout.splitlines():
if line.startswith("health: "):
body = line.removeprefix("health: ").strip()
try:
return str(json.loads(body)["ok"])
except (json.JSONDecodeError, KeyError):
return body
pytest.fail(f"the probe printed no health line:\n{stdout}")
@pytest.mark.parametrize(
("shape", "reason"),
[
("missing", "cannot be read"),
("empty", "is empty"),
("no-revision", "BUNDLE-REV"),
("two-keys", "the agent certificate, the agent key and the root CA"),
],
)
def test_a_bad_cert_bundle_is_refused_with_its_reason_before_anything_else(
tmp_path: Path, shape: str, reason: str
) -> None:
"""Completion criterion: `--cert-bundle /nonexistent` refuses with the reason, touches nothing.
The validation runs *before* `need_root`, so the failure names the file rather than
sending the operator to add a sudoers line for a typo in the flag's argument — and
nothing after the validation (user, files, unit) can have run.
"""
if shape == "missing":
path = tmp_path / "absent.bundle"
elif shape == "empty":
path = tmp_path / "empty.bundle"
path.write_text("\n", encoding="ascii")
elif shape == "no-revision":
path = tmp_path / "revless.bundle"
path.write_text(_fake_bundle_text().replace("# BUNDLE-REV 3\n", ""), encoding="ascii")
else: # a bundle with the root *key* in it is exactly what the shape check refuses
path = tmp_path / "leaky.bundle"
extra = "-----BEGIN PRIVATE KEY-----\nROOTKEY\n-----END PRIVATE KEY-----\n"
path.write_text(_fake_bundle_text() + extra, encoding="ascii")
result = _installer_without_root("--cert-bundle", str(path))
assert result.returncode == 2, "the bundle refusal keeps its own exit code (2)"
assert result.stdout == "", "a refusal goes to stderr, not stdout"
assert reason in result.stderr
assert str(path) in result.stderr, "the message names the file the operator passed"
assert GRANT_PREFIX not in result.stderr, "a bad bundle is not a sudoers problem"
def test_a_well_formed_bundle_passes_validation_and_reaches_the_root_check(
tmp_path: Path,
) -> None:
"""Validation is shape-only and never dials: the next refusal is the usual sudoers one."""
path = tmp_path / "agent.bundle"
path.write_text(_fake_bundle_text(), encoding="ascii")
result = _installer_without_root("--bind", "10.0.0.5", "--cert-bundle", str(path))
assert result.returncode == 1
assert _grant_lines(result.stderr), "the bundle validated; what remains is the root boundary"
def test_installer_help_documents_the_cert_bundle_and_its_path() -> None:
result = _run([BASH, str(INSTALLER), "--help"])
assert result.returncode == 0
assert "--cert-bundle" in result.stdout
assert CERT_FILE_PATH in result.stdout
def test_the_bundle_lands_at_the_token_file_idiom_in_the_script() -> None:
"""`0640 root:$AGENT_USER` + chown: the agent opens the bundle itself and re-reads it."""
text = INSTALLER.read_text()
assert f'CERT_FILE="{CERT_FILE_PATH}"' in text
assert 'install -m 0640 "$BUNDLE_SRC" "$CERT_FILE"' in text
assert 'chown root:"$AGENT_USER" "$CERT_FILE"' in text
# 0600 would fail the unit the way it would fail the token file: the service user opens
# the bundle at startup and re-reads the denylist live. Pin the reasoning, not just the mode.
assert "0600 root-owned file would fail the unit" in text
assert "re-reads it when its stamp changes" in text
def test_the_tls_unit_lines_come_from_one_bundle_branch() -> None:
"""Flag + RuntimeDirectory are emitted together, or the unit is a token-mode unit."""
text = INSTALLER.read_text()
match = re.search(r'\n if \[ -f "\$CERT_FILE" \]; then(.*?)\n fi\n', text, re.DOTALL)
assert match, "the TLS unit lines must come from one `if [ -f \"$CERT_FILE\" ]` branch"
block = match.group(1)
assert 'TLS_EXEC_ARGS=" --cert-bundle $CERT_FILE"' in block
assert "RuntimeDirectory=dashboards-agent" in block
assert "${TLS_EXEC_ARGS}" in text, "ExecStart must carry the flag from that branch"
def test_status_probes_tls_with_the_bundle_ca_and_no_client_cert() -> None:
"""The status branch: unit says --cert-bundle → python3 ssl probe, never openssl, no cert."""
status_body = INSTALLER.read_text().split("status() {", 1)[1].split("\n}", 1)[0]
assert "grep -q -- '--cert-bundle'" in status_body
assert "PROTOCOL_TLS_CLIENT" in status_body
assert "load_verify_locations" in status_body
assert "https://" in status_body
assert "load_cert_chain" not in status_body, "the installer holds no client certificate"
assert 'http://$BIND:$PORT/health' in status_body, "token mode keeps the plain probe"
assert "openssl" not in INSTALLER.read_text(), "no new binary dependency on a monitored host"
@pytest.mark.skipif(hasattr(os, "geteuid") and os.geteuid() == 0, reason="running as root")
def test_a_bundle_install_lands_the_file_the_unit_flag_and_the_runtime_directory(
tmp_path: Path,
) -> None:
"""The install body with a bundle: byte-identical file at 0640, TLS unit, https hint."""
bundle = tmp_path / "agent.bundle"
bundle.write_text(_fake_bundle_text(), encoding="ascii")
script, call_log, env = _sandbox_installer(tmp_path)
result = subprocess.run(
[BASH, str(script), "--bind", "10.0.0.5", "--port", "9120", "--cert-bundle", str(bundle)],
capture_output=True,
text=True,
env=env,
timeout=60,
check=False,
)
assert result.returncode == 0, f"install failed:\n{result.stdout}\n{result.stderr}"
cert_path = tmp_path / "target" / "certs"
assert cert_path.is_file(), "install -m never landed the bundle"
assert cert_path.read_text(encoding="ascii") == _fake_bundle_text(), (
"the installed bundle must be byte-identical to the downloaded one"
)
mode = stat.S_IMODE(cert_path.stat().st_mode)
assert mode == 0o640, f"bundle mode is {oct(mode)}, expected 0o640 (group = the agent user)"
assert not mode & 0o007, "the bundle holds the agent's key: never world-readable"
unit = (tmp_path / "target" / "dashboards-agent.service").read_text()
assert f"--cert-bundle {cert_path}" in unit
assert "RuntimeDirectory=dashboards-agent" in unit, (
"ProtectSystem=strict leaves the agent no writable file but this, and the bundle "
"unpacks its PEM blocks there"
)
assert "--token-file" in unit, "the dual-mode line stays — rollout is host by host"
assert 'HOST_TARGETS="hostname=https://10.0.0.5:9120"' in result.stdout, (
"a TLS install points the dashboard at https, with no token in the URL"
)
calls = call_log.read_text()
assert calls.count("chown root:dashboards-agent") == 2, "token and bundle both chowned"
@pytest.mark.skipif(hasattr(os, "geteuid") and os.geteuid() == 0, reason="running as root")
def test_an_unrelated_rerun_reuses_the_installed_bundle(tmp_path: Path) -> None:
"""The token-reuse idiom: a re-run without the flag neither rewrites nor drops the bundle."""
script, _call_log, env = _sandbox_installer(tmp_path)
target = tmp_path / "target"
target.mkdir(parents=True)
cert_path = target / "certs"
cert_path.write_text(_fake_bundle_text(revision="7"), encoding="ascii")
result = subprocess.run(
[BASH, str(script), "--bind", "10.0.0.5"],
capture_output=True,
text=True,
env=env,
timeout=60,
check=False,
)
assert result.returncode == 0, f"re-run failed:\n{result.stdout}\n{result.stderr}"
assert cert_path.read_text(encoding="ascii") == _fake_bundle_text(revision="7")
assert "reusing the installed certificate bundle" in result.stdout
unit = (target / "dashboards-agent.service").read_text()
assert f"--cert-bundle {cert_path}" in unit, "an installed bundle keeps the unit in TLS mode"
@pytest.mark.skipif(hasattr(os, "geteuid") and os.geteuid() == 0, reason="running as root")
def test_uninstall_removes_the_bundle_with_the_token(tmp_path: Path) -> None:
"""An uninstalled agent leaves no private key behind."""
script, call_log, env = _sandbox_installer(tmp_path)
target = tmp_path / "target"
(target / "lib").mkdir(parents=True)
leftovers = {
target / "token": "tok\n",
target / "certs": _fake_bundle_text(),
target / "lib" / "host_agent.py": "# stub\n",
target / "dashboards-agent.service": "[Unit]\n",
}
for path, body in leftovers.items():
path.write_text(body, encoding="ascii")
result = subprocess.run(
[BASH, str(script), "--uninstall"],
capture_output=True,
text=True,
env=env,
timeout=60,
check=False,
)
assert result.returncode == 0, f"uninstall failed:\n{result.stdout}\n{result.stderr}"
for path in leftovers:
assert not path.exists(), f"uninstall left {path} on disk"
assert "systemctl disable --now dashboards-agent" in call_log.read_text()
# --- the --status probe, end to end against the real TLS agent -----------------------------
class DictMeta:
"""The three-method `certs.MetaStore` slice, backed by a dict (the `test_auth.py` idiom)."""
def __init__(self) -> None:
self.rows: dict[str, str] = {}
def get_meta(self, key: str) -> str | None:
return self.rows.get(key)
def set_meta(self, key: str, value: str) -> None:
self.rows[key] = value
def delete_meta(self, key: str) -> int:
return 1 if self.rows.pop(key, None) is not None else 0
def _mint_bundle() -> str:
"""A real bundle from the dashboard's own CA — the artifact the operator downloads."""
store = DictMeta()
state = certs.ensure_certs(store)
state = certs.issue_agent_cert(store, state, "localhost", ["127.0.0.1", "localhost"])
entry = state.agent("localhost")
assert entry is not None
return entry.bundle
def _serve_tls_agent(host_agent: Any, bundle_text: str, where: Path) -> tuple[Any, int]:
"""The real agent handler on a TLS-wrapped loopback port, exactly as the unit runs it."""
path = where / "installed.certs"
path.write_text(bundle_text, encoding="ascii")
bundle, error = host_agent.TlsBundle.load(str(path))
assert error is None and bundle is not None
host_agent.Handler.collector = host_agent.Collector("/", smart=False)
host_agent.Handler.token = None
host_agent.Handler.bundle = bundle
httpd = ThreadingHTTPServer(("127.0.0.1", 0), host_agent.Handler)
httpd.socket = bundle.context.wrap_socket(httpd.socket, server_side=True)
threading.Thread(target=httpd.serve_forever, daemon=True).start()
return httpd, httpd.server_address[1]
def _run_status(script: Path, port: int, env: dict[str, str]) -> str:
result = subprocess.run(
[BASH, str(script), "--status", "--bind", "127.0.0.1", "--port", str(port)],
capture_output=True,
text=True,
env=env,
timeout=60,
check=False,
)
assert result.returncode == 0, f"--status exited {result.returncode}:\n{result.stderr}"
return result.stdout
@pytest.mark.skipif(hasattr(os, "geteuid") and os.geteuid() == 0, reason="running as root")
def test_the_tls_status_probe_reads_health_with_the_ca_and_no_client_cert(
tmp_path: Path, host_agent_module: Any
) -> None:
"""The task-02 ASSUMPTION, proven through the installer: CERT_OPTIONAL + the /health
exemption let a probe that holds only the bundle's CA read /health on a TLS agent."""
bundle = _mint_bundle()
httpd, port = _serve_tls_agent(host_agent_module, bundle, tmp_path)
try:
script, _call_log, env = _sandbox_installer(tmp_path / "installer")
target = tmp_path / "installer" / "target"
target.mkdir(parents=True)
(target / "dashboards-agent.service").write_text(
f"ExecStart=python3 host_agent.py --cert-bundle {target / 'certs'}\n", encoding="ascii"
)
(target / "certs").write_text(bundle, encoding="ascii")
assert _installer_status(_run_status(script, port, env)) == "True"
finally:
httpd.shutdown()
httpd.server_close()
host_agent_module.Handler.bundle = None
@pytest.mark.skipif(hasattr(os, "geteuid") and os.geteuid() == 0, reason="running as root")
def test_the_tls_status_probe_verifies_the_chain_and_says_no_to_another_authority(
tmp_path: Path, host_agent_module: Any
) -> None:
"""The probe loads the CA for a reason: a server signed by a different root is not health."""
httpd, port = _serve_tls_agent(host_agent_module, _mint_bundle(), tmp_path)
try:
script, _call_log, env = _sandbox_installer(tmp_path / "installer")
target = tmp_path / "installer" / "target"
target.mkdir(parents=True)
(target / "dashboards-agent.service").write_text(
f"ExecStart=python3 host_agent.py --cert-bundle {target / 'certs'}\n", encoding="ascii"
)
(target / "certs").write_text(_mint_bundle(), encoding="ascii") # a *different* CA
stdout = _run_status(script, port, env)
finally:
httpd.shutdown()
httpd.server_close()
host_agent_module.Handler.bundle = None
line = _installer_status(stdout)
assert line != "True" and line.startswith("(no answer"), f"the probe must refuse: {line}"
@pytest.mark.skipif(hasattr(os, "geteuid") and os.geteuid() == 0, reason="running as root")
def test_the_tls_status_probe_names_the_bundle_when_it_cannot_read_it(tmp_path: Path) -> None:
"""The bundle is 0640 root:agent — an unprivileged --status cannot read it, and says so."""
script, _call_log, env = _sandbox_installer(tmp_path)
target = tmp_path / "target"
target.mkdir(parents=True)
(target / "dashboards-agent.service").write_text(
f"ExecStart=python3 host_agent.py --cert-bundle {target / 'certs'}\n", encoding="ascii"
)
cert = target / "certs"
cert.write_text(_fake_bundle_text(), encoding="ascii")
cert.chmod(0o000)
line = _installer_status(_run_status(script, 1, env))
assert "cannot read" in line and "run --status as root" in line, line
@pytest.mark.skipif(shutil.which("curl") is None, reason="curl is not installed on this box")
@pytest.mark.skipif(hasattr(os, "geteuid") and os.geteuid() == 0, reason="running as root")
def test_a_token_mode_status_probe_stays_plain_http(tmp_path: Path) -> None:
"""The other branch: no bundle in the unit → the unchanged plain probe, not https."""
script, _call_log, env = _sandbox_installer(tmp_path)
target = tmp_path / "target"
target.mkdir(parents=True)
(target / "dashboards-agent.service").write_text(
"ExecStart=python3 host_agent.py --token-file /etc/dashboards-agent.token\n",
encoding="ascii",
)
result = subprocess.run(
[BASH, str(script), "--status", "--bind", "127.0.0.1", "--port", "1"],
capture_output=True,
text=True,
env=env,
timeout=60,
check=False,
)
assert result.returncode == 0
assert _installer_status(result.stdout).startswith("(no answer"), (
"token mode must probe plain http — nothing listens here, and the refusal is the point"
)
# --- scripts/dev-certs-export.py (phase 24 task 01) ---------------------------------------
#: The dev exporter, and the dev server that calls it. Both are **run** below and **read**
#: below: the bytes a host installs are the contract of the first, and the composition of the
#: second (export *after* the readiness probe, failure *as* a warning) is the contract of the
#: dev loop that has to stop producing `http://` agents.
EXPORTER = ROOT / "scripts" / "dev-certs-export.py"
DEV_SERVER = ROOT / "scripts" / "dev-server.sh"
#: The invariant-3 pair, as two configured hosts: one with a bundle in `meta`, one without.
ISSUED_HOST = "issuedhost"
UNISSUED_HOST = "unissuedhost"
def _load_exporter() -> Any:
"""The exporter as a module — it is a script, not a package member, so import it by path."""
spec = importlib.util.spec_from_file_location("dev_certs_export", EXPORTER)
assert spec is not None and spec.loader is not None
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
@contextmanager
def served_dashboard(tmp_path: Path) -> Iterator[tuple[str, SampleStore]]:
"""A real `create_app(...)` on a real socket, with one host's bundle already issued.
uvicorn in a thread rather than `TestClient`, because the unit under test is an **HTTP
client**: the exporter signs in over the public route and reads the session token back out
of a `Set-Cookie` header, and a transport-level test client can pass that without ever
serialising a header. Port 0, so nothing here can collide with a port another test bound.
The store is injected and closed here, and the two `HOST_TARGETS` entries point at a port
nothing listens on: the app under test must never dial, and a dead target is what keeps
this hermetic. Every other source is switched off explicitly, so an operator running the
suite with `.env.dev` sourced still gets a test of two hosts and no fleet.
"""
db = tmp_path / "export.sqlite3"
store = SampleStore(db)
state = certs.ensure_certs(store)
certs.issue_agent_cert(store, state, ISSUED_HOST, san=[ISSUED_HOST])
settings = Settings(
db_path=str(db),
admin_password=ADMIN_PASSWORD,
pbkdf2_iterations=FAST_PBKDF2,
host_targets=(Target(name=ISSUED_HOST, url="http://127.0.0.1:1"),
Target(name=UNISSUED_HOST, url="http://127.0.0.1:1")),
host_interval=3600,
host_timeout=0.2,
gufo_url="",
vllm_url="",
nut_host="",
)
server = uvicorn.Server(uvicorn.Config(create_app(settings, store), host="127.0.0.1",
port=0, log_level="error", lifespan="on"))
thread = threading.Thread(target=server.run, daemon=True, name="dev-certs-export-test")
thread.start()
try:
for _ in range(2_000):
if server.started:
break
time.sleep(0.01)
assert server.started, "the test dashboard never came up (see the captured stderr)"
port = int(server.servers[0].sockets[0].getsockname()[1])
yield f"http://127.0.0.1:{port}", store
finally:
server.should_exit = True
thread.join(timeout=60)
store.close()
def _export(base: str, out_dir: Path, names: list[str], *,
password: str | None = ADMIN_PASSWORD) -> subprocess.CompletedProcess[str]:
"""Run the exporter exactly the way `dev-server.sh` does, as a subprocess."""
args = [sys.executable, str(EXPORTER), "--url", base, "--out-dir", str(out_dir)]
if password is not None:
args += ["--password", password]
if names:
args += ["--names", *names]
return _run(args)
def _served_bundle(base: str, name: str) -> bytes:
"""What `GET /api/certs/<name>/bundle` answers, fetched the way the exporter fetches it."""
with httpx.Client(base_url=base, timeout=10.0) as client:
login = client.post("/api/auth/login", json={"password": ADMIN_PASSWORD})
login.raise_for_status()
token = login.cookies[auth.SESSION_COOKIE]
answer = client.get(f"/api/certs/{name}/bundle",
headers={"authorization": f"Bearer {token}"})
answer.raise_for_status()
return answer.content
def test_the_export_writes_the_issued_bundle_byte_identical_at_0600(tmp_path: Path) -> None:
"""The task's headline: the file is the stored bundle, at a mode that keeps it private.
Byte-identity is compared against the **route** rather than the `meta` row because the
question this answers is "is the file I am about to `scp` the file the dashboard issued?",
and a bundle that re-signed between the two would make that question unanswerable.
"""
with served_dashboard(tmp_path) as (base, _store):
out = tmp_path / "certs"
result = _export(base, out, [ISSUED_HOST])
assert result.returncode == 0, result.stderr
path = out / f"{ISSUED_HOST}.bundle"
assert path.is_file(), f"no bundle exported; stdout was:\n{result.stdout}"
assert stat.S_IMODE(path.stat().st_mode) == 0o600, (
"a bundle carries a private key; 0600 is its birth mode and stays its mode"
)
assert path.read_bytes() == _served_bundle(base, ISSUED_HOST)
assert ISSUED_HOST in result.stdout and "0600" in result.stdout
def test_an_unissued_host_writes_no_file_and_names_the_certs_route(tmp_path: Path) -> None:
"""`issued: false` is a fact, not a failure: one line, no file, exit 0 (invariant 3)."""
with served_dashboard(tmp_path) as (base, _store):
out = tmp_path / "certs"
result = _export(base, out, [ISSUED_HOST, UNISSUED_HOST])
assert result.returncode == 0, result.stderr
assert not (out / f"{UNISSUED_HOST}.bundle").exists()
note = next(line for line in result.stdout.splitlines() if UNISSUED_HOST in line)
assert "no bundle issued" in note and "/certs" in note, note
assert "!" not in note, f"an unissued host must not read as a failure: {note}"
def test_a_name_outside_host_targets_is_a_note_and_not_a_crash(tmp_path: Path) -> None:
"""The `{"configured": false}` arm: impossible from `HOST_TARGETS`, still never a crash."""
with served_dashboard(tmp_path) as (base, _store):
out = tmp_path / "certs"
result = _export(base, out, ["nosuchhost"])
assert result.returncode == 0, result.stderr
assert not out.exists(), "nothing was issued, so nothing — not even a directory"
assert "HOST_TARGETS" in result.stdout
def test_a_wrong_password_exits_non_zero_and_writes_nothing(tmp_path: Path) -> None:
"""A dev server that cannot be signed in to says so loudly (and the CA stays untouched)."""
with served_dashboard(tmp_path) as (base, _store):
out = tmp_path / "certs"
result = _export(base, out, [ISSUED_HOST], password="definitely-not-the-password")
assert result.returncode == 2, f"a sign-in failure must not look like success: {result}"
assert not out.exists()
assert "sign-in" in result.stderr.lower()
def test_no_password_at_all_is_a_refusal_and_not_a_hang(tmp_path: Path) -> None:
"""`--password` is optional only because `$DASH_ADMIN_PASSWORD` is the dev source of it."""
env = {key: value for key, value in os.environ.items() if key != "DASH_ADMIN_PASSWORD"}
result = subprocess.run(
[sys.executable, str(EXPORTER), "--url", "http://127.0.0.1:1",
"--out-dir", str(tmp_path / "certs"), "--names", ISSUED_HOST],
capture_output=True, text=True, check=False, env=env, timeout=60,
)
assert result.returncode == 2
assert "DASH_ADMIN_PASSWORD" in result.stderr
assert not (tmp_path / "certs").exists()
def test_no_names_at_all_is_a_quiet_zero(tmp_path: Path) -> None:
"""A dashboard with no `HOST_TARGETS` has nothing to export and is not broken."""
result = _export("http://127.0.0.1:1", tmp_path / "certs", [])
assert result.returncode == 0, result.stderr
assert "nothing to export" in result.stdout
assert not (tmp_path / "certs").exists()
def test_a_second_export_is_idempotent_and_says_unchanged(tmp_path: Path) -> None:
"""`restart` runs this every time; a dev loop that rewrote keys on every boot would be noise."""
with served_dashboard(tmp_path) as (base, _store):
out = tmp_path / "certs"
first = _export(base, out, [ISSUED_HOST])
assert first.returncode == 0, first.stderr
path = out / f"{ISSUED_HOST}.bundle"
before = path.read_bytes()
path.chmod(0o644) # somebody loosened it; the export is what puts the mode back
second = _export(base, out, [ISSUED_HOST])
assert second.returncode == 0, second.stderr
assert path.read_bytes() == before, "the stored bundle must not move between exports"
assert stat.S_IMODE(path.stat().st_mode) == 0o600, "an existing file is re-chmodded"
assert "unchanged" in second.stdout
def test_the_export_reads_the_authority_and_never_mints_anything(tmp_path: Path) -> None:
"""The difference between `read_state` and `ensure_certs`, pinned as an observable.
"The dev server should generate certs" is the TODO's wording; the safe reading is *export
what the first boot minted*. If this script ever issued, a stray `restart` would rotate a
fleet's identities — so the serials, the revisions and the root all have to be the same
bytes after the run as before it.
"""
with served_dashboard(tmp_path) as (base, store):
def fingerprint() -> tuple[str, ...]:
listed = certs.read_state(store)
rows = tuple(f"{e.name}:{e.serial}:{e.bundle_rev}:{e.status}"
for e in certs.read_agents(store))
return (f"root:{listed.root_serial}", *rows)
before = fingerprint()
assert _export(base, tmp_path / "certs",
[ISSUED_HOST, UNISSUED_HOST, "nosuchhost"]).returncode == 0
assert fingerprint() == before, "the exporter changed the certificate authority"
def test_the_export_prints_no_key_material_and_no_password(tmp_path: Path) -> None:
"""Invariant 6, on the one path that holds both a session token and a private key."""
with served_dashboard(tmp_path) as (base, _store):
result = _export(base, tmp_path / "certs", [ISSUED_HOST, UNISSUED_HOST])
printed = result.stdout + result.stderr
assert "BEGIN" not in printed, "a PEM block reached the terminal (and the dev log)"
assert ADMIN_PASSWORD not in printed
assert auth.SESSION_COOKIE not in printed, "the token itself must never be printed"
def test_the_exporter_splits_names_the_way_host_targets_looks() -> None:
"""One argument with spaces in it, three arguments, commas: all the same list."""
module = _load_exporter()
assert module.split_names(["alpha beta", "gamma,delta"]) == ["alpha", "beta", "gamma", "delta"]
assert module.split_names([" alpha,,beta "]) == ["alpha", "beta"]
assert module.split_names([]) == []
assert module.split_names(None) == []
def test_the_exporter_reads_the_cookie_the_app_sets() -> None:
"""`auth.SESSION_COOKIE` is imported, not restated — a rename must not silently break dev."""
module = _load_exporter()
assert module.SESSION_COOKIE == auth.SESSION_COOKIE
def test_write_bundle_refuses_a_name_that_would_leave_the_directory(tmp_path: Path) -> None:
"""The route gates names long before this, but this is the function that picks a path."""
module = _load_exporter()
for bad in ("../escape", "nested/x", "/absolute", "", "."):
with pytest.raises(module.ExportError):
module.write_bundle(tmp_path, bad, b"secret")
assert list(tmp_path.iterdir()) == []
def test_the_bundles_only_ever_land_under_the_gitignored_data_tree() -> None:
"""No key, bundle or PEM outside `data/`: the exporter's default and the caller's flag."""
module = _load_exporter()
assert module.DEFAULT_OUT_DIR == ROOT / "data" / "certs"
gitignore = (ROOT / ".gitignore").read_text()
assert re.search(r"^data/$", gitignore, re.MULTILINE), "data/ is the gitignored tree"
dev_server = DEV_SERVER.read_text()
assignments = [line for line in dev_server.splitlines() if line.startswith("CERTDIR=")]
assert assignments == ['CERTDIR="$ROOT/data/certs"'], (
f"the dev server must name exactly one export dir, under data/: {assignments}"
)
assert '--out-dir "$CERTDIR"' in dev_server, "the export must be told where it writes"
def _shell_function(text: str, name: str) -> str:
"""One function's body, so a pin can talk about *that* block and not the whole file."""
match = re.search(rf"^{re.escape(name)}\(\) \{{$", text, re.MULTILINE)
assert match is not None, f"{name}() is no longer a plain function in dev-server.sh"
body = text[match.end():]
end = body.index("\n}")
return body[:end]
def test_dev_server_exports_the_bundles_after_the_readiness_probe() -> None:
"""The order is the whole safety of the dev loop: no bundle export against a dead server."""
text = DEV_SERVER.read_text()
probe = text.index("curl -sf -o /dev/null")
call = text.index('export_bundles "$PORT"')
assert probe < call, "the export must run only once /api/health has answered"
assert "dev-certs-export.py" in _shell_function(text, "export_bundles")
body = _shell_function(text, "export_bundles")
assert "http://127.0.0.1:${port}" in body, "the exporter dials the dev server and nothing else"
# The names are HOST_TARGETS' names, split by the caller: the exporter re-parses no config.
assert "${entry%%=*}" in body
def test_a_failed_bundle_export_never_fails_the_dev_server_start() -> None:
"""A dev-convenience failure is a warning line: the readiness probe already proved the app."""
body = _shell_function(DEV_SERVER.read_text(), "export_bundles")
assert "|| echo" in body, "a failed export must print a warning rather than propagate"
for escape in ("return 1", "exit 1", "set -e"):
assert escape not in body, f"the export can now abort `start` ({escape})"
def test_dev_server_status_prints_the_exported_bundles_block() -> None:
"""`status` answers "is this host's bundle there yet?" without a signed-in curl."""
text = DEV_SERVER.read_text()
body = _shell_function(text, "bundles")
assert "bundles exported" in body and ".bundle" in body
assert "mode" in body, "the block shows the 0600, which is the thing worth checking"
assert re.search(r"^ bundles ;;$", text, re.MULTILINE), "`status` must print the block"
assert "bundles)" in text, "`bundles` is a subcommand of its own"
def test_a_dashboard_that_never_answers_is_named_rather_than_guessed(tmp_path: Path) -> None:
"""Nothing listened: the line says which URL, the exit is non-zero, nothing is written."""
result = _export("http://127.0.0.1:1", tmp_path / "certs", [ISSUED_HOST])
assert result.returncode == 2
assert "no dashboard answered" in result.stderr and "127.0.0.1:1" in result.stderr
assert not (tmp_path / "certs").exists()
def test_an_unexpected_answer_on_the_bundle_route_is_not_read_as_unissued(tmp_path: Path) -> None:
"""Only the two 404 shapes are notes. A 401 means the caller is not authorised, which is news."""
with served_dashboard(tmp_path) as (base, _store):
module = _load_exporter()
with pytest.raises(module.ExportError) as raised:
module.fetch_bundle(base, ISSUED_HOST, "not-a-session-token")
assert "401" in str(raised.value)
def test_one_host_the_route_refuses_never_stops_the_others(tmp_path: Any,
monkeypatch: pytest.MonkeyPatch) -> None:
"""The aggregation `main` owns: every name is attempted, and a failure moves the exit code."""
module = _load_exporter()
attempted: list[str] = []
def fake_fetch(base: str, name: str, token: str) -> bytes | str:
attempted.append(name)
if name == "bad":
raise module.ExportError("bad: GET /api/certs/bad/bundle answered 500: boom")
return b"bundle-bytes"
monkeypatch.setattr(module, "sign_in", lambda base, password: "a-token")
monkeypatch.setattr(module, "fetch_bundle", fake_fetch)
code = module.main(["--url", "http://127.0.0.1:1", "--password", "p",
"--names", "good bad later", "--out-dir", str(tmp_path / "certs")])
assert attempted == ["good", "bad", "later"], "one refused host must not end the run"
assert code == 1, "a bundle nobody exported is a host that stays on http:// — say so"
assert (tmp_path / "certs" / "good.bundle").is_file()
assert not (tmp_path / "certs" / "bad.bundle").exists()
# --- fetching the bundle during registration (phase 24 task 02) ---------------------------
#: `install-agent.sh --fetch-bundle <url> --cert-name <name> --session <token>`: the install
#: run pulls its own bundle from the dashboard, so a host is never registered onto a token URL
#: because an operator forgot a `curl`. The contract has three parts — the bytes that land are
#: the bytes the route serves, a refusal writes *nothing*, and the session token is a fetch
#: credential that appears in no artefact the run leaves behind.
FETCH_UNISSUED = "no bundle issued for"
FETCH_ALL_OR_NOTHING = "--fetch-bundle, --cert-name and --session go together"
FETCH_TWO_SOURCES = "two bundle sources"
FETCH_MODE_REFUSAL = "--fetch-bundle needs an install"
def _sign_in(base: str) -> str:
"""A real session token for the served dashboard — the credential `--session` carries."""
with httpx.Client(base_url=base, timeout=10.0) as client:
login = client.post("/api/auth/login", json={"password": ADMIN_PASSWORD})
login.raise_for_status()
return login.cookies[auth.SESSION_COOKIE]
def _fetch_run(tmp_path: Path, *flags: str,
) -> tuple[subprocess.CompletedProcess[str], Path, Path]:
"""One sandboxed install with a sandbox `TMPDIR`, so the fetched temp file is observable.
The fetch writes to `${TMPDIR:-/tmp}`, so pointing TMPDIR into the sandbox is what turns
"the fetched private key never stays behind" into an assertion instead of a hope — and it
catches the temp file on the refusal paths too, where nothing else was written to look at.
"""
script, call_log, env = _sandbox_installer(tmp_path)
tmpdir = tmp_path / "tmp"
tmpdir.mkdir(parents=True, exist_ok=True)
result = _install(script, {**env, "TMPDIR": str(tmpdir)}, *flags)
return result, tmpdir, call_log
def _fetch(base: str, name: str, token: str) -> list[str]:
"""The three fetch flags, spelled once."""
return ["--fetch-bundle", base, "--cert-name", name, "--session", token]
@contextmanager
def served_body(*, status: int = 200, body: bytes = b"wrong",
media_type: str = "text/html") -> Iterator[str]:
"""A loopback port that answers every GET with one canned body.
Only for the shapes the real route cannot produce: a proxy's 200 error page, a 200 with no
bytes at all. The issued host, the unissued host and a refused session are all real answers
from `served_dashboard`, and those are the legs that matter most.
"""
class Handler(BaseHTTPRequestHandler):
def do_GET(self) -> None:
self.send_response(status)
self.send_header("content-type", media_type)
self.send_header("content-length", str(len(body)))
self.end_headers()
if body:
self.wfile.write(body)
def log_message(self, *_args: Any, **_kwargs: Any) -> None:
pass # the installer's answer is the assertion, not this server's access log
httpd = ThreadingHTTPServer(("127.0.0.1", 0), Handler)
threading.Thread(target=httpd.serve_forever, daemon=True).start()
try:
yield f"http://127.0.0.1:{httpd.server_address[1]}"
finally:
httpd.shutdown()
httpd.server_close()
@pytest.mark.skipif(hasattr(os, "geteuid") and os.geteuid() == 0, reason="running as root")
def test_a_fetched_bundle_installs_byte_identical_at_0640(tmp_path: Path) -> None:
"""The registration leg: fetch, validate, install, TLS unit — one run, no hand-carried file.
Byte-identity is against the same route's answer as task 01's export, because the claim the
installer makes is the same one: the file on the host *is* the row in `meta`. Everything
after the fetch is the existing `--cert-bundle` path, so the mode, the unit's TLS lines and
the https hint are asserted here as unchanged rather than as new.
"""
with served_dashboard(tmp_path) as (base, _store):
token = _sign_in(base)
result, tmpdir, call_log = _fetch_run(
tmp_path, "--bind", "10.0.0.5", "--port", "9120", *_fetch(base, ISSUED_HOST, token))
if result.returncode != 0:
pytest.fail(f"the fetch install failed:\n{result.stdout}\n{result.stderr}")
cert_path = tmp_path / "target" / "certs"
assert cert_path.read_bytes() == _served_bundle(base, ISSUED_HOST)
mode = stat.S_IMODE(cert_path.stat().st_mode)
assert mode == 0o640, f"bundle mode is {oct(mode)}, expected 0o640 (group = agent user)"
unit = (tmp_path / "target" / "dashboards-agent.service").read_text()
assert f"--cert-bundle {cert_path}" in unit
assert "RuntimeDirectory=dashboards-agent" in unit
assert 'HOST_TARGETS="hostname=https://10.0.0.5:9120"' in result.stdout
assert f"fetched the certificate bundle for {ISSUED_HOST} from {base}" in result.stdout
assert "chown root:dashboards-agent" in call_log.read_text()
assert list(tmpdir.iterdir()) == [], "the fetched private key outlived the install"
@pytest.mark.skipif(hasattr(os, "geteuid") and os.geteuid() == 0, reason="running as root")
def test_an_unissued_bundle_is_refused_before_anything_is_written(tmp_path: Path) -> None:
"""`issued: false` is one sentence naming the fix, and the host stays exactly as it was.
This is the invariant-3 answer on the install path: the route says "configured, nothing
issued", and the installer must not read that as a bundle, as a sudoers problem, or as a
reason to create a service user. The stub log is the proof nothing privileged ran: `id -u`
is the first privileged call a real install makes, and it is absent.
"""
with served_dashboard(tmp_path) as (base, _store):
token = _sign_in(base)
result, tmpdir, call_log = _fetch_run(
tmp_path, "--bind", "10.0.0.5", *_fetch(base, UNISSUED_HOST, token))
assert result.returncode == 2, f"a refused fetch keeps exit 2: {result.returncode}"
assert result.stdout == "", "a refusal is a failure: nothing on stdout"
assert FETCH_UNISSUED in result.stderr and UNISSUED_HOST in result.stderr
assert "/certs" in result.stderr, "the sentence names where the certificate is issued"
assert GRANT_PREFIX not in result.stderr, "a refusal is not a sudoers problem"
assert not call_log.exists(), "refused before the root boundary: no privileged command ran"
assert not (tmp_path / "target").exists(), "a refused fetch writes no files at all"
assert list(tmpdir.iterdir()) == [], "the temp file is gone even though it was written"
@pytest.mark.skipif(hasattr(os, "geteuid") and os.geteuid() == 0, reason="running as root")
def test_a_name_the_dashboard_does_not_dial_is_refused_with_its_own_404(tmp_path: Path) -> None:
"""`{"configured": false}` is a third fact, and it is not read as "nothing issued".
The route refuses a name outside `HOST_TARGETS` before any signing, so a typo in
`--cert-name` must say *that* — an operator who is told "no bundle issued" would go looking
for a certificate that was never supposed to exist for a host this dashboard does not dial.
"""
with served_dashboard(tmp_path) as (base, _store):
token = _sign_in(base)
result, tmpdir, call_log = _fetch_run(
tmp_path, "--bind", "10.0.0.5", *_fetch(base, "nosuchhost", token))
assert result.returncode == 2
assert "404" in result.stderr, result.stderr
assert FETCH_UNISSUED not in result.stderr, "not configured is not the same as unissued"
assert "HOST_TARGETS" in result.stderr, "the dashboard's own sentence is echoed"
assert not call_log.exists()
assert list(tmpdir.iterdir()) == []
@pytest.mark.skipif(hasattr(os, "geteuid") and os.geteuid() == 0, reason="running as root")
def test_a_refused_session_names_the_http_status(tmp_path: Path) -> None:
"""A stale or wrong session is a 401 on the wire, and the run says 401.
Not "no bundle" and not a sudoers hint: the operator's move is a fresh sign-in, and the
only way they learn that is the status the dashboard actually answered.
"""
with served_dashboard(tmp_path) as (base, _store):
result, tmpdir, call_log = _fetch_run(
tmp_path, "--bind", "10.0.0.5", *_fetch(base, ISSUED_HOST, "not-a-session-token"))
assert result.returncode == 2
assert "401" in result.stderr, result.stderr
assert "sign in required" in result.stderr, "the dashboard's own sentence is echoed"
assert not call_log.exists()
assert not (tmp_path / "target").exists()
assert list(tmpdir.iterdir()) == []
@pytest.mark.skipif(hasattr(os, "geteuid") and os.geteuid() == 0, reason="running as root")
@pytest.mark.parametrize(
("status", "body", "reason"),
[
(200, b"<html><body>502 from the proxy</body></html>", "# BUNDLE-REV"),
(200, b"", "empty body"),
(500, b"upstream exploded", "500"),
],
ids=["proxy-error-page", "empty-200", "server-error"],
)
def test_a_body_that_is_not_a_bundle_never_becomes_an_install(
tmp_path: Path, status: int, body: bytes, reason: str
) -> None:
"""The shapes the dashboard cannot answer with — and the check that catches each one.
A 200 with a proxy's HTML page is the dangerous one: it is a *success* to any client that
only looks at the status, and installing it produces a unit that exits at startup. It falls
through to the existing shape check, which is the reason one validator serves both bundle
sources. The refusal names `--fetch-bundle` (the flag that was used), not the temp file.
"""
with served_body(status=status, body=body) as base:
result, tmpdir, call_log = _fetch_run(
tmp_path, "--bind", "10.0.0.5", *_fetch(base, ISSUED_HOST, "a-token"))
assert result.returncode == 2, f"{status}/{len(body)} bytes must be refused"
assert reason in result.stderr, result.stderr
assert "--fetch-bundle" in result.stderr
assert not call_log.exists()
assert not (tmp_path / "target").exists()
assert list(tmpdir.iterdir()) == []
@pytest.mark.skipif(hasattr(os, "geteuid") and os.geteuid() == 0, reason="running as root")
def test_a_dashboard_that_never_answers_stops_the_fetch(tmp_path: Path) -> None:
"""Nothing listening on the dashboard URL: the line names it, and no install happens."""
result, tmpdir, call_log = _fetch_run(
tmp_path, "--bind", "10.0.0.5",
*_fetch("http://127.0.0.1:1", ISSUED_HOST, "a-token"))
assert result.returncode == 2
assert "no dashboard answered" in result.stderr and "127.0.0.1:1" in result.stderr
assert not call_log.exists()
assert list(tmpdir.iterdir()) == []
@pytest.mark.skipif(hasattr(os, "geteuid") and os.geteuid() == 0, reason="running as root")
def test_the_session_token_appears_in_no_written_artefact(tmp_path: Path) -> None:
"""Completion criterion: the token is a fetch credential, not a stored one.
The test signs in for a real token and then searches **every** file the run could have
touched plus both output streams. The agent's own bearer token is expected in the token
file and on stdout — that is a different secret, deliberately printed once — so the pin is
specifically that this session value is nowhere.
"""
with served_dashboard(tmp_path) as (base, _store):
token = _sign_in(base)
assert token and token != ADMIN_PASSWORD
result, _tmpdir, call_log = _fetch_run(
tmp_path, "--bind", "10.0.0.5", "--port", "9120",
*_fetch(base, ISSUED_HOST, token))
assert result.returncode == 0, f"install failed:\n{result.stderr}"
where = tmp_path / "target"
assert token not in (where / "token").read_text(), "the token file is the agent's, not ours"
assert token not in (where / "certs").read_text(), "a bundle is not a place for a session"
assert token not in (where / "dashboards-agent.service").read_text()
assert token not in call_log.read_text(), "a privileged call must not carry it either"
assert token not in result.stdout + result.stderr
hits = [str(path.relative_to(tmp_path)) for path in tmp_path.rglob("*")
if path.is_file() and token in path.read_text(encoding="utf-8", errors="replace")]
assert hits == [], f"the session token was written to {hits}"
@pytest.mark.parametrize(
"flags",
[
["--fetch-bundle", "http://127.0.0.1:8090"],
["--cert-name", "deskwork"],
["--session", "a-token"],
["--fetch-bundle", "http://127.0.0.1:8090", "--cert-name", "deskwork"],
["--cert-name", "deskwork", "--session", "a-token"],
],
ids=["url", "name", "token", "url+name", "name+token"],
)
@pytest.mark.skipif(hasattr(os, "geteuid") and os.geteuid() == 0, reason="running as root")
def test_the_fetch_flags_are_all_or_nothing(tmp_path: Path, flags: list[str]) -> None:
"""Half a fetch is a refusal, not a guess: no URL, no name, or no token means nothing dials.
A URL without a name has no route to fetch, and a name without a token is a 401 the
operator would have to diagnose from a stack of unrelated output. Both are answered with
one sentence before the root boundary and before any write — the `--caps` reasoning again.
"""
script, call_log, env = _sandbox_installer(tmp_path)
result = _install(script, env, "--bind", "127.0.0.1", "--port", "9199", *flags)
assert result.returncode == 1, "a flag mistake keeps exit 1, not the fetch's 2"
assert result.stdout == ""
assert FETCH_ALL_OR_NOTHING in result.stderr
assert GRANT_PREFIX not in result.stderr, "a flag mistake is not a sudoers problem"
assert not call_log.exists(), "refused before a single privileged command"
assert not (tmp_path / "target").exists()
@pytest.mark.skipif(hasattr(os, "geteuid") and os.geteuid() == 0, reason="running as root")
def test_two_bundle_sources_are_refused_rather_than_ordered(tmp_path: Path) -> None:
"""`--fetch-bundle` beside `--cert-bundle` is a contradiction: one install, one answer.
"Which one wins" has no good answer here — a stale file and a fresh bundle are two
different identities, and silently preferring either would install a certificate the
operator did not mean to install. So the run stops.
"""
bundle = tmp_path / "agent.bundle"
bundle.write_text(_fake_bundle_text(), encoding="ascii")
script, call_log, env = _sandbox_installer(tmp_path)
result = _install(script, env, "--bind", "127.0.0.1", "--port", "9199",
*_fetch("http://127.0.0.1:8090", "deskwork", "a-token"),
"--cert-bundle", str(bundle))
assert result.returncode == 1
assert FETCH_TWO_SOURCES in result.stderr
assert GRANT_PREFIX not in result.stderr
assert not call_log.exists()
assert not (tmp_path / "target").exists()
@pytest.mark.parametrize("mode", ["--status", "--uninstall"], ids=["status", "uninstall"])
@pytest.mark.skipif(hasattr(os, "geteuid") and os.geteuid() == 0, reason="running as root")
def test_fetching_a_bundle_is_refused_outside_an_install(tmp_path: Path, mode: str) -> None:
"""The fetch belongs to the run that installs, or a key is fetched to be thrown away.
`--status` answers about a port and `--uninstall` removes files; neither has a use for the
bytes, and a silent "flags ignored" on the uninstall path would leave an operator believing
a bundle had been refreshed.
"""
script, call_log, env = _sandbox_installer(tmp_path)
result = _install(script, env, mode,
*_fetch("http://127.0.0.1:8090", "deskwork", "a-token"))
assert result.returncode == 1
assert FETCH_MODE_REFUSAL in result.stderr
assert not call_log.exists(), "and refused before the mode's own privileged work"
def test_help_teaches_the_registration_fetch() -> None:
"""The three flags and the recipe are learnable from `--help`, like every other flag here."""
stdout = _run([BASH, str(INSTALLER), "--help"]).stdout
assert "--fetch-bundle URL" in stdout
assert "--cert-name NAME" in stdout
assert "--session TOKEN" in stdout
assert "GET <url>/api/certs/<cert-name>/bundle" in stdout
assert "fetch credential only" in stdout, "the token's scope has to be learnable, not folklore"
recipe = "--fetch-bundle https://dashboards.example.com --cert-name <HOST_TARGETS name>"
assert recipe in stdout.replace("\\\n", " ").replace(" ", " "), (
"the recipe line must be copy-pasteable from --help"
)
@pytest.mark.skipif(hasattr(os, "geteuid") and os.geteuid() == 0, reason="running as root")
def test_the_sudoers_hint_never_repeats_the_session_token(tmp_path: Path) -> None:
"""The hint quotes a command, so it quotes only the flags that are safe to re-type.
`need_root` ends with `sudo <this script> …` so the operator can copy it. Handing that
string the real argv would print a bearer credential into the terminal, the ssh log and
whoever's scrollback — and the fetch runs *before* the root boundary, so this is the one
path where a good fetch and a refusal share a run. The fetch succeeding here is also the
proof of the order: an unprivileged run can only reach the hint after fetching.
"""
with served_dashboard(tmp_path) as (base, _store):
token = _sign_in(base)
result = _installer_without_root("--bind", "10.0.0.5", "--port", "9120",
*_fetch(base, ISSUED_HOST, token))
assert result.returncode == 1
assert _grant_lines(result.stderr), "the fetch succeeded, so what remains is the grant"
assert f"fetched the certificate bundle for {ISSUED_HOST}" in result.stdout
assert token not in result.stdout + result.stderr
assert "--session" not in result.stderr, "the echoed command must not name the flag either"
def test_the_session_token_is_confined_to_the_fetch() -> None:
"""Structural pin: the install body — everything that writes — cannot see the token.
`unset SESSION_TOKEN` is the promise; this is the proof that the promise is enforceable
rather than aspirational. Every file the installer writes is written inside `do_install`
(the token file, the bundle, the unit), so if the name does not appear anywhere in that
function or in the unit template, no artefact can carry it — the same style of pin
`tests/test_auth.py` and `tests/test_certs.py` hold over the two modules that hold secrets.
"""
text = INSTALLER.read_text()
assert 'unset SESSION_TOKEN' in text, "the fetch must forget the credential when it is done"
assert 'FETCH_SESSION="$SESSION_TOKEN" python3' in text, (
"the token reaches python in the environment: argv is world-readable through `ps`, so a"
" second copy on a command line would widen the exposure instead of limiting it"
)
body = text.split("do_install() {", 1)[1]
assert "SESSION_TOKEN" not in body, "nothing that writes may read the fetch credential"
assert text.count("SESSION_TOKEN") <= 8, (
"the name belongs to the parser, the all-or-nothing check and the fetch; every further"
" mention is another place a bearer token could be printed or written"
)
def test_the_fetch_and_its_shape_check_both_run_before_the_root_boundary() -> None:
"""Text pin for the order the no-partial-install promise depends on.
Behaviourally, a refusal as `ops` proves the refusal comes first; this proves the *shape*
check is not quietly moved after `need_root` (where a bad fetched bundle would produce a
sudoers hint instead of a reason, on the host where the operator can least afford it).
"""
body = INSTALLER.read_text().split("do_install() {", 1)[1]
fetch = body.index("fetch_bundle\n")
shape = body.index('validate_bundle "$BUNDLE_SRC"')
root = body.index("need_root --bind")
assert fetch < shape < root, "fetch, then shape, then root — in that order"
assert 'trap cleanup_fetch EXIT' in INSTALLER.read_text(), (
"the fetched key is cleaned up on every exit path, not only the happy one"
)
@pytest.mark.skipif(hasattr(os, "geteuid") and os.geteuid() == 0, reason="running as root")
def test_a_local_bundle_still_validates_with_its_own_flag_name(tmp_path: Path) -> None:
"""The validator grew a label, and the pre-existing path must read exactly as before.
`--fetch-bundle` needed the refusal to name the flag that was used; the `--cert-bundle`
path must not start naming a flag nobody passed. That is the whole change, so this is the
whole pin — the file-local behaviour around it is covered by the phase-15 tests.
"""
path = tmp_path / "revless.bundle"
path.write_text(_fake_bundle_text().replace("# BUNDLE-REV 3\n", ""), encoding="ascii")
result = _installer_without_root("--cert-bundle", str(path))
assert result.returncode == 2
assert result.stderr.startswith("--cert-bundle"), result.stderr
assert "--fetch-bundle" not in result.stderr
# --- the gateway capture (phase 28 task 04) ------------------------------------------------
#: The script that records `tests/fixtures/gateway_*` — the ground truth the agent's `haproxy`,
#: `nginx` and `sockets` parsers are pinned to. It has no Python-side coverage to speak of (the
#: project's coverage source is `src/dashboards`), so the pins here **run it**, against a fake
#: remote reached through a stubbed `ssh`, the way the installer sandbox stubs `install`.
CAPTURE = SCRIPTS / "capture-gateway-config.sh"
#: The remote documents, and the fixture each one becomes. A new include directory on the gateway
#: means a new entry here *and* a new `case` in the script — the script refuses silently-unknown
#: globs for exactly this reason.
CAPTURE_TARGETS = (
"/etc/haproxy/haproxy.cfg",
"/etc/nginx/nginx.conf",
"/etc/nginx/conf.d/*.conf",
"/etc/nginx/stream.d/*.conf",
"/proc/net/tcp",
"/proc/net/tcp6",
)
#: The stub `ssh`. It drops the options the script passes, records every call, and answers `cat`
#: and `ls` from `$FAKE_REMOTE` as if that directory were the remote filesystem's `/`. Nothing
#: here can reach a network: the point is to exercise the script's own branches (the include
#: globs, the refusal rule, the socket-table edit) with no gateway in sight.
CAPTURE_SSH_STUB = """#!/bin/sh
printf '%s\\n' "$*" >> "$STUB_LOG"
while [ $# -gt 0 ]; do
case "$1" in
-o) shift 2 ;;
-n) shift ;;
*) break ;;
esac
done
host="$1"; shift
command="$*"
if [ "${FAIL_SSH:-0}" = "1" ]; then
echo "ssh: connect to host $host port 22: Connection refused" >&2
exit 255
fi
case "$command" in
"cat "*)
path="${command#cat }"
file="$FAKE_REMOTE$path"
[ -f "$file" ] || { echo "cat: $path: No such file or directory" >&2; exit 1; }
cat "$file"
;;
"getent "*)
# libc resolution on the fake box. Answers come from `$FAKE_REMOTE/getent/<name>.<family>`;
# a file that is not there is `getent`'s own "no such record" (exit 2, no output), which the
# script records as a status rather than a failure. Two env switches stand in for the two
# reads that are *not* a fact about the name: `GETENT_MODE=transport` is ssh dying, and
# `GETENT_MODE=missing` is a gateway with no getent to ask.
family="${command#getent }"
family="${family%% *}"
name="${command##* }"
case "${GETENT_MODE:-ok}" in
transport) echo "ssh: connect to host $host port 22: Connection refused" >&2; exit 255 ;;
missing) echo "bash: line 1: getent: command not found" >&2; exit 127 ;;
esac
file="$FAKE_REMOTE/getent/$name.${family#ahosts}"
[ -f "$file" ] || exit 2
cat "$file"
;;
"ls "*)
spec="${command#ls }"
dir="${spec%/*}"
glob="${spec##*/}"
found=0
for file in "$FAKE_REMOTE$dir"/$glob; do
[ -e "$file" ] || continue
found=1
printf '%s\\n' "${file#"$FAKE_REMOTE"}"
done
[ "$found" = 1 ] || { echo "ls: cannot access '$spec': No such file or directory" >&2; exit 2; }
;;
*)
echo "stub ssh: unsupported remote command: $command" >&2
exit 2
;;
esac
"""
#: A gateway tree small enough to assert on whole, with the two shapes the parsers exist for: a
#: `use_backend` whose target is a fetch expression, and a stream `proxy_pass` of a map variable.
CAPTURE_FAKE_GATEWAY: dict[str, str] = {
"/etc/haproxy/haproxy.cfg": (
"global\n maxconn 4096\n"
"defaults\n mode tcp\n"
"frontend haproxy-22\n bind :::22 v4v6\n default_backend gitea-2222\n"
"frontend haproxy-8443\n bind :::8443 v4v6\n"
" use_backend %[req.hdr(host),lower,map_dom(/etc/haproxy/maps,b0)\n"
"backend gitea-2222\n server gitea gitea.reeselink.com:2222 check inter 5s\n"
),
"/etc/nginx/nginx.conf": (
"user nginx;\n"
"stream {\n include /etc/nginx/stream.d/*.conf;\n}\n"
"http {\n"
" include /etc/nginx/mime.types;\n"
" server { listen 80; listen [::]:80; server_name _; return 301 https://$host; }\n"
" include /etc/nginx/conf.d/*.conf;\n}\n"
),
"/etc/nginx/conf.d/http.conf": (
"server {\n"
" listen 4443 ssl proxy_protocol;\n"
" server_name nextcloud.reeseapps.com;\n"
" ssl_certificate_key /etc/letsencrypt/live/nextcloud.reeseapps.com/privkey.pem;\n"
" location / { proxy_pass http://nextcloud.reeselink.com:11000; }\n}\n"
),
"/etc/nginx/conf.d/tls.conf": (
"server {\n listen 8443 ssl;\n server_name brain.reeseapps.com;\n"
" location / { proxy_pass http://reeseapps-brain-of-reese.reeselink.com:443; }\n}\n"
),
"/etc/nginx/stream.d/stream.conf": (
"map $ssl_preread_server_name $targetBackend {\n"
" default 127.0.0.1:4443;\n"
" brain.example reeseapps-brain-of-reese.reeselink.com:443;\n}\n"
# `resolver` here, inside the stream server, is where this fleet writes it: the fixture's
# `config_directive` must come out of an *included* document, read from the bytes the run
# already captured, with no round trip of its own.
"server {\n listen 443;\n proxy_pass $targetBackend;\n resolver 10.9.8.7;\n}\n"
),
# 8.8.8.8 and 2603:6013::1 are globally routable, `::ffff:8.8.8.8` is a visitor behind a v6
# socket, and 203.0.113.7 is already documentation space. The tx/rx queue pair on the last row
# is spelled like an address column and is not one.
"/proc/net/tcp": (
" sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid"
" timeout inode\n"
" 0: 00000000:1EFF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0"
" 0 1 1 0000000000000000 100 0 0 10 0\n"
" 1: 1B01010A:01BB 08080808:911A 01 00000000:00000000 00:00000000 00000000 101"
" 0 2 1 00000000d22dedba 20 4 28 10 -1\n"
" 2: 0100007F:23A0 017100CB:C0A8 06 08080808:08080808 00:00000000 00000000 0"
" 0 3 3 0000000000000000 20 0 0 10 0\n"
),
"/proc/net/tcp6": (
" sl local_address remote_address"
" st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode\n"
" 0: 00000000000000000000000000000000:01BB 00000000000000000000000000000000:0000 0A"
" 00000000:00000000 00:00000000 00000000 0 0 4 1 0000000000000000 100 0 0 10 0\n"
" 1: 1360032601010031FF005450E0B284FE:01BB 0000000000000000FFFF000008080808:C0AC 01"
" 00000000:00000000 00:00000000 00000000 101 0 5 1 0000000000000000 63 4 26 10 -1\n"
),
}
#: What the fake gateway's libc answers for the names its configs declare. The three arms are the
#: three the capture has to tell apart: an answer (private, so unscrubbed — this is what the real
#: fleet looks like), an answer that is **globally routable** (so it must become documentation
#: space), and no answer at all (a status, not a failure). `nextcloud` deliberately answers a v6
#: that is `::ffff:`-mapped, because `getent ahostsv6` synthesises that spelling for a name with no
#: AAAA record and the agent's own `getaddrinfo` never publishes it.
CAPTURE_FAKE_ANSWERS: dict[str, dict[str, str]] = {
# Private and answered twice over — the A record, and the `::ffff:` spelling `getent ahostsv6`
# synthesises for a name with no AAAA record. One address goes in; nothing moves.
"gitea.reeselink.com": {
"v4": "10.1.0.137 STREAM gitea.reeselink.com\n10.1.0.137 DGRAM \n",
"v6": "::ffff:10.1.0.137 STREAM \n",
},
# Two globally routable answers (one per family) beside one already in documentation space: the
# first two become `203.0.113.1` / `2001:db8::1` and the third stays exactly as it was, which is
# what makes a second run a no-op instead of a renumbering.
"nextcloud.reeselink.com": {
"v4": ("8.8.8.8 STREAM nextcloud.reeselink.com\n"
"203.0.113.9 STREAM nextcloud.reeselink.com\n"),
"v6": "2603:6013:3100:101:5054:ff:fe84:b2e0 STREAM nextcloud.reeselink.com\n",
},
# `reeseapps-brain-of-reese.reeselink.com` is answered by nothing on purpose: the absence of
# the file *is* the nxdomain arm, a status among successes rather than a failed run.
}
def _capture_sandbox(
tmp_path: Path,
gateway: dict[str, str] | None = None,
*,
recorded: dict[str, str] | None = None,
fail_ssh: bool = False,
fail_getent: str | None = None,
answers: dict[str, dict[str, str]] | None = None,
alias: str | None = None,
) -> tuple[Path, Path, Path, dict[str, str]]:
"""A copy of the capture script, a fake gateway, and a PATH whose `ssh` reaches only the fake.
Returns (script, fixtures dir, stub call log, env). The script is copied into
`<tmp>/scripts/` because it derives `tests/fixtures/` from its own location, which is what
keeps the repository's fixtures out of reach of a test.
The parser step needs the repo, so `agent/host_agent.py` is copied beside the copied script:
the sandbox is a checkout shape, and the plan step imports `target_names` from it exactly as
it does when the real script runs. That copy is the pin — a script that re-implemented the
parser would not need it, and one that imported a different module would not find it.
"""
script = tmp_path / "scripts" / CAPTURE.name
script.parent.mkdir(parents=True, exist_ok=True)
shutil.copyfile(CAPTURE, script)
(tmp_path / "agent").mkdir(parents=True, exist_ok=True)
shutil.copyfile(ROOT / "agent/host_agent.py", tmp_path / "agent/host_agent.py")
fake = tmp_path / "gateway"
for path, body in {**CAPTURE_FAKE_GATEWAY, **(gateway or {})}.items():
target = fake / path.lstrip("/")
target.parent.mkdir(parents=True, exist_ok=True)
target.write_text(body, encoding="utf-8")
for name, families in (CAPTURE_FAKE_ANSWERS if answers is None else answers).items():
for family, body in families.items():
answer = fake / "getent" / f"{name}.{family}"
answer.parent.mkdir(parents=True, exist_ok=True)
answer.write_text(body, encoding="utf-8")
fixtures = tmp_path / "tests" / "fixtures"
fixtures.mkdir(parents=True, exist_ok=True)
for name, body in (recorded or {}).items():
(fixtures / name).write_text(body, encoding="utf-8")
stubs = tmp_path / "stubs"
stubs.mkdir()
stub = stubs / "ssh"
stub.write_text(CAPTURE_SSH_STUB, encoding="utf-8")
stub.chmod(0o755)
call_log = tmp_path / "ssh-calls.log"
call_log.write_text("", encoding="utf-8")
env = {**os.environ,
"PATH": f"{stubs}{os.pathsep}{os.environ['PATH']}",
"STUB_LOG": str(call_log),
"FAKE_REMOTE": str(fake),
"FAIL_SSH": "1" if fail_ssh else "0",
"GETENT_MODE": fail_getent or "ok",
# The script prepends its own root to this, which is how `agent.host_agent` resolves
# when uv has no project to run in (this sandbox is not one).
"PYTHONPATH": str(tmp_path)}
if alias is not None:
env["GATEWAY_SSH"] = alias
return script, fixtures, call_log, env
def _capture(tmp_path: Path, **kwargs: object) -> subprocess.CompletedProcess[str]:
script, _fixtures, _log, env = _capture_sandbox(tmp_path, **kwargs) # type: ignore[arg-type]
return subprocess.run([BASH, str(script)], capture_output=True, text=True, env=env, check=False)
def _fixture_body(path: Path) -> str:
"""A fixture without its `#` provenance block — the bytes the host answered."""
return "".join(line for line in path.read_text().splitlines(keepends=True)
if not line.startswith("#"))
def test_the_gateway_capture_exists_and_asks_for_no_privilege() -> None:
"""Six world-readable reads plus `getent`, over an ssh key: no root, no rewrite tool.
`getent` belongs in this list because it is the seventh read and the only one that is not a
file: it is libc resolution on the box that dials, which is what `via: "libc"` claims, and it
is world-runnable for the same reason the six files are world-readable.
"""
assert CAPTURE.is_file(), "scripts/capture-gateway-config.sh is missing (phase 28 task 04)"
assert os.access(CAPTURE, os.X_OK)
text = CAPTURE.read_text()
for path in CAPTURE_TARGETS:
assert path in text, f"{path} is no longer captured"
for family in ("getent ahostsv4", "getent ahostsv6"):
assert family in text, f"{family} is no longer how the resolver document is recorded"
for tool in ("dig", "nslookup", "resolvectl", "drill"):
assert not re.search(rf"(?<![\w-]){tool}\s+[A-Za-z0-9.*_-]", text), (
f"{tool} assumes a DNS client the gateway may not ship; getent is libc, which is the "
"vantage the agent's own lookup performs")
code = "\n".join(line for line in text.splitlines() if not line.lstrip().startswith("#"))
assert "sudo" not in code, (
"the capture must read exactly what dashboards-agent can read; a pass that needed root "
"would record more than the agent can see (the smartctl note in capture-fixtures.sh)"
)
for tool in ("sed ", "awk ", " tr ", "cut "):
assert tool not in text, f"{tool.strip()} would be a text filter between the read and a fixture"
def test_the_gateway_capture_dials_the_alias_and_nothing_else(tmp_path: Path) -> None:
"""No hardcoded address: every remote command goes to `$GATEWAY_SSH`, default `gateway-ops`."""
text = CAPTURE.read_text()
assert 'GATEWAY_SSH="${GATEWAY_SSH:-gateway-ops}"' in text
# Comments may name an address (`0.0.0.0` is a shape the parser has to survive); code may not.
code = "\n".join(line for line in text.splitlines() if not line.lstrip().startswith("#"))
stray = [a for a in re.findall(r"\b(?:\d{1,3}\.){3}\d{1,3}\b", code)
if not a.startswith("203.0.113.")]
assert not stray, f"the script dials or embeds an address: {stray}"
_script, _fixtures, log, env = _capture_sandbox(tmp_path)
subprocess.run([BASH, str(_script)], capture_output=True, text=True, env=env, check=False)
assert _dialled_hosts(log) == {"gateway-ops"}
other = _capture_sandbox(tmp_path / "alias", alias="lab-gw")
subprocess.run([BASH, str(other[0])], capture_output=True, text=True, env=other[3], check=False)
assert _dialled_hosts(other[2]) == {"lab-gw"}
def _dialled_hosts(log: Path) -> set[str]:
"""The host argument of every ssh the stub was called for — options are not hosts."""
hosts = set()
for line in log.read_text().splitlines():
tokens = [token for token in line.split() if not token.startswith("-") and "=" not in token]
if tokens:
hosts.add(tokens[0])
return hosts
def test_the_gateway_capture_records_every_document_of_the_tree_it_read(tmp_path: Path) -> None:
"""The happy path, run: one fixture per remote document, include globs and all.
Two files in `conf.d` is deliberate. The script reads the include globs out of the captured
main config rather than a hardcoded pair of directories, so a gateway that adds a vhost file
gets it captured, and `files` in the payload stays the tree the config actually merges.
"""
result = _capture(tmp_path)
assert result.returncode == 0, result.stdout + result.stderr
fixtures = tmp_path / "tests" / "fixtures"
expected = {"gateway_haproxy.cfg", "gateway_nginx_main.conf",
"gateway_nginx_conf_d_http.conf", "gateway_nginx_conf_d_tls.conf",
"gateway_nginx_stream_d_stream.conf",
"gateway_proc_net_tcp.txt", "gateway_proc_net_tcp6.txt",
# The resolver document, derived from the configs in this same set.
"gateway_resolver.json"}
assert {p.name for p in fixtures.iterdir()} == expected, result.stdout
assert _fixture_body(fixtures / "gateway_haproxy.cfg") == \
CAPTURE_FAKE_GATEWAY["/etc/haproxy/haproxy.cfg"]
assert _fixture_body(fixtures / "gateway_nginx_conf_d_tls.conf") == \
CAPTURE_FAKE_GATEWAY["/etc/nginx/conf.d/tls.conf"]
# `mime.types` is included by the config and absent on the host: no fixture, no complaint —
# the same absence-the-agent-reports rule, one level up.
assert not (fixtures / "gateway_nginx_mime.types").exists()
def test_the_gateway_capture_writes_the_domains_it_read_verbatim(tmp_path: Path) -> None:
"""Nothing is scrubbed from a config, and the domains are the proof.
The `server_name` and the `proxy_pass` target beside it are the ingress map, and the
`ssl_certificate_key` is a path rather than a key — so the file the fixture holds is the file
the gateway runs, byte for byte. The one exception in this script is the socket tables'
globally routable addresses, which `capture-fixtures.sh`'s identifier rule requires.
"""
_capture(tmp_path)
vhosts = (tmp_path / "tests" / "fixtures" / "gateway_nginx_conf_d_http.conf").read_text()
assert "server_name nextcloud.reeseapps.com;" in vhosts
assert "proxy_pass http://nextcloud.reeselink.com:11000;" in vhosts
assert "ssl_certificate_key /etc/letsencrypt/live/nextcloud.reeseapps.com/privkey.pem;" in vhosts
assert "SCRUB" not in vhosts and "REDACTED" not in vhosts
assert next((line for line in vhosts.splitlines()
if line.startswith("# Verbatim /etc/nginx/conf.d/http.conf from gateway-ops")),
None), "every fixture says which remote document it is"
def test_a_dead_gateway_leaves_the_recorded_fixtures_alone(tmp_path: Path) -> None:
"""The `slots_gufo.json` rule: a capture script must never turn six good fixtures into six
empty files, because then the parser tests pass against nothing (or fail for the wrong
reason) and the ground truth is gone."""
keep = {"gateway_haproxy.cfg": "# old\nfrontend kept\n bind :::22 v4v6\n",
"gateway_proc_net_tcp.txt": " 0: 00000000:1EFF 00000000:0000 0A x\n"}
result = _capture(tmp_path, recorded=keep, fail_ssh=True)
assert result.returncode == 1, result.stdout
for name, body in keep.items():
assert (tmp_path / "tests" / "fixtures" / name).read_text() == body, \
f"{name} was overwritten by a read that failed"
for name in keep:
assert f"✗ {name}" in result.stdout, result.stdout
assert "Connection refused" in result.stdout, "one line names the reason, per fixture"
assert sorted(p.name for p in (tmp_path / "tests" / "fixtures").iterdir()) == sorted(keep), \
"a failed capture leaves no temp files behind"
def test_an_empty_read_is_refused_the_way_a_failed_one_is(tmp_path: Path) -> None:
"""`cat` exiting 0 on an empty file is still not a capture."""
keep = {"gateway_proc_net_tcp.txt": " 0: 00000000:1EFF 00000000:0000 0A keep me\n"}
result = _capture(tmp_path, gateway={"/proc/net/tcp": ""}, recorded=keep)
assert result.returncode == 1, result.stdout
assert "gateway_proc_net_tcp.txt" in result.stdout
assert "empty" in result.stdout
assert (tmp_path / "tests" / "fixtures" / "gateway_proc_net_tcp.txt").read_text() == \
next(iter(keep.values()))
def test_an_include_dir_with_no_fixture_name_is_reported_and_fails(tmp_path: Path) -> None:
"""A config that moved its vhosts is a loud failure, not a fixture set that quietly stopped
being the tree the agent merges."""
moved = {"/etc/nginx/nginx.conf": (
"http {\n include /etc/nginx/sites-enabled/*.conf;\n}\n"
"stream {\n include /etc/nginx/stream.d/*.conf;\n}\n")}
result = _capture(tmp_path, gateway=moved)
assert result.returncode == 1, result.stdout
assert "/etc/nginx/sites-enabled/*.conf" in result.stdout
assert not (tmp_path / "tests" / "fixtures" / "gateway_nginx_sites_enabled_web.conf").exists()
def test_a_config_with_no_glob_include_says_the_vhost_fixtures_were_not_refreshed(
tmp_path: Path) -> None:
keep = {"gateway_nginx_conf_d_http.conf": "# keep\nserver {\n listen 4443;\n}\n"}
result = _capture(tmp_path, gateway={"/etc/nginx/nginx.conf": "user nginx;\nevents { }\n"},
recorded=keep)
assert result.returncode == 1, result.stdout
assert "no glob include" in result.stdout
assert (tmp_path / "tests" / "fixtures" / "gateway_nginx_conf_d_http.conf").read_text() == \
next(iter(keep.values()))
def test_the_socket_capture_publishes_no_globally_routable_endpoint(tmp_path: Path) -> None:
"""The one edit the capture makes, run rather than asserted in prose.
Two rules at once, which is what makes the socket fixtures both usable and publishable: a
globally routable address (including one behind `::ffff:`) becomes documentation space, and
everything else — every port, every private/loopback/wildcard word, every other column, and
the column widths themselves — is byte-for-byte what the kernel answered. A tx/rx queue pair
is spelled exactly like an address column and must survive untouched, which is why the edit
reads two columns and not the line.
"""
_capture(tmp_path)
fixtures = tmp_path / "tests" / "fixtures"
v4 = _fixture_body(fixtures / "gateway_proc_net_tcp.txt").splitlines()
v6 = _fixture_body(fixtures / "gateway_proc_net_tcp6.txt").splitlines()
raw_v4 = CAPTURE_FAKE_GATEWAY["/proc/net/tcp"].splitlines()
raw_v6 = CAPTURE_FAKE_GATEWAY["/proc/net/tcp6"].splitlines()
assert len(v4) == len(raw_v4) and len(v6) == len(raw_v6), "a row was added or lost"
assert v4[1] == raw_v4[1], "a wildcard listener must survive untouched"
assert "08080808:911A" not in "".join(v4), "8.8.8.8 is still in the fixture"
assert "017100CB:911A" in v4[2], v4[2] # 203.0.113.1, the port kept
assert len(v4[2]) == len(raw_v4[2]), "the replacement must be exactly as wide as the original"
assert v4[3] == raw_v4[3], (
"an already-documentation address and the tx/rx queue pair on that row both moved: only "
"the two address columns may be looked at")
assert "08080808:08080808" in v4[3], v4[3]
assert "1360032601010031FF005450E0B284FE" not in "".join(v6), "a global v6 is left in"
assert "B80D0120000000000000000001000000:01BB" in v6[2], v6[2] # 2001:db8::1, port kept
assert "FFFF0000017100CB:C0AC" in v6[2] or "FFFF0000" in v6[2], \
"a v4-mapped row must stay v4-mapped, or the parser's branch for it stops being exercised"
assert v6[1] == raw_v6[1], "the wildcard v6 listener moved"
assert len(v6[2]) == len(raw_v6[2])
# --- the resolver document (phase 32 task 02) ------------------------------------------------
#: One entry per declared target of the fake gateway, in the plan's own order: haproxy's `server`
#: line first, then the nginx vhosts' `proxy_pass` targets, then the stream `map`'s entries — with
#: the map's `default` an address literal, which is why it costs no read on the remote.
CAPTURE_RESOLVER_TARGETS: tuple[tuple[str, int | None], ...] = (
("gitea.reeselink.com", 2222),
("nextcloud.reeselink.com", 11000),
("reeseapps-brain-of-reese.reeselink.com", 443),
("127.0.0.1", 4443),
)
RESOLVER_KEEP = {
"gateway_resolver.json": '{"available": true, "entries": ["keep me"]}\n',
}
def _resolver_fixture(path: Path) -> dict[str, Any]:
"""The recorded document, parsed — and a clear failure when the run refused to write it."""
assert path.is_file(), f"{path.name} was not written"
return json.loads(path.read_text())
def _resolver_run(tmp_path: Path, **kwargs: Any) -> tuple[subprocess.CompletedProcess[str], Path]:
"""One sandboxed capture run, returning its result and the fixture directory it wrote into."""
script, fixtures, _log, env = _capture_sandbox(tmp_path, **kwargs)
result = subprocess.run([BASH, str(script)], capture_output=True, text=True, env=env,
check=False)
return result, fixtures
#: The config documents of the captured tree, the same mapping `tests/conftest.py` lays down for
#: `sources/gateway.py`: an agent `--root` under which the agent can read this repo's captures.
def test_the_capture_asks_its_own_parser_and_not_its_memory() -> None:
"""The name list is `target_names()`, imported — never a second list somebody maintained.
This is the phase's rule 3 in the capture's own hands: the fixture can only ever name what the
agent will resolve, so `target_names()` changing moves the fixture with it instead of leaving a
document of names the agent stopped asking about.
"""
text = CAPTURE.read_text()
assert "from agent.host_agent import" in text, "the plan does not import the agent's parser"
assert "target_names(" in text, "the plan does not ask the agent what its configs declare"
assert "Collector(" in text, "the plan does not read the captured configs the agent reads them"
# And no domain is written into the script: the only domains in it are comments and the fake
# gateway's own fixtures live in the test, not here.
code = "\n".join(line for line in text.splitlines() if not line.lstrip().startswith("#"))
assert ".reeselink.com" not in code and ".reeseapps.com" not in code, (
"a target name is hardcoded in the capture instead of derived from the configs")
def test_the_resolver_document_names_every_target_the_configs_declare(tmp_path: Path) -> None:
"""The happy path: one libc read per declared name, in the agent's order, in its own shape.
Four assertions the fixture's whole usefulness rests on: the entry set is the plan, `via` says
how the addresses were obtained, `config_directive` came out of the **captured** nginx text (so
it matches what the agent will read from the same bytes, with no extra round trip), and the
remote was asked exactly twice per name — and never about the literal the map writes.
"""
result, fixtures = _resolver_run(tmp_path)
assert result.returncode == 0, result.stdout + result.stderr
document = _resolver_fixture(fixtures / "gateway_resolver.json")
assert document["available"] is True
assert document["via"] == "libc"
assert document["config_directive"] == "10.9.8.7", (
"the `resolver` directive did not come out of the included stream config")
assert [(row["name"], row["port"]) for row in document["entries"]] == list(
CAPTURE_RESOLVER_TARGETS), "the entries are the plan, in the agent's order"
assert document["errors"] == []
for row in document["entries"]:
assert set(row) == {"name", "port", "status", "addresses", "ts"}
assert row["ts"] == document["ts"], "a fixed capture ts keeps the fixture byte-stable"
script, _fixtures, log, _env = _capture_sandbox(tmp_path / "ledger")
subprocess.run([BASH, str(script)], capture_output=True, text=True, env=_env, check=False)
asked = [line for line in log.read_text().splitlines() if "getent " in line]
for name, _port in CAPTURE_RESOLVER_TARGETS:
if ipaddress.ip_address(name) if name[0].isdigit() else False:
assert not [line for line in asked if name in line], (
"an address literal cost a lookup on the remote")
continue
families = [line for line in asked if "getent ahostsv" in line and line.endswith(name)]
assert len(families) == 2, f"{name} was not read once per family: {families}"
def test_the_resolver_document_scrubs_global_addresses_and_keeps_everything_else(
tmp_path: Path) -> None:
"""What the document edits, and what it must not, in one run.
Three arms at once, because they are one rule: `8.8.8.8` and a global EUI-64 become
documentation space (invariant 6 — a resolved address is as much an identifier as the socket
table's), `10.1.0.137` and an address already in documentation space stay exactly as they were
(which is what makes a re-run a no-op), and the `::ffff:` spelling `getent ahostsv6` synthesises
for a name with no AAAA record is dropped — the agent's one `getaddrinfo` never publishes it, so
recording it would claim an address the agent does not. A name nobody answers is `nxdomain`, the
status the page splits out from "resolved and idle".
"""
result, fixtures = _resolver_run(tmp_path)
assert result.returncode == 0, result.stdout + result.stderr
entries = {row["name"]: row for row in
_resolver_fixture(fixtures / "gateway_resolver.json")["entries"]}
private = entries["gitea.reeselink.com"]
assert private["status"] == "ok"
assert private["addresses"] == ["10.1.0.137"], private
assert not any(a.startswith("::ffff:") for a in private["addresses"]), (
"the synthesised v4-mapped spelling survived: the agent never publishes it")
moved = entries["nextcloud.reeselink.com"]
assert moved["status"] == "ok"
assert moved["addresses"] == ["203.0.113.1", "203.0.113.9", "2001:db8::1"], moved
assert "8.8.8.8" not in json.dumps(moved), "a globally routable answer is in a tracked file"
assert "2603:6013" not in json.dumps(moved), "an EUI-64 address is in a tracked file"
missing = entries["reeseapps-brain-of-reese.reeselink.com"]
assert missing["status"] == "nxdomain", "one name failing among successes is a fact, kept"
assert missing["addresses"] == [], "an unresolved name publishes no address, not 0 and not a guess"
literal = entries["127.0.0.1"]
assert literal["status"] == "literal" and literal["addresses"] == ["127.0.0.1"]
def test_the_resolver_document_is_idempotent_so_a_re_run_does_not_churn(tmp_path: Path) -> None:
"""Two runs over the same answers write the same bytes.
The `ts` is a constant and the scrub is first-seen order over a deterministic plan, so a
re-capture of a gateway nobody changed is a no-op — the property that makes `git diff` on this
directory a statement about the ingress rather than about the clock.
"""
once, first = _resolver_run(tmp_path)
assert once.returncode == 0, once.stdout + once.stderr
again, second = _resolver_run(tmp_path / "again")
assert again.returncode == 0, again.stdout + again.stderr
assert (second / "gateway_resolver.json").read_bytes() == (
first / "gateway_resolver.json").read_bytes()
@pytest.mark.parametrize("mode, needle", [
pytest.param("transport", "did not answer", id="ssh-dies"),
pytest.param("missing", "getent is not available", id="no-getent"),
])
def test_a_broken_resolver_vantage_is_not_a_fixture(tmp_path: Path, mode: str,
needle: str) -> None:
"""The configs capture fine and only the resolver is broken — and it still refuses.
This is the arm the socket rule cannot cover: `getent` answering *nothing* for every name is a
fact about the box's resolver, not about the names, and a document of `nxdomain` rows would
make every live route on the page a permanent dash and every join test a test of nothing.
"""
result, fixtures = _resolver_run(tmp_path, recorded=dict(RESOLVER_KEEP), fail_getent=mode)
assert result.returncode == 1, result.stdout
assert needle in result.stdout, result.stdout
assert "gateway_resolver.json" in result.stdout
assert (fixtures / "gateway_resolver.json").read_text() == RESOLVER_KEEP[
"gateway_resolver.json"], "a broken vantage overwrote the recorded document"
def test_not_one_name_answering_is_refused_the_way_a_dead_transport_is(tmp_path: Path) -> None:
"""Every name answered `nxdomain`: each individual read succeeded, and the run still refuses.
A resolver that returns "no records" for the whole config is a firewall, a dead upstream DNS,
or a box that has never been pointed at one — and the fixture it would produce is the same
nothing the other two arms produce.
"""
result, fixtures = _resolver_run(tmp_path, recorded=dict(RESOLVER_KEEP), answers={})
assert result.returncode == 1, result.stdout
assert "none of the" in result.stdout and "vantage is broken" in result.stdout, result.stdout
assert (fixtures / "gateway_resolver.json").read_text() == RESOLVER_KEEP[
"gateway_resolver.json"]
def test_a_dead_gateway_does_not_attempt_the_resolver_document(tmp_path: Path) -> None:
"""With no configs there is no name list, and a document of the wrong question is worse than none."""
result = _capture(tmp_path, recorded=dict(RESOLVER_KEEP), fail_ssh=True)
fixtures = tmp_path / "tests" / "fixtures"
assert result.returncode == 1, result.stdout
assert "not attempted" in result.stdout, result.stdout
assert (fixtures / "gateway_resolver.json").read_text() == RESOLVER_KEEP[
"gateway_resolver.json"]
assert sorted(p.name for p in fixtures.iterdir()) == ["gateway_resolver.json"], (
"a refused resolver capture left a temp file in tests/fixtures/")
def test_the_socket_capture_is_idempotent_so_a_re_run_does_not_churn(tmp_path: Path) -> None:
"""Re-recording the same moment must not diff, or every capture moves the fixture twice.
Documentation space is not globally routable, so the second pass leaves it alone — the same
property that makes the drive-serial scrub re-runnable.
"""
once = tmp_path / "once"
_capture(once)
again = _capture_sandbox(tmp_path / "twice",
gateway={"/proc/net/tcp": _fixture_body(
once / "tests" / "fixtures" / "gateway_proc_net_tcp.txt")})
result = subprocess.run([BASH, str(again[0])], capture_output=True, text=True,
env=again[3], check=False)
assert result.returncode == 0, result.stdout + result.stderr
assert _fixture_body(again[1] / "gateway_proc_net_tcp.txt") == _fixture_body(
once / "tests" / "fixtures" / "gateway_proc_net_tcp.txt")
# --- the route-switch helper: --with-routectl / --without-routectl (phase 33 task 02) --------
#: The install that adds the helper and its two units, at the sandbox's default bind/port.
ROUTECTL_FLAGS = ("--bind", "10.0.0.5", "--port", "9120", "--with-routectl")
def _target(tmp_path: Path, where: str = "") -> Path:
return tmp_path / where / "target"
@pytest.mark.skipif(hasattr(os, "geteuid") and os.geteuid() == 0, reason="running as root")
def test_with_routectl_installs_helper_and_units_and_leaves_the_agent_unit_byte_identical(
tmp_path: Path
) -> None:
"""The phase's central safety claim, as a bytes comparison.
Two sandboxes, the same flags, one with the helper: the rendered `dashboards-agent.service`
must be byte-identical — the temptation to "help" the agent reach the socket by relaxing
its sandbox is exactly what this task exists to close, and the comparison is the pin. The
helper and both units land in the other sandbox, byte-identical to the deployed copies, and
the install ends with the socket's activation and the agent-uid reachability check.
"""
plain_script, _plain_log, plain_env = _sandbox_installer(tmp_path / "plain")
plain = _install(plain_script, plain_env, "--bind", "10.0.0.5", "--port", "9120")
assert plain.returncode == 0, f"plain install failed:\n{plain.stdout}\n{plain.stderr}"
rc_script, rc_log, rc_env = _sandbox_installer(tmp_path / "rc")
rc = _install(rc_script, rc_env, *ROUTECTL_FLAGS)
assert rc.returncode == 0, f"the routectl install failed:\n{rc.stdout}\n{rc.stderr}"
plain_unit = (
_target(tmp_path, "plain") / "dashboards-agent.service"
).read_text().replace(str(_target(tmp_path, "plain")), "<ROOT>")
rc_unit = (
_target(tmp_path, "rc") / "dashboards-agent.service"
).read_text().replace(str(_target(tmp_path, "rc")), "<ROOT>")
assert plain_unit == rc_unit, "the agent unit must be byte-identical with and without --with-routectl"
target = _target(tmp_path, "rc")
helper = target / "sbin" / "dashboards-routectl.py"
socket_unit = target / "dashboards-routectl.socket"
service_unit = target / "dashboards-routectl@.service"
assert helper.is_file() and socket_unit.is_file() and service_unit.is_file()
assert helper.read_text() == (DEPLOY / "dashboards-routectl.py").read_text(), (
"the installed helper is a copy, not a re-render"
)
assert socket_unit.read_text() == (DEPLOY / "dashboards-routectl.socket").read_text()
assert service_unit.read_text() == (DEPLOY / "dashboards-routectl@.service").read_text()
calls = rc_log.read_text()
assert "systemctl enable --now dashboards-routectl.socket" in calls
assert "sudo -u dashboards-agent python3" in calls, "the reachability check runs as the agent uid"
assert str(target / "run" / "dashboards-routectl.sock") in calls, (
"the check connects the sandbox's socket path, as the agent uid"
)
def _unit_lines(path: Path) -> list[str]:
return [line.rstrip() for line in path.read_text().splitlines() if line.strip()]
@pytest.mark.skipif(hasattr(os, "geteuid") and os.geteuid() == 0, reason="running as root")
def test_allow_writes_adds_only_the_flag_to_the_agent_unit(tmp_path: Path) -> None:
"""The write path's one unit change is one argument, and nothing else moves.
Task 07's guard says a re-run diff that shows `NoNewPrivileges`, `ProtectSystem`,
`PrivateDevices` or `SystemCallFilter` moving is a stop, not a `--force` — so this is
the same diff in the sandbox: with `--allow-writes`, the generated unit differs from
the plain install's exactly in the `ExecStart` line, and every security directive is
byte-identical. The flag lands on the unit's own ExecStart, because the agent (not
the installer) is the one that must refuse a write it was not started for.
"""
script, _log, env = _sandbox_installer(tmp_path)
plain = _install(script, env, "--bind", "10.0.0.5", "--port", "9120")
assert plain.returncode == 0
plain_unit = _target(tmp_path) / "dashboards-agent.service"
plain_root = str(_target(tmp_path))
script2, _log2, env2 = _sandbox_installer(tmp_path / "w")
writes = _install(script2, env2, "--bind", "10.0.0.5", "--port", "9120",
"--allow-writes", "--with-routectl")
assert writes.returncode == 0, f"--allow-writes install failed:\n{writes.stderr}"
writes_unit = _target(tmp_path, "w") / "dashboards-agent.service"
plain_lines = _unit_lines(plain_unit)
writes_lines = _unit_lines(writes_unit)
writes_root = str(_target(tmp_path, "w"))
plain_exec = [line_ for line_ in plain_lines if line_.startswith("ExecStart=")]
writes_exec = [line_ for line_ in writes_lines if line_.startswith("ExecStart=")]
assert len(plain_exec) == 1 and len(writes_exec) == 1
writes_exec[0] = writes_exec[0].replace(writes_root, "<ROOT>")
plain_exec[0] = plain_exec[0].replace(plain_root, "<ROOT>")
assert writes_exec[0] == plain_exec[0] + " --allow-writes", (
"the flag is appended to ExecStart, nothing else changes there"
)
assert len(plain_lines) == len(writes_lines), "no other line is added or removed"
for line_ in plain_lines:
if line_.startswith("ExecStart="):
continue
assert line_.replace(plain_root, "<ROOT>") in [
other.replace(writes_root, "<ROOT>") for other in writes_lines
], f"the write path moved a unit line: {line_}"
# The four directives task 07's guard names: they must be byte-identical, not moved.
# `PrivateDevices` is `false` by documented decision (the unit carries no device filter
# at all — see the template's comment), so the pin is on the value that is there.
for directive in ("NoNewPrivileges=true", "ProtectSystem=strict",
"PrivateDevices=false", "SystemCallFilter=@system-service"):
assert directive in writes_unit.read_text(), f"the write path moved {directive}"
assert directive in plain_unit.read_text(), f"the baseline unit lacks {directive}"
# And a flag without a helper is a legitimate host state: it installs, and the agent
# answers a write with 503 rather than a write — the installer has nothing to refuse.
script3, _log3, env3 = _sandbox_installer(tmp_path / "w2")
solo = _install(script3, env3, "--bind", "10.0.0.5", "--port", "9120", "--allow-writes")
assert solo.returncode == 0, f"--allow-writes without --with-routectl must install:\n{solo.stderr}"
assert " --allow-writes" in _target(tmp_path, "w2").joinpath(
"dashboards-agent.service").read_text()
# Non-install modes do not render a unit, so the flag refuses there before any write.
result = _install(script, env, "--status", "--allow-writes")
assert result.returncode == 1
assert "needs an install" in result.stderr
def _serve_on_socket(tmp_path: Path, *, allow_uid: str,
request: bytes) -> tuple[int, str]:
"""Run the real helper as a subprocess the unit does: a connected AF_UNIX socket on
fd 0/fd 1 (`Accept=yes` + `StandardInput=socket`), `--allow-uid`, one request, one
answer line. Returns `(returncode, answer line)` — the process's exit code is the
gate's verdict as much as the line is."""
child_side, parent_side = socket.socketpair(socket.AF_UNIX, socket.SOCK_STREAM)
proc = subprocess.Popen(
[sys.executable, str(DEPLOY / "dashboards-routectl.py"), "--serve",
"--allow-uid", allow_uid,
"--agent-module", str(ROOT / "agent" / "host_agent.py"),
"--state", str(tmp_path / "serve-state.json")],
stdin=child_side.fileno(), stdout=child_side.fileno(),
stderr=subprocess.PIPE, close_fds=True)
parent_side.sendall(request)
answer = parent_side.recv(65536).decode("utf-8").strip()
parent_side.close()
proc.wait(timeout=60)
child_side.close()
err = proc.stderr.read().decode() if proc.stderr is not None else ""
if proc.returncode not in (0, 1):
raise AssertionError(
f"the helper exited {proc.returncode} instead of answering:\n"
f"{answer}\n{err}")
return proc.returncode, answer
@pytest.mark.skipif(hasattr(os, "geteuid") and os.geteuid() == 0, reason="running as root")
def test_serve_answers_one_request_on_the_socket_stdin(tmp_path: Path) -> None:
"""The live box's transport, pinned: with `Accept=yes` + `StandardInput=socket`,
the accepted connection lands on fd 0, and `serve()` must find it there (fd 3 first —
the classic contract — then fd 0), name its peer, and answer one request. The
first live install (phase 33 task 07) answered a real connection with
`peer: no connected socket on this transport` because only fd 3 was looked at;
the same task found the box's kernel delivers `SO_PEERCRED` reversed
(`{pid, uid, gid}`) and `read(2)` on a socket fd that does not wake on
buffered data (`recv(2)` does) — which is why the helper calibrates the uid
slot with a same-process probe and reads the socket path with `recv`."""
me = pwd.getpwuid(os.geteuid()).pw_name
code, answer = _serve_on_socket(
tmp_path, allow_uid=me,
request=b'{"id": "haproxy:80->127.0.0.1:443", "action": "show"}\n')
body = json.loads(answer)
assert isinstance(body, dict), (
f"the answer is one JSON object on the wire (one write, no double): {answer!r}")
assert body.get("ok") is not None, f"the named peer's request was not answered: {answer}"
assert "peer:" not in str(body.get("detail", "")), (
f"the named peer's request was refused by the gate: {answer}")
assert code in (0, 1)
@pytest.mark.skipif(hasattr(os, "geteuid") and os.geteuid() == 0, reason="running as root")
def test_serve_refuses_a_wrong_peer_and_a_transport_without_one(
tmp_path: Path) -> None:
"""The second look fails closed in both directions: a named peer that is not
`--allow-uid` is a refusal, and a transport whose caller the kernel will not name
(`/dev/null` on stdin) is a refusal too — the gate never opens on an unnamed caller."""
me = pwd.getpwuid(os.geteuid()).pw_name
_code, answer = _serve_on_socket(tmp_path, allow_uid="root",
request=b'{"verb": "list"}\n')
body = json.loads(answer)
assert body["ok"] is False and "peer:" in body["detail"], (
f"a foreign uid must not pass the gate: {answer}")
# the wire's own gate (a correctly-peered caller): a wider body is a
# refusal with the wire's own sentence — and the answer is a JSON
# *object*, not the (dict, code) tuple a caller-side inversion once
# serialised as a list (phase 33 task 07 caught it on the live chain).
_code, answer = _serve_on_socket(tmp_path, allow_uid=me,
request=b'{"verb": "list"}\n')
body = json.loads(answer)
assert body["ok"] is False, f"a wider body must be refused: {answer}"
assert body["detail"] == "body: exactly {id, action, dry_run}", (
f"the refusal must carry the wire's own sentence: {answer}")
proc = subprocess.Popen(
[sys.executable, str(DEPLOY / "dashboards-routectl.py"), "--serve",
"--allow-uid", me, "--agent-module", str(ROOT / "agent" / "host_agent.py"),
"--state", str(tmp_path / "pipe-state.json")],
stdin=subprocess.DEVNULL, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
close_fds=True)
proc.wait(timeout=60)
out = proc.stdout.read().decode("utf-8").strip() if proc.stdout is not None else ""
assert proc.returncode == 1, (
f"an unnamed caller must exit refused (1), not answered: rc={proc.returncode} out={out!r}")
assert out == "", (
f"a pipe transport has no wire; the refusal is the exit code, not a line: {out!r}")
@pytest.mark.skipif(hasattr(os, "geteuid") and os.geteuid() == 0, reason="running as root")
def test_the_units_carry_the_grant_as_directives(tmp_path: Path) -> None:
"""The file-layer grant is a directive systemd enforces; the sandbox pins the lines.
`systemd-analyze verify` is not available in the sandbox, so the assertions are on the
directive lines: the socket is 0600 and agent-owned (the whole access control at the file
layer), the service is root with the socket on stdin and the one-state-directory
`StateDirectory`, and `ReadWritePaths` names every directory whose file the helper
replaces — `/etc/haproxy`, `/etc/nginx/conf.d`, `/etc/nginx/stream.d` — and nothing else
(the main `nginx.conf` is never written, so it must not be listed).
"""
script, _log, env = _sandbox_installer(tmp_path)
result = _install(script, env, *ROUTECTL_FLAGS)
assert result.returncode == 0, f"install failed:\n{result.stdout}\n{result.stderr}"
target = _target(tmp_path)
socket_unit = (target / "dashboards-routectl.socket").read_text()
# Without `Accept=yes` systemd would look for a `dashboards-routectl.service` that does
# not exist (a `Service=` line naming the template does not load on systemd 257) and
# refuse to listen — the live box's first install, phase 33 task 07.
assert _directive(socket_unit, "Accept") == ["Accept=yes"]
assert _directive(socket_unit, "ListenStream") == ["ListenStream=/run/dashboards-routectl.sock"]
assert _directive(socket_unit, "SocketMode") == ["SocketMode=0600"], (
"0600 + SocketUser is the whole access control at the file layer"
)
assert _directive(socket_unit, "SocketUser") == ["SocketUser=dashboards-agent"]
assert _directive(socket_unit, "SocketGroup") == ["SocketGroup=dashboards-agent"]
assert "WantedBy=sockets.target" in socket_unit
service = (target / "dashboards-routectl@.service").read_text()
assert _directive(service, "User") == ["User=root"]
assert "StandardInput=socket" in service and "StandardOutput=socket" in service, (
"one connection, one instance: the connected socket is stdin"
)
assert _directive(service, "StateDirectory") == ["StateDirectory=dashboards-routectl"]
assert _directive(service, "ProtectSystem") == ["ProtectSystem=read-only"]
assert _directive(service, "ReadWritePaths") == [
"ReadWritePaths=/etc/haproxy /etc/nginx/conf.d /etc/nginx/stream.d"
], "os.replace needs write on the directory: every one listed, and nothing the helper never writes"
assert _directive(service, "NoNewPrivileges") == ["NoNewPrivileges=true"], (
"the privilege comes from systemd starting it as root, not from escalation"
)
assert _directive(service, "SystemCallFilter") == ["SystemCallFilter=@system-service"]
assert _directive(service, "ProtectHome") == ["ProtectHome=read-only"]
assert _directive(service, "PrivateTmp") == ["PrivateTmp=yes"]
exec_lines = _directive(service, "ExecStart")
assert len(exec_lines) == 1 and exec_lines[0].startswith(
"ExecStart=/usr/local/sbin/dashboards-routectl.py --serve"
)
assert "--allow-uid dashboards-agent" in service, "the second look: the peer uid the helper accepts"
assert "--state /var/lib/dashboards-routectl/state.json" in service
# The on-disk modes the sandbox's real `install -m` applied.
assert stat.S_IMODE((target / "sbin" / "dashboards-routectl.py").stat().st_mode) == 0o755, (
"the helper is world-executable: the grant is the socket, not the file mode"
)
assert stat.S_IMODE((target / "dashboards-routectl.socket").stat().st_mode) == 0o644
assert stat.S_IMODE((target / "dashboards-routectl@.service").stat().st_mode) == 0o644
@pytest.mark.skipif(hasattr(os, "geteuid") and os.geteuid() == 0, reason="running as root")
def test_without_routectl_removes_the_units_and_not_the_config_or_the_state(tmp_path: Path) -> None:
"""The inverse keeps what the removal must keep.
The proxy configs and the helper's state directory are the operator's memory of what was
switched, so `--without-routectl` prints the still-off list first, removes the helper and
its two units, and leaves the state (and the configs) behind, ending with the reminder.
"""
script, call_log, env = _sandbox_installer(tmp_path)
assert _install(script, env, *ROUTECTL_FLAGS).returncode == 0
target = _target(tmp_path)
state_dir = target / "var-lib" / "dashboards-routectl"
state_dir.mkdir(parents=True)
state_dir.joinpath("state.json").write_text('{"nginx:443->127.0.0.1:44450": {}}', encoding="utf-8")
result = _install(script, env, "--without-routectl")
assert result.returncode == 0, f"--without-routectl failed:\n{result.stdout}\n{result.stderr}"
assert not (target / "dashboards-routectl.socket").exists(), "the socket unit must be removed"
assert not (target / "dashboards-routectl@.service").exists(), "the service unit must be removed"
assert not (target / "sbin" / "dashboards-routectl.py").exists(), "the helper must be removed"
assert (state_dir / "state.json").is_file(), "the state is the memory of what was switched; it stays"
calls = call_log.read_text()
assert "systemctl disable --now dashboards-routectl.socket" in calls
assert "daemon-reload" in calls
out = result.stdout
assert "routes the helper has switched off" in out, "the still-off list prints first"
assert "still off" in out, "the reminder ends the removal, not the file list"
@pytest.mark.skipif(hasattr(os, "geteuid") and os.geteuid() == 0, reason="running as root")
def test_the_with_and_without_flags_do_not_mix(tmp_path: Path) -> None:
"""One flag each direction, before any write."""
script, call_log, env = _sandbox_installer(tmp_path)
result = _install(script, env, "--with-routectl", "--without-routectl")
assert result.returncode == 1
assert result.stdout == ""
assert "one flag each direction" in result.stderr
assert not call_log.exists(), "refused before a single privileged command"
@pytest.mark.skipif(hasattr(os, "geteuid") and os.geteuid() == 0, reason="running as root")
def test_with_routectl_needs_an_install(tmp_path: Path) -> None:
"""`--status` probes a port; `--uninstall` deletes the agent. Neither installs files."""
script, _log, env = _sandbox_installer(tmp_path)
result = _install(script, env, "--status", "--with-routectl")
assert result.returncode == 1
assert "needs an install" in result.stderr
def test_no_new_sudoers_line_exists() -> None:
"""The grant is a file mode systemd enforces; the pin is the absence of a sudoers rule.
`deploy/agent-sudoers` is still exactly one line (the staged installer), neither of the
two new units names sudo, and the operator page says the sentence out loud.
"""
assert _grant_lines(SUDOERS.read_text()) == [CANONICAL_GRANT], (
"phase 33 adds a write without adding a sudoers line; a new rule is the regression"
)
for name in ("dashboards-routectl.socket", "dashboards-routectl@.service"):
text = (DEPLOY / name).read_text()
# `sudo\b` is the word sudo by itself: the units' own "not a sudoers line" comment
# (the negation that is the point) does not match, a grant would.
assert not re.search(r"sudo\b", text.lower()), f"{name} grants nothing by sudoers"
block = INSTALLER.read_text().split("routectl_off() {", 1)
assert len(block) == 2, "the --without-routectl path is a function"
assert "sudoers" not in block[1].split("\n}\n", 1)[0].lower(), (
"the removal path must not touch sudoers either"
)
readme = (DEPLOY / "gateway-routectl-README.md").read_text()
assert "No sudoers line is involved" in readme
assert "0600" in readme, "the operator page names the mode that is the grant"
@pytest.mark.skipif(hasattr(os, "geteuid") and os.geteuid() == 0, reason="running as root")
def test_the_install_checks_the_agent_can_reach_the_socket(tmp_path: Path) -> None:
"""A socket the agent cannot connect to is a feature that fails at 03:00.
So the check is part of the install: with the check's `sudo -u` step failing, the install
must exit non-zero rather than report a success nobody can use, and the check must have
run (the stub log is the proof it connected as the agent uid, not just been skipped).
"""
script, call_log, env = _sandbox_installer(tmp_path)
sudo_stub = tmp_path / "stubs" / "sudo"
sudo_stub.write_text(
'#!/bin/sh\nprintf "%s %s\\n" "sudo" "$*" >> "$STUB_LOG"\nexit 1\n', encoding="utf-8"
)
sudo_stub.chmod(0o755)
result = _install(script, env, *ROUTECTL_FLAGS)
assert result.returncode == 1, "an unreachable socket is a failed install, not a silent success"
assert "cannot connect" in result.stderr
assert "sudo -u dashboards-agent python3" in call_log.read_text(), "the check ran as the agent uid"
# --- scripts/capture-fixtures.sh: the radiance pass (phase 34, task 01) --------------
#
# The script learns radiance through the same `--with-llm` gate as the other engines and
# carries no deployment detail of its own: RADIANCE_BASE_URL is the dial, `/metrics`
# joins the per-engine loop, and `/stats` + `/v1/models` are recorded in the same pass
# (radiance is a vLLM derivative; the vLLM engine and env var stay for other deployments).
# A stub `curl` answers the three endpoints from canned bodies, so the script's own
# branches run — verbatim bodies, the script's header, the at-rest hint, the
# never-overwrite-a-good-fixture rule — with no engine in sight.
RADIANCE_CAPTURE = SCRIPTS / "capture-fixtures.sh"
#: The stub `curl`: it drops the options the script passes (`-fsS`, `--max-time N`, `-o`),
#: records every call, and answers the engine's three read-only endpoints from `$CANNED_*`.
#: Nothing here can reach a network.
RADIANCE_CURL_STUB = """#!/bin/sh
printf '%s\\n' "$*" >> "$STUB_LOG"
if [ "${FAIL_CURL:-0}" = "1" ]; then
echo "curl: (7) Failed to connect" >&2
exit 7
fi
out=""
url=""
while [ $# -gt 0 ]; do
case "$1" in
--max-time) shift 2 ;;
-o) out="$2"; shift 2 ;;
-*) shift ;;
*) url="$1"; shift ;;
esac
done
[ -n "$out" ] || { echo "stub curl: no -o target" >&2; exit 2; }
case "$url" in
*/metrics) printf '%s' "$CANNED_METRICS" > "$out" ;;
*/stats) printf '%s' "$CANNED_STATS" > "$out" ;;
*/v1/models) printf '%s' "$CANNED_MODELS" > "$out" ;;
*) echo "stub curl: unexpected URL $url" >&2; exit 2 ;;
esac
"""
#: The seven per-position spec-acceptance lines: the phase pins position="0".."6".
RADIANCE_CANNED_METRICS = (
"# HELP vllm:num_requests_running Number of requests currently running on GPU.\n"
"# TYPE vllm:num_requests_running gauge\n"
'vllm:num_requests_running{model_name="juggernaut",engine="0"} 0\n'
'radiance:decode_tokens_per_second{model_name="juggernaut",engine="0"} 110.9\n'
+ "".join(
f'radiance:draft_position_acceptance_ratio{{model_name="juggernaut",engine="0",'
f'position="{i}"}} 0.7\n'
for i in range(7)
)
)
RADIANCE_CANNED_STATS = (
'{"model":"juggernaut","version":"1.15.1","uptime_s":67490,"queue_cap":24,'
'"in_flight":0,"kv_util":0.7241322994232178,"prefix_hit_rate":0.9572382569313049,'
'"draft_positions":[{"reached":701741,"accepted":516252,"rate":0.7356731329650114}],'
'"requests":[],"cards":[{"index":0,"name":"AMD Radeon AI PRO R9700",'
'"vram_used":32119517184,"vram_total":34208743424}]}'
)
RADIANCE_CANNED_STATS_BUSY = (
'{"model":"juggernaut","version":"1.15.1","uptime_s":67500,"queue_cap":24,'
'"in_flight":1,"kv_util":0.72,"prefix_hit_rate":0.95,'
'"draft_positions":[{"reached":701741,"accepted":516252,"rate":0.735}],'
'"requests":[{"id":"req-1","queue_pos":1}],'
'"cards":[{"index":0,"name":"AMD Radeon AI PRO R9700",'
'"vram_used":32119517184,"vram_total":34208743424}]}'
)
RADIANCE_CANNED_MODELS = (
'{"object":"list","data":[{"id":"juggernaut","object":"model","created":1793484879,'
'"owned_by":"radiance","max_model_len":131072,"capabilities":{"chat":true}}]}'
)
RADIANCE_BASE = "http://radiance.test:8000"
def _radiance_capture_sandbox(
tmp_path: Path,
*,
recorded: dict[str, str] | None = None,
fail_curl: bool = False,
busy: bool = False,
no_engine: bool = False,
) -> tuple[Path, Path, Path, dict[str, str]]:
"""A copy of the script, a canned radiance, and a PATH whose `curl` reaches only the canned.
Returns (script, fixtures dir, stub call log, env). The script is copied into
`<tmp>/scripts/` because it derives `tests/fixtures/` from its own location, which is
what keeps the repository's fixtures out of reach of a test.
"""
script = tmp_path / "scripts" / RADIANCE_CAPTURE.name
script.parent.mkdir(parents=True, exist_ok=True)
shutil.copyfile(RADIANCE_CAPTURE, script)
fixtures = tmp_path / "tests" / "fixtures"
fixtures.mkdir(parents=True, exist_ok=True)
for name, body in (recorded or {}).items():
(fixtures / name).write_text(body, encoding="utf-8")
stubs = tmp_path / "stubs"
stubs.mkdir()
stub = stubs / "curl"
stub.write_text(RADIANCE_CURL_STUB, encoding="utf-8")
stub.chmod(0o755)
log = tmp_path / "curl.log"
env = {
"PATH": f"{stubs}{os.pathsep}{os.environ['PATH']}",
"STUB_LOG": str(log),
"CANNED_METRICS": RADIANCE_CANNED_METRICS,
"CANNED_STATS": RADIANCE_CANNED_STATS_BUSY if busy else RADIANCE_CANNED_STATS,
"CANNED_MODELS": RADIANCE_CANNED_MODELS,
}
if not no_engine:
env["RADIANCE_BASE_URL"] = RADIANCE_BASE
if fail_curl:
env["FAIL_CURL"] = "1"
return script, fixtures, log, env
def _radiance_run(tmp_path: Path, **kwargs: object) -> subprocess.CompletedProcess[str]:
script, _fixtures, _log, env = _radiance_capture_sandbox(tmp_path, **kwargs) # type: ignore[arg-type]
return subprocess.run([BASH, str(script), "--with-llm"], capture_output=True, text=True,
env=env, check=False)
def _dialled_urls(log: Path) -> list[str]:
urls: list[str] = []
for line in log.read_text().splitlines():
for token in line.split():
if token.startswith("http"):
urls.append(token)
return urls
def _assert_verbatim(path: Path, canned: str) -> None:
"""The engine's reply inside a fixture, claimed verbatim.
The script's header is comment text; the engine's reply is the file's complete tail —
so the reply is verbatim iff the file ends with it byte for byte and everything before
it is comment lines (the metrics body's own `# HELP` / `# TYPE` lines are part of the
reply and stay in the fixture).
"""
text = path.read_text()
assert text.endswith(canned), f"{path.name} lost the tail of the engine's reply"
prefix = text[: -len(canned)]
non_comment = [line for line in prefix.splitlines() if line and not line.startswith("#")]
assert not non_comment, f"{path.name} has non-comment text before the reply: {non_comment}"
assert prefix, f"{path.name} lost its verbatim header"
def test_the_radiance_capture_records_all_three_endpoints_verbatim(tmp_path: Path) -> None:
"""The happy path, run: three fixtures, each with the script's verbatim header, the body
byte-for-byte what the engine answered, and a dial to exactly the three read-only
endpoints — nothing else, in the documented order."""
result = _radiance_run(tmp_path)
assert result.returncode == 0, result.stdout + result.stderr
fixtures = tmp_path / "tests" / "fixtures"
assert {p.name for p in fixtures.iterdir()} == {
"metrics_radiance.txt", "stats_radiance.json", "models_radiance.json"}
for name in ("metrics_radiance.txt", "stats_radiance.json", "models_radiance.json"):
text = (fixtures / name).read_text()
assert text.startswith("# Verbatim"), f"{name} lost its verbatim header"
assert "./scripts/capture-fixtures.sh" in text, f"{name} names its recorder"
_assert_verbatim(fixtures / "metrics_radiance.txt", RADIANCE_CANNED_METRICS)
_assert_verbatim(fixtures / "stats_radiance.json", RADIANCE_CANNED_STATS)
_assert_verbatim(fixtures / "models_radiance.json", RADIANCE_CANNED_MODELS)
assert _dialled_urls(fixtures.parent.parent / "curl.log") == [
f"{RADIANCE_BASE}/metrics", f"{RADIANCE_BASE}/stats", f"{RADIANCE_BASE}/v1/models"]
# the capture at rest records `requests: []` — the script says so, so the operator
# re-runs with a request in flight to record its row shape
assert "requests[] was empty — re-run with a request in flight to record its shape" in result.stdout
def test_the_radiance_capture_says_nothing_to_re_run_when_a_request_is_in_flight(tmp_path: Path) -> None:
"""With a request in flight the hint is gone (it would send the operator to re-run a
capture that already has the row shape), and the header still records what it saw."""
result = _radiance_run(tmp_path, busy=True)
assert result.returncode == 0, result.stdout + result.stderr
assert "re-run with a request in flight" not in result.stdout
stats = (tmp_path / "tests" / "fixtures" / "stats_radiance.json").read_text()
assert 'requests":[{"id":"req-1","queue_pos":1}]' in stats
assert "in_flight was 1 at capture" in stats
def test_the_radiance_capture_without_an_engine_says_which_env_var_it_wants(tmp_path: Path) -> None:
"""No engine env var is not a silent no-op: the gate names the var, like the others."""
script, _fixtures, _log, env = _radiance_capture_sandbox(tmp_path, no_engine=True)
result = subprocess.run([BASH, str(script), "--with-llm"], capture_output=True, text=True,
env=env, check=False)
assert result.returncode == 1
assert "no GUFO_BASE_URL / VLLM_BASE_URL / RADIANCE_BASE_URL set" in result.stdout
def test_a_dead_radiance_engine_never_replaces_a_recorded_capture(tmp_path: Path) -> None:
"""The `slots_gufo.json` rule: a capture script must never turn three good fixtures into
three empty files, because then the shape tests pass against nothing (or fail for the
wrong reason) and the ground truth is gone."""
good = {"metrics_radiance.txt": "# old\nradiance:kept 1\n",
"stats_radiance.json": "# old\n{\"cards\":[]}\n",
"models_radiance.json": "# old\n{\"object\":\"list\"}\n"}
script, fixtures, _log, env = _radiance_capture_sandbox(tmp_path, recorded=good, fail_curl=True)
result = subprocess.run([BASH, str(script), "--with-llm"], capture_output=True, text=True,
env=env, check=False)
assert result.returncode == 1
for name, body in good.items():
assert (fixtures / name).read_text() == body, f"{name} was replaced by a dead engine"