#!/usr/bin/env bash
# tests/d139-step6-vip-rehome/run-tests.sh
#
# Offline harness for netbox/d139-step6-vip-rehome.py (D-139 execution step 6).
# Exercises plan() against fixtures shaped like the live NetBox API. No network.
#
# The tool's write path is CREATE -> verify -> DEPRECATE and never deletes; plan() is
# what decides all three sets, so it is where the risk lives.
#
# PROOF-OF-TEETH is a first-class case here (T13): this repo has twice shipped
# assertions that could not fail. Each REFUSE case is also proven to be reached for the
# stated reason, not incidentally.
set -uo pipefail
REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
TOOL="$REPO/netbox/d139-step6-vip-rehome.py"
PASS=0; FAIL=0
ok() { echo " PASS $1"; PASS=$((PASS+1)); }
bad() { echo " FAIL $1"; FAIL=$((FAIL+1)); }
echo "== d139-step6-vip-rehome: plan() against API-shaped fixtures =="
[ -r "$TOOL" ] || { echo " FAIL tool missing at $TOOL"; echo "RESULT: PASS=0 FAIL=1"; exit 1; }
run_case() { # run_case <label> <python-snippet-file>
python3 "$1" 2>&1
}
TMP="$(mktemp -d)"; trap 'rm -rf "$TMP"' EXIT
cat > "$TMP/harness.py" <<'PY'
import importlib.util, ipaddress, os, sys, io, contextlib
TOOL = os.environ["TOOL"]
spec = importlib.util.spec_from_file_location("step6", TOOL)
m = importlib.util.module_from_spec(spec); spec.loader.exec_module(m)
def pfx(cidr, role, dc="vr1-dc0", status="active", pid=None):
return {"id": pid if pid is not None else abs(hash(cidr)) % 100000,
"prefix": cidr, "status": {"value": status},
"role": ({"slug": role} if role else None),
"scope": {"slug": dc}}
def adr(addr, desc, status="reserved", aid=None):
return {"id": aid if aid is not None else abs(hash(addr)) % 100000,
"address": addr, "status": {"value": status}, "description": desc}
# dc0's five retiring ULA /64s + four /60 parents = the 9 the live apex reports.
def ula_prefixes():
return [pfx("fd50:840e:74e2:220::/60", "metal-admin"),
pfx("fd50:840e:74e2:220::/64", "metal-admin"),
pfx("fd50:840e:74e2:221::/64", "metal-internal"),
pfx("fd50:840e:74e2:230::/60", "data-tenant"),
pfx("fd50:840e:74e2:230::/64", "data-tenant"),
pfx("fd50:840e:74e2:240::/60", "storage"),
pfx("fd50:840e:74e2:240::/64", "storage"),
pfx("fd50:840e:74e2:250::/60", "replication"),
pfx("fd50:840e:74e2:250::/64", "replication")]
# MEASURED against the live apex 2026-08-02, and the harness caught this the hard way:
# the VIP host parts MIRROR THE v4 DECIMAL BAND (D-134 .50-.99 VIP band), so they read
# ::50..::59 then ::60..::62 -- THIRTEEN per plane. They are NOT a contiguous hex run:
# 0x5a-0x5f are skipped. A fixture generating range(0x50, 0x63) yields 19 per plane and
# silently inflates every count, which is how the first run of this harness reported
# CREATE=38 against a real CREATE=26. A mock must be truthful to the real data or the
# assertions grade the mock.
VIP_OCTETS = list(range(0x50, 0x5a)) + list(range(0x60, 0x63)) # 13
# The GUA /64s that ACTUALLY EXIST in the live apex for dc0 (step 1 created 16 rows).
# The DEF-1 guard refuses any target not in this set, so omitting them from the fixture
# made every plan() case refuse -- correct behaviour, wrong fixture. Only the /64s the
# ULA roles map to are needed here.
def gua_prefixes():
return [pfx("2602:f3e2:f02:20::/64", "metal-admin"),
pfx("2602:f3e2:f02:21::/64", "metal-internal"),
pfx("2602:f3e2:f02:30::/64", "data-tenant"),
pfx("2602:f3e2:f02:40::/64", "storage"),
pfx("2602:f3e2:f02:50::/64", "replication")]
def all_prefixes():
return ula_prefixes() + gua_prefixes()
def vip_addrs():
out = []
for hx, plane in ((0x220, "metal-admin"), (0x221, "metal-internal")):
for i in VIP_OCTETS:
out.append(adr("fd50:840e:74e2:%x::%x/64" % (hx, i),
"VIP svc%x %s v6 (vr1-dc0) -- octet mirror ::%x" % (i, plane, i)))
return out
def refuses(fn):
"""Returns (did_refuse, stderr_text). die() calls sys.exit(2)."""
err = io.StringIO()
try:
with contextlib.redirect_stderr(err):
fn()
except SystemExit as e:
return (e.code == 2), err.getvalue()
return False, err.getvalue()
PY
emit() { cat > "$TMP/t.py"; TOOL="$TOOL" PYTHONPATH="$TMP" python3 "$TMP/t.py" 2>&1; }
# ---- T1-T4 happy path ------------------------------------------------------------
out="$(emit <<'PY'
import sys; sys.path.insert(0, __import__("os").environ.get("PYTHONPATH","."))
from harness import *
c, da, dp, al = m.plan("vr1-dc0", all_prefixes(), vip_addrs())
print("CREATE=%d DEPA=%d DEPP=%d ALREADY=%d" % (len(c), len(da), len(dp), len(al)))
tgt = sorted(x["address"] for x in c)
print("FIRST=%s LAST=%s" % (tgt[0], tgt[-1]))
print("STATUS_SET=%s" % sorted({x["status"] for x in c}))
print("DESC0=%s" % c[0]["description"])
PY
)"
grep -q "CREATE=26 DEPA=26 DEPP=9 ALREADY=0" <<<"$out" \
&& ok "T1 26 creates, 26 addr-deprecations, 9 prefix-deprecations" \
|| bad "T1 wrong plan counts: $out"
grep -q "FIRST=2602:f3e2:f02:20::50/64" <<<"$out" \
&& ok "T2 metal-admin ULA :220 maps to GUA :20, host octet preserved" \
|| bad "T2 wrong low target: $out"
grep -q "LAST=2602:f3e2:f02:21::62/64" <<<"$out" \
&& ok "T3 metal-internal ULA :221 maps to GUA :21, host octet preserved" \
|| bad "T3 wrong high target: $out"
grep -q "STATUS_SET=\['reserved'\]" <<<"$out" \
&& ok "T4 creates are status=reserved (MEASURED from the ULA originals, not 'active')" \
|| bad "T4 wrong create status: $out"
# ---- T5 description carried verbatim ---------------------------------------------
grep -q "DESC0=VIP svc50 metal-admin v6" <<<"$out" \
&& ok "T5 description carried VERBATIM onto the GUA record" \
|| bad "T5 description not preserved: $out"
# ---- T6 idempotence --------------------------------------------------------------
out="$(emit <<'PY'
import sys; sys.path.insert(0, __import__("os").environ.get("PYTHONPATH","."))
from harness import *
a = vip_addrs() + [adr("2602:f3e2:f02:20::50/64", "already there")]
c, da, dp, al = m.plan("vr1-dc0", all_prefixes(), a)
print("CREATE=%d ALREADY=%d" % (len(c), len(al)))
PY
)"
grep -q "CREATE=25 ALREADY=1" <<<"$out" \
&& ok "T6 an existing GUA address is ALREADY, not a duplicate create" \
|| bad "T6 not idempotent: $out"
# ---- T7 already-deprecated rows drop out of the deprecate sets --------------------
out="$(emit <<'PY'
import sys; sys.path.insert(0, __import__("os").environ.get("PYTHONPATH","."))
from harness import *
p = all_prefixes(); p[0]["status"] = {"value": "deprecated"}
a = vip_addrs(); a[0]["status"] = {"value": "deprecated"}
c, da, dp, al = m.plan("vr1-dc0", p, a)
print("DEPA=%d DEPP=%d" % (len(da), len(dp)))
PY
)"
grep -q "DEPA=25 DEPP=8" <<<"$out" \
&& ok "T7 rows already deprecated are not re-patched (idempotent deprecate)" \
|| bad "T7 re-patches deprecated rows: $out"
# ---- T8 REFUSE: no ULA prefixes in scope is NOT silent success --------------------
out="$(emit <<'PY'
import sys; sys.path.insert(0, __import__("os").environ.get("PYTHONPATH","."))
from harness import *
did, err = refuses(lambda: m.plan("vr1-dc0", gua_prefixes(), vip_addrs()))
print("REFUSED=%s" % did); print("ERR=%s" % err.strip())
PY
)"
grep -q "REFUSED=True" <<<"$out" && grep -qi "no ULA prefixes in scope" <<<"$out" \
&& ok "T8 REFUSE when no ULA prefixes in scope (empty != done)" \
|| bad "T8 did not refuse for the stated reason: $out"
# ---- T9 REFUSE: a role with no GUA plane -----------------------------------------
out="$(emit <<'PY'
import sys; sys.path.insert(0, __import__("os").environ.get("PYTHONPATH","."))
from harness import *
p = [pfx("fd50:840e:74e2:220::/64", "no-such-role")]
did, err = refuses(lambda: m.plan("vr1-dc0", p + gua_prefixes(), vip_addrs()))
print("REFUSED=%s" % did); print("ERR=%s" % err.strip())
PY
)"
grep -q "REFUSED=True" <<<"$out" && grep -qi "no D-139 GUA plane carries apex role" <<<"$out" \
&& ok "T9 REFUSE on a role with no GUA counterpart" \
|| bad "T9 did not refuse for the stated reason: $out"
# ---- T10 REFUSE: ambiguous role (provider-public owns :10 AND :11) ----------------
out="$(emit <<'PY'
import sys; sys.path.insert(0, __import__("os").environ.get("PYTHONPATH","."))
from harness import *
did, err = refuses(lambda: m.gua_net_for_role("vr1-dc0", "provider-public"))
print("REFUSED=%s" % did); print("ERR=%s" % err.strip())
PY
)"
grep -q "REFUSED=True" <<<"$out" && grep -qi "ambiguous, refusing to choose" <<<"$out" \
&& ok "T10 REFUSE on an ambiguous role rather than picking a /64" \
|| bad "T10 did not refuse on ambiguity: $out"
# ---- T11 REFUSE: ULA prefix carrying no role -------------------------------------
out="$(emit <<'PY'
import sys; sys.path.insert(0, __import__("os").environ.get("PYTHONPATH","."))
from harness import *
p = [pfx("fd50:840e:74e2:220::/64", None)]
did, err = refuses(lambda: m.plan("vr1-dc0", p + gua_prefixes(), vip_addrs()))
print("REFUSED=%s" % did); print("ERR=%s" % err.strip())
PY
)"
grep -q "REFUSED=True" <<<"$out" && grep -qi "has no apex role" <<<"$out" \
&& ok "T11 REFUSE on a roleless ULA prefix (cannot map it)" \
|| bad "T11 did not refuse: $out"
# ---- T12 other DCs' rows are ignored ----------------------------------------------
out="$(emit <<'PY'
import sys; sys.path.insert(0, __import__("os").environ.get("PYTHONPATH","."))
from harness import *
p = all_prefixes() + [pfx("fd50:840e:74e2:320::/64", "metal-admin", dc="vr1-dc1")]
c, da, dp, al = m.plan("vr1-dc0", p, vip_addrs())
print("DEPP=%d" % len(dp))
PY
)"
grep -q "DEPP=9" <<<"$out" \
&& ok "T12 another DC's ULA prefix is out of scope and untouched" \
|| bad "T12 leaked across DC scope: $out"
# ---- T13 PROOF OF TEETH ------------------------------------------------------------
# Confirm the ULA->GUA mapping assertions (T2/T3) CAN fail. Uses live_gua=None to bypass
# the DEF-1 existence guard DELIBERATELY: with the guard active a wrong /48 REFUSES
# before producing a target, so the test would assert on a refusal rather than on the
# mapping it is meant to constrain.
# HARDENED after the 2026-08-02 adversarial review: the original asserted only that the
# right string was ABSENT, so a TRACEBACK satisfied it -- it passed against a tool file
# that did not even parse. It now requires a POSITIVE, well-formed, DIFFERENT target.
out="$(emit <<'PYX'
import sys; sys.path.insert(0, __import__("os").environ.get("PYTHONPATH","."))
from harness import *
good = m.gua_net_for_role("vr1-dc0", "metal-admin")
orig = m.C.DC_GUA["vr1-dc0"]
m.C.DC_GUA["vr1-dc0"] = "2602:f3e2:f0f::/48"
mutant = m.gua_net_for_role("vr1-dc0", "metal-admin")
m.C.DC_GUA["vr1-dc0"] = orig
print("GOOD=%s" % good)
print("MUTANT=%s" % mutant)
print("DIFFER=%s" % (str(good) != str(mutant)))
PYX
)"
if grep -q "GOOD=2602:f3e2:f02:20::/64" <<<"$out" \
&& grep -q "MUTANT=2602:f3e2:f0f:20::/64" <<<"$out" \
&& grep -q "DIFFER=True" <<<"$out"; then
ok "T13 PROOF-OF-TEETH: a wrong /48 yields a well-formed but DIFFERENT /64 (T2/T3 can fail)"
else
bad "T13 PROOF-OF-TEETH did not produce the expected mutant mapping: $out"
fi
# ---- T14 NO DELETE PATH, across the tool AND the module it imports -------------------
# The ruling is "Deprecate both, delete nothing". Assert on the ARTIFACT.
# HARDENED after review: the original grepped ONE file, so adding a delete to the
# IMPORTED d139-gua-carve.py left it green. The import inherits that module's whole
# surface, so the assertion must cover it too.
CARVE_TOOL="$REPO/netbox/d139-gua-carve.py"
if grep -nE '"DELETE"|\.delete\(|method="DELETE"' "$TOOL" "$CARVE_TOOL" >/dev/null 2>&1; then
bad "T14 a DELETE path exists in the tool or its imported module -- the ruling forbids it"
else
ok "T14 NO delete path in the tool OR in the module it imports"
fi
# ---- T15 the tool actually PARSES (T13's escape hatch, closed) ----------------------
if python3 -c "import ast,sys; ast.parse(open(sys.argv[1]).read())" "$TOOL" 2>/dev/null; then
ok "T15 tool parses -- so a passing suite cannot mean 'the file is broken'"
else
bad "T15 tool does not parse"
fi
# ---- T16-T18 main(): PHASE ORDER, which had ZERO coverage before the review ---------
# The reviewer moved the deprecate loops ABOVE the create phase and the suite stayed
# green. Both rulings call this order load-bearing, so it is now asserted directly by
# recording the ORDER of calls a fake client receives.
out="$(emit <<'PY'
import sys; sys.path.insert(0, __import__("os").environ.get("PYTHONPATH","."))
from harness import *
import ipaddress
CALLS = []
class FakeNB:
def __init__(self, *a, **k): pass
def get_all(self, path):
if "prefixes" in path:
p = list(all_prefixes())
if CALLS.count("PATCH_P"): # model the deprecation landing
for x in p:
if x["prefix"].startswith("fd50:"):
x["status"] = {"value": "deprecated"}
return p
a = list(vip_addrs())
if CALLS.count("PATCH_A"): # model the deprecation landing
for x in a:
x["status"] = {"value": "deprecated"}
if CALLS.count("POST"): # after creates, read-back must find them
for hx, g in ((0x220, 0x20), (0x221, 0x21)):
for i in VIP_OCTETS:
a.append(adr("2602:f3e2:f02:%x::%x/64" % (g, i), "created"))
return a
def post(self, path, body): CALLS.append("POST"); return {}
def patch(self, path, body):
CALLS.append("PATCH_A" if "ip-addresses" in path else "PATCH_P"); return {}
m.NBW = FakeNB
sys.argv = ["x", "--dc", "vr1-dc0", "--commit"]
import os as _os
_os.environ["NETBOX_URL"] = "http://10.10.1.10:8000"
_os.environ["NETBOX_TOKEN"] = "fake"
rc = m.main()
print("RC=%s" % rc)
print("NPOST=%d NPATCH=%d" % (CALLS.count("POST"), CALLS.count("PATCH_A")+CALLS.count("PATCH_P")))
print("FIRST_PATCH_AFTER_LAST_POST=%s" %
(CALLS.index("PATCH_A") > max(i for i,c in enumerate(CALLS) if c == "POST")))
PY
)"
grep -q "RC=0" <<<"$out" \
&& ok "T16 main() --commit completes rc=0 against a fake client" \
|| bad "T16 main() did not complete: $out"
grep -q "NPOST=26 NPATCH=35" <<<"$out" \
&& ok "T17 main() issues 26 POSTs and 35 PATCHes (26 addr + 9 prefix)" \
|| bad "T17 wrong call counts: $out"
grep -q "FIRST_PATCH_AFTER_LAST_POST=True" <<<"$out" \
&& ok "T18 ORDER: every CREATE precedes the first DEPRECATE (both rulings' load-bearing property)" \
|| bad "T18 ORDER VIOLATED -- a deprecate ran before the creates finished: $out"
# ---- T19 DEF-1: refuse when the target GUA prefix does not exist --------------------
out="$(emit <<'PY'
import sys; sys.path.insert(0, __import__("os").environ.get("PYTHONPATH","."))
from harness import *
did, err = refuses(lambda: m.gua_net_for_role("vr1-dc0", "metal-admin", live_gua=set()))
print("REFUSED=%s" % did); print("ERR=%s" % err.strip())
PY
)"
grep -q "REFUSED=True" <<<"$out" && grep -qi "DOES NOT EXIST in the apex" <<<"$out" \
&& ok "T19 DEF-1 REFUSE when the target GUA /64 is absent (the dc1 orphan-create)" \
|| bad "T19 did not refuse on a missing target prefix: $out"
# ---- T20 DEF-3: refuse on an address no in-scope /64 covers ------------------------
out="$(emit <<'PY'
import sys; sys.path.insert(0, __import__("os").environ.get("PYTHONPATH","."))
from harness import *
p = [x for x in all_prefixes() if x["prefix"] != "fd50:840e:74e2:221::/64"]
did, err = refuses(lambda: m.plan("vr1-dc0", p, vip_addrs()))
print("REFUSED=%s" % did); print("ERR=%s" % err.strip())
PY
)"
grep -q "REFUSED=True" <<<"$out" && grep -qi "claimed by NO prefix row" <<<"$out" \
&& ok "T20 DEF-3 REFUSE on the silent under-count (13 VIPs skipped at rc=0)" \
|| bad "T20 under-counted silently instead of refusing: $out"
echo
echo "RESULT: PASS=$PASS FAIL=$FAIL"
[ "$FAIL" -eq 0 ] && echo "ALL PASS" || echo "FAILURES PRESENT"
[ "$FAIL" -eq 0 ]