Newer
Older
openstack-caracal-dc-dc / tests / d115-office-carve / run-tests.sh
#!/usr/bin/env bash
# tests/d115-office-carve/run-tests.sh
#
# Harness for netbox/d115-office-carve.py. OFFLINE -- touches no NetBox.
#
# The carve's VALUES are the point. Every CIDR in that script was MEASURED off
# the live Office1 build; D-115 blesses exactly what is running, so a "tidy-up"
# that changes one of these silently turns a zero-renumber carve into a
# renumber. This harness pins them.
# ASCII + LF.
set -uo pipefail
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
S="$(cd "$HERE/../../netbox" && pwd)/d115-office-carve.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 (the D-117 lesson).
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"

# WRITING UPSTREAM IS GATED IN CODE, not by discipline. Feeding the production
# apex is an operator decision; it must never be a side effect of an import.
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)"

# THE D-115 VALUES. Each was measured on the live build; changing one costs a renumber.
for cidr in \
  "10.10.0.0/16" "10.10.0.0/22" "10.10.0.0/24" "10.10.1.0/24" \
  "172.30.0.0/16" "172.30.1.0/24" \
  "2602:f3e2:f01:100::/56" "2602:f3e2:f01:100::/64"; do
  grep -qF "\"$cidr\"" "$S" && ok || bad "D-115 prefix $cidr is GONE from the carve"
done

# The two roles D-115 exists to create. `edge` is the NEW one -- v6 had "Edge
# Networks", v4 had nothing, so the WAN was squatting inside the OOB /12.
grep -q '"slug": "office"' "$S" && ok || bad "the office role is gone"
grep -q '"slug": "edge"'   "$S" && ok || bad "the edge role is gone -- the WAN goes back to squatting in OOB"

# The office KEEPS its number (D-117 operator ruling): site is vr1-off1, NOT off0.
grep -q '"slug": "vr1-off1"' "$S" && ok || bad "site slug is not vr1-off1 (D-117: the office keeps its number)"
grep -q 'vr1-off0' "$S" && bad "vr1-off0 appears -- the office was NOT renamed (D-117)" || ok

# The DC v4 supernet must NOT be duplicated here -- it belongs to the six-plane
# importer. Two owners for one prefix is how they drift apart.
# (match the PREFIXES table, not the docstring that explains why it is absent)
grep -qE '^\s*\("10\.12\.64\.0/19"' "$S" \
  && bad "DC1's v4 supernet is duplicated here -- it belongs to dc-dc-prefixes-import.py" || ok

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