#!/usr/bin/env bash
# tests/site-tailscale/run-tests.sh -- offline harness for scripts/site-tailscale.sh.
# Fakes `tailscale` (status --json / up / version) and `ip`; real python3 for jget. NO network,
# mutates nothing outside mktemp. Proves each exit path can FIRE (a new assertion is decoration
# until it has a failing-direction fixture):
# check-happy -> 0 (Running + route approved + tagged + .7 leg)
# check-notrun -> 1 (BackendState != Running)
# check-noroute -> 1 (metal-admin CIDR not in approved PrimaryRoutes)
# check-notag -> 1 (node not tagged)
# check-noleg -> 1 (no .7 metal-admin leg on the host)
# install-nokey -> 4 (no tagged pre-auth key)
# install-noTS -> 4 (tailscale binary absent)
# install-upfail -> 4 (tailscale up rejected)
# install-happy -> 0 (up ok + check green)
# badmode/badsite/noargs -> 2
# site-table rows carry MEASURED tags (hard rule 2)
# dc1 site resolves its own CIDR (10.12.68.0/22), not dc0's
# Exit: 0 all pass | 1 any case failed. ASCII + LF.
set -uo pipefail
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO="$(cd "$HERE/../.." && pwd)"
SUT="$REPO/scripts/site-tailscale.sh"
TMP="$(mktemp -d)"; trap 'rm -rf "$TMP"' EXIT
PASS=0; FAIL=0
BIN="$TMP/bin"; mkdir -p "$BIN"
# ---- fake tailscale --------------------------------------------------------
cat > "$BIN/tailscale" <<'FB'
#!/usr/bin/env bash
mode="${TS_FAKE_MODE:-happy}"; cidr="${TS_FAKE_CIDR:-10.12.8.0/22}"
case "$1" in
version) echo "1.98.9"; exit 0;;
up) [ "$mode" = upfail ] && exit 1; exit 0;;
status)
# $2 == --json
st='"Running"'; routes="[\"$cidr\"]"; tags='["tag:subnet-router"]'
case "$mode" in
notrun) st='"Stopped"';;
noroute) routes='[]';;
notag) tags='[]';;
esac
printf '{"BackendState":%s,"Self":{"PrimaryRoutes":%s,"Tags":%s}}\n' "$st" "$routes" "$tags"
exit 0;;
*) exit 0;;
esac
FB
chmod +x "$BIN/tailscale"
# ---- fake ip (own_leg_matches) --------------------------------------------
cat > "$BIN/ip" <<'FB'
#!/usr/bin/env bash
# emit a .7 metal-admin leg unless TS_FAKE_MODE=noleg
[ "${TS_FAKE_MODE:-}" = noleg ] && { echo "1: lo inet 127.0.0.1/8 scope host lo"; exit 0; }
echo "2: enp1s0 inet ${TS_FAKE_LEG:-10.12.8.7}/22 scope global enp1s0"
exit 0
FB
chmod +x "$BIN/ip"
run(){ # <name> <expected-exit> <mode> <args...>
local name="$1" exp="$2" mode="$3"; shift 3
local out code
out="$(PATH="$BIN:$PATH" TAILSCALE="$BIN/tailscale" TS_FAKE_MODE="$mode" \
TS_AUTHKEY="${CASE_AUTHKEY:-}" TAILSCALE="${CASE_TS:-$BIN/tailscale}" \
bash "$SUT" "$@" 2>&1)"; code=$?
if [ "$code" -eq "$exp" ]; then PASS=$((PASS+1)); echo "PASS: $name (exit $code)"
else FAIL=$((FAIL+1)); echo "FAIL: $name (got $code want $exp)"; echo "$out" | sed 's/^/ /'; fi
}
echo "=== site-tailscale harness ==="
# check cases (dc0)
run check-happy 0 happy check vr1-dc0
run check-notrun 1 notrun check vr1-dc0
run check-noroute 1 noroute check vr1-dc0
run check-notag 1 notag check vr1-dc0
run check-noleg 1 noleg check vr1-dc0
# install cases
CASE_AUTHKEY="tskey-fake" run install-happy 0 happy install vr1-dc0
run install-nokey 4 happy install vr1-dc0
CASE_AUTHKEY="tskey-fake" run install-upfail 4 upfail install vr1-dc0
CASE_TS="$BIN/nope" CASE_AUTHKEY="tskey-fake" run install-noTS 4 happy install vr1-dc0
# arg/site validation
run badmode 2 happy frobnicate vr1-dc0
run badsite 2 happy check vr1-dc9
run noargs 2 happy
# dc1 resolves its OWN cidr (not dc0's) -- run check-happy with dc1 fixture
PASS_BEFORE=$PASS
out="$(PATH="$BIN:$PATH" TAILSCALE="$BIN/tailscale" TS_FAKE_MODE=happy TS_FAKE_CIDR='10.12.68.0/22' TS_FAKE_LEG='10.12.68.7' \
bash "$SUT" check vr1-dc1 2>&1)"; code=$?
if [ "$code" -eq 0 ] && printf '%s' "$out" | grep -q '10.12.68.0/22'; then PASS=$((PASS+1)); echo "PASS: dc1 resolves 10.12.68.0/22 (exit 0)"
else FAIL=$((FAIL+1)); echo "FAIL: dc1 site (got $code)"; echo "$out" | sed 's/^/ /'; fi
# site-table rows must carry MEASURED tags (hard rule 2)
for s in 'vr1-dc0.*MEASURED' 'vr1-dc1.*MEASURED'; do
if grep -qE "$s" "$SUT"; then PASS=$((PASS+1)); echo "PASS: site row tagged MEASURED ($s)"
else FAIL=$((FAIL+1)); echo "FAIL: site row missing MEASURED ($s)"; fi
done
echo "=== $PASS pass / $FAIL fail ==="
[ "$FAIL" -eq 0 ]