#!/usr/bin/env bash
# tests/d120-compose-bands/run-tests.sh
#
# Harness for netbox/d120-compose-bands.py. OFFLINE -- touches no NetBox.
#
# Pins the D-120 band VALUES (a changed endpoint silently re-bands the /24), and the
# guard behaviour every sandbox-loop writer must have: dry by default, upstream-write
# gated IN CODE, and a whole-plan preflight so a bad plan cannot half-write.
set -uo pipefail
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
S="$(cd "$HERE/../../netbox" && pwd)/d120-compose-bands.py"
pass=0; fail=0
ok() { pass=$((pass+1)); }
bad() { fail=$((fail+1)); echo " FAIL: $1"; }
command -v python3 >/dev/null 2>&1 || { echo "FAIL: python3 required"; exit 1; }
python3 -c "import ast;ast.parse(open('$S').read())" 2>/dev/null && ok || bad "does not parse"
python3 "$S" --help >/dev/null 2>&1 && ok || bad "--help -> 0"
# no env -> must fail loud, not guess a target
NETBOX_URL= NETBOX_TOKEN= python3 "$S" >/dev/null 2>&1; [ $? -ne 0 ] && ok || bad "missing NETBOX_URL/TOKEN must fail"
# DRY BY DEFAULT
grep -q '"--commit", action="store_true"' "$S" && ok || bad "no --commit flag -- must be dry by default"
grep -q 'DRY RUN -- nothing will be written' "$S" && ok || bad "does not announce its dry run"
# UPSTREAM WRITE GATED IN CODE (not by discipline)
grep -q 'yes-write-upstream' "$S" && ok || bad "lost the --yes-write-upstream gate"
out="$(NETBOX_URL=https://netbox.baldurkeep.com NETBOX_TOKEN=x python3 "$S" --commit 2>&1)"
printf '%s' "$out" | grep -q "REFUSING to --commit" && ok \
|| bad "did NOT refuse a --commit to a non-sandbox host (it would have written to production)"
# WHOLE-PLAN PREFLIGHT -- must validate the plan BEFORE any create (no half-writes)
grep -q "outside the parent" "$S" && ok || bad "lost the in-parent preflight"
grep -q "parent prefix .* absent" "$S" && ok || bad "lost the parent-exists preflight"
# THE D-120 VALUES -- the 3 child ranges D-120 names for NetBox (static/dynamic/node)
for pair in \
'"10.10.1.2/24", "10.10.1.49/24"' \
'"10.10.1.100/24", "10.10.1.200/24"' \
'"10.10.1.201/24", "10.10.1.254/24"'; do
grep -qF "$pair" "$S" && ok || bad "D-120 range [$pair] is GONE / changed"
done
# The two re-IP'd service addresses (D-120: .201->.10, .202->.11) and their dns_names
grep -qF '"10.10.1.10/24"' "$S" && grep -q 'office1-netbox' "$S" && ok || bad "office1-netbox 10.10.1.10 assignment is gone"
grep -qF '"10.10.1.11/24"' "$S" && grep -q 'office1-tailscale' "$S" && ok || bad "office1-tailscale 10.10.1.11 assignment is gone"
# The parent compose net must be the D-115 /24, not something invented
grep -qF 'PARENT = "10.10.1.0/24"' "$S" && ok || bad "parent compose net is not 10.10.1.0/24"
# The node band must NOT still say .201/.202 for the services (the pre-re-IP snapshot)
grep -qE '"10\.10\.1\.20[12]/24", "active", "office1' "$S" && bad "a service is still addressed .201/.202 (pre-D-120 re-IP)" || ok
echo
total=$((pass+fail))
if [ "$fail" -eq 0 ]; then echo "d120-compose-bands: $pass/$total PASS"; exit 0; fi
echo "d120-compose-bands: $fail/$total FAIL"; exit 1