#!/usr/bin/env bash
# tests/juju-spaces-check/run-tests.sh -- mock harness for scripts/juju-spaces-check.sh
# Covers the model gate (DOCFIX-115 capture-then-test fix): model present -> spaces
# asserted (0); model absent -> exit 2 "not present"; 'juju models' FAILS (expired
# macaroon) -> exit 1 with the macaroon hint, NEVER misreported as "model not
# present" (the pre-fix live pipe masked auth failure as absence). Plus: missing
# space -> exit 1; stale space present -> exit 1. Requires jq (real; skips if absent).
# Exit: 0 all pass | 1 any case failed. ASCII + LF.
set -uo pipefail
SD="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"; SCRIPT="$SD/../../scripts/juju-spaces-check.sh"
command -v jq >/dev/null || { echo "SKIP: jq absent"; exit 0; }
W=$(mktemp -d); trap 'rm -rf "$W"' EXIT
mkdir -p "$W/bin"
cat > "$W/bin/juju" <<'JM'
#!/usr/bin/env bash
S="${MOCK_SCEN:-present}"
case "$*" in
"whoami") echo "Controller: maas-controller"; echo "User: admin";;
"models")
if [ "$S" = authfail ]; then echo "ERROR cannot list models: macaroon discharge required" >&2; exit 1; fi
echo "Model Cloud Status"; echo "controller maas available";;
"models --format json")
if [ "$S" = authfail ]; then echo "ERROR cannot list models: macaroon discharge required" >&2; exit 1; fi
if [ "$S" = absent ]; then echo '{"models":[{"name":"admin/controller"}]}'
else echo '{"models":[{"name":"admin/controller"},{"name":"admin/openstack"}]}'; fi;;
"spaces -m openstack --format json")
case "$S" in
missingspace) echo '{"spaces":[{"name":"provider-public"},{"name":"metal-admin"},{"name":"metal-internal"},{"name":"data-tenant"},{"name":"storage"}]}';;
stalespace) echo '{"spaces":[{"name":"provider-public"},{"name":"metal-admin"},{"name":"metal-internal"},{"name":"data-tenant"},{"name":"storage"},{"name":"replication"},{"name":"lbaas"}]}';;
*) echo '{"spaces":[{"name":"provider-public"},{"name":"metal-admin"},{"name":"metal-internal"},{"name":"data-tenant"},{"name":"storage"},{"name":"replication"}]}';;
esac;;
*) echo "fake-juju: unmatched: $*" >&2; exit 1;;
esac
JM
chmod +x "$W/bin/juju"
P=0; F=0
runcase(){ # runcase <scen> <want_rc> <want_regex> <mustnot_regex|-> <label>
local OUT RC
OUT=$(MOCK_SCEN="$1" PATH="$W/bin:$PATH" bash "$SCRIPT" 2>&1); RC=$?
if [ "$RC" = "$2" ] && grep -qE "$3" <<<"$OUT" && { [ "$4" = "-" ] || ! grep -qE "$4" <<<"$OUT"; }; then
echo " PASS $5"; P=$((P+1))
else echo " FAIL $5 (rc=$RC want=$2)"; echo "$OUT" | tail -4 | sed 's/^/ /'; F=$((F+1)); fi
}
runcase present 0 'Summary: 0 fatal' 'FAIL:' "model present, six spaces, none stale -> 0"
runcase absent 2 "model 'openstack' not present yet" '-' "model absent -> 2 with add-model hint"
# the DOCFIX-115 regression: an auth failure must take the macaroon-hint path,
# never be classified as "model not present"
runcase authfail 1 'juju models failed \(auth/macaroon' 'not present yet' "juju models failure -> 1 + macaroon hint (not 'absent')"
runcase missingspace 1 'MISSING: replication' '-' "missing space -> 1"
runcase stalespace 1 'STALE STILL PRESENT: lbaas' '-' "stale space -> 1"
echo; T=$((P+F)); [ "$F" = 0 ] && { echo "ALL PASS ($P/$T)"; exit 0; } || { echo "FAILURES: $F ($P/$T)"; exit 1; }