phase: 32_gateway_resolved_target_liveness

Fixture and live stream.conf are byte-identical (modulo header comment). Let me test the parser directly:
This commit is contained in:
2026-10-26 14:03:42 -04:00
parent 25fd74b7c5
commit 51772ffef2
58 changed files with 5272 additions and 478 deletions
+19 -3
View File
@@ -257,7 +257,7 @@ GATEWAY_TREE = {
"proc/net/tcp6": "gateway_proc_net_tcp6.txt",
}
GATEWAY_MODES = ("full", "predates", "no_haproxy", "no_nginx", "sockets_silent")
GATEWAY_MODES = ("full", "resolved", "predates", "no_haproxy", "no_nginx", "sockets_silent")
@pytest.fixture
@@ -269,9 +269,19 @@ def gateway_snapshot(host_agent_module: Any, tmp_path: Path) -> Any:
`sources/gateway.py` are the bytes agent 1.2.0 serves. A field rename on either side of the
wire therefore fails a source test instead of drawing an empty pipe on the page (rule 7).
Modes are the degradation arms the page has to render:
One more axis is a **version**, not a degradation:
* `full` — all three sections `available: true`, live sockets from the capture
* `resolved` — the same tree as `full` plus agent 1.3.0's fourth section, the recorded
`gateway_resolver.json` attached verbatim (the document `capture-gateway-config.sh` reads
back with `getent ahostsv4/6` on the box that dials). This is what the deployed ingress
serves after phase 32 task 05, and it is the arm in which a name-written route becomes
countable.
Modes are otherwise the degradation arms the page has to render:
* `full` — all three sections `available: true`, live sockets from the capture, and **no**
`resolver` key at all: a 1.2.0 agent, or a 1.3.0 one run with `--no-resolve`. Phase 30's
payload, verbatim, which is what the phase-32 additivity pins compare against
* `predates` — none of the three keys at all (an agent older than 1.2.0, or `--no-proxy`)
* `no_haproxy` / `no_nginx` — that one config file is absent: `available: false` plus the
agent's own **not found** line, the other half of the page untouched
@@ -308,6 +318,12 @@ def gateway_snapshot(host_agent_module: Any, tmp_path: Path) -> Any:
snapshot["haproxy"] = collector.haproxy(errors)
snapshot["nginx"] = collector.nginx(errors)
snapshot["sockets"] = collector.sockets(errors)
if mode == "resolved":
# The recorded capture, not a re-derivation: the names are the ones `target_names()`
# derives from the config fixtures above and the answers are libc's on the router, so
# the join is tested against the document the agent will actually serve (rule 7). The
# dashboard never asks a resolver, and nothing here does either.
snapshot["resolver"] = json.loads((FIXTURES / "gateway_resolver.json").read_text())
return snapshot
return build