Newer
Older
openstack-caracal-dc-dc / tests / site-headend-install / run-tests.sh
#!/usr/bin/env bash
# tests/site-headend-install/run-tests.sh
#
# Harness for scripts/site-headend-install.sh. Exercises arg parsing, the SAFETY GUARDS,
# and --dry-run only. It NEVER installs a snap, never touches MAAS/LXD, and never mutates
# the machine (same posture as tests/prereqs and the opnsense-* harnesses).
#
# The guards are the point of this harness. The script's whole reason to exist is that
# four specific traps cost a live session on 2026-07-13; a regression that quietly drops
# one of them would not show up in any deploy until something broke in production.
# ASCII + LF.
set -uo pipefail
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
S="$(cd "$HERE/../../scripts" && pwd)/site-headend-install.sh"
pass=0; fail=0
ok()  { pass=$((pass+1)); }
bad() { fail=$((fail+1)); echo "  FAIL: $1"; }
t() { local d="$1" exp="$2"; shift 2; "$@" >/dev/null 2>&1; local rc=$?; if [ "$rc" = "$exp" ]; then ok; else bad "$d (rc=$rc want=$exp)"; fi; }

# 1. arg contract
t "--help -> 0"                 0 bash "$S" --help
t "unknown arg -> 2"            2 bash "$S" --bogus
t "missing --compose-cidr -> 2" 2 bash "$S" --dry-run
t "non-/24 cidr -> 2"           2 bash "$S" --dry-run --compose-cidr 10.10.1.0/16
t "garbage cidr -> 2"           2 bash "$S" --dry-run --compose-cidr not-a-cidr
t "valid --dry-run -> 0"        0 bash "$S" --dry-run --compose-cidr 10.10.1.0/24

# 2. --compose-cidr must have NO default. A default here is how you end up serving MAAS
#    DHCP on the site LAN, where the edge's Kea is authoritative (trap 4).
out="$(bash "$S" --dry-run 2>&1)"
printf '%s' "$out" | grep -q -- "--compose-cidr is REQUIRED" && ok || bad "missing --compose-cidr must fail LOUD and say why"

# 3. --dry-run must MUTATE NOTHING: no snap install, no lxc, no maas invoked.
out="$(bash "$S" --dry-run --compose-cidr 10.10.1.0/24 2>&1)"
printf '%s' "$out" | grep -q '\[dry-run\]' && ok || bad "--dry-run printed no [dry-run] plan"
if snap list lxd >/dev/null 2>&1 || snap list maas >/dev/null 2>&1; then
  bad "--dry-run appears to have INSTALLED a snap on the test host"
else ok; fi

# 4. the derived addresses must track --compose-cidr, not be hardcoded.
out="$(bash "$S" --dry-run --compose-cidr 10.77.5.0/24 2>&1)"
printf '%s' "$out" | grep -q "10.77.5.1/24"   && ok || bad "bridge IP not derived from --compose-cidr"
printf '%s' "$out" | grep -q "10.77.5.100"    && ok || bad "range start not derived from --compose-cidr"
printf '%s' "$out" | grep -q "10.77.5.200"    && ok || bad "range end not derived from --compose-cidr"

# 5. THE FOUR TRAPS must remain encoded in the script. Each of these cost a live session;
#    if someone "simplifies" one away, this harness goes red rather than the cloud.
grep -q 'raw.dnsmasq' "$S"                    && ok || bad "trap 1 LOST: raw.dnsmasq=port=0 is what stops dnsmasq binding :53 against MAAS's bind9"
grep -q 'ipv4.dhcp=false' "$S"                && ok || bad "trap 1 LOST: lxdbr0 must have LXD's own DHCP off"

# Fold backslash-continuations first, and strip comments + echo'd strings, so we test what
# the script EXECUTES rather than what it says. (Both of these bit this harness on its
# first run: a multi-line `lxc network create` reads as missing its redirect, and an echo
# that WARNS about `lxd init --auto` reads as calling it.)
CODE="$(sed -e 's/#.*$//' "$S" | sed -e ':a' -e '/\\$/{N; s/\\\n//; ta}' | grep -vE '^[[:space:]]*echo ')"

printf '%s' "$CODE" | grep -qE '\blxd init --auto\b' \
  && bad "trap 1 LOST: 'lxd init --auto' is EXECUTED -- it FAILS when MAAS's bind9 holds :53" || ok

n="$(printf '%s' "$CODE" | grep -cE '\blxc\b.*</dev/null')"
m="$(printf '%s' "$CODE" | grep -cE '\blxc\b')"
[ "$m" -ge 1 ] && [ "$n" = "$m" ] && ok || bad "trap 2 LOST: every lxc call must redirect </dev/null ($n of $m do) -- lxc reads stdin and EATS the piped script"
grep -q '5.21/stable' "$S"                    && ok || bad "trap 3 LOST: LXD must be pinned to the 5.21 LTS track (MAAS breaks on LXD >= 6.7)"
grep -q 'is ON for a subnet that is NOT the compose network' "$S" \
                                              && ok || bad "trap 4 LOST: the guard asserting MAAS DHCP is on NO other subnet is gone"

echo
total=$((pass+fail))
if [ "$fail" -eq 0 ]; then echo "site-headend-install: $pass/$total PASS"; exit 0; fi
echo "site-headend-install: $fail/$total FAIL"; exit 1