#!/usr/bin/env bash
# tests/prereqs/run-tests.sh
# Harness for scripts/prereqs/* -- exercises the mode-parse / guard / --check /
# --dry-run paths only. It NEVER runs a real apt install (that needs root and
# would mutate the machine; same posture as the opnsense-* harnesses). ASCII + LF.
set -uo pipefail
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PREQ="$(cd "$HERE/../../scripts/prereqs" && pwd)"
pass=0; fail=0
ok() { pass=$((pass+1)); }
bad() { fail=$((fail+1)); echo " FAIL: $1"; }
# t <desc> <expected-rc> <cmd...>
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; }
INSTALLERS="install-opentofu install-virtualization install-jq install-image-tools"
# 1. lib-prereq sourcing + mode parsing
. "$PREQ/lib-prereq.sh"
type pq_have >/dev/null 2>&1 && ok || bad "lib-prereq did not define pq_have"
pq_parse_mode --check >/dev/null 2>&1; [ "${PQ_CHECK:-x}" = "1" ] && ok || bad "parse --check set PQ_CHECK"
pq_parse_mode --dry-run >/dev/null 2>&1; [ "${PQ_DRYRUN:-x}" = "1" ] && ok || bad "parse --dry-run set PQ_DRYRUN"
pq_parse_mode --bogus >/dev/null 2>&1; [ "$?" = "2" ] && ok || bad "parse bad arg -> 2"
pq_parse_mode --help >/dev/null 2>&1; [ "$?" = "10" ] && ok || bad "parse --help -> 10"
# 2. pq_run: dry-run must NOT execute; real mode must
tmp="$(mktemp -d)"; trap 'rm -rf "$tmp"' EXIT
PQ_DRYRUN=1 pq_run "sentinel" -- touch "$tmp/nope" >/dev/null 2>&1
[ ! -e "$tmp/nope" ] && ok || bad "pq_run dry-run executed the command"
PQ_DRYRUN=0 pq_run "sentinel" -- touch "$tmp/yes" >/dev/null 2>&1
[ -e "$tmp/yes" ] && ok || bad "pq_run real-mode did not execute"
# 3. each installer: --help=0, bad-arg=2, --dry-run=0 (never a real install)
for s in $INSTALLERS; do
t "$s --help" 0 bash "$PREQ/$s.sh" --help
t "$s bad-arg" 2 bash "$PREQ/$s.sh" --bogus
t "$s --dry-run" 0 bash "$PREQ/$s.sh" --dry-run
done
# 4. orchestrator
t "install-all --help" 0 bash "$PREQ/install-all.sh" --help
t "install-all bad-arg" 2 bash "$PREQ/install-all.sh" --bogus
t "install-all --dry-run" 0 bash "$PREQ/install-all.sh" --dry-run
# 5. check-prereqs is read-only and exits 0 (all present) or 1 (something missing)
bash "$PREQ/check-prereqs.sh" >/dev/null 2>&1; rc=$?
{ [ "$rc" = "0" ] || [ "$rc" = "1" ]; } && ok || bad "check-prereqs rc=$rc (want 0|1)"
# 5b. each tool row appears at most once -- guards the line() return-value bug
# (a helper whose last cmd is a failing test makes `A && line OK || line WARN`
# print BOTH). Found on first dogfood run; fixed via line() return 0.
crep="$(bash "$PREQ/check-prereqs.sh" 2>&1)"
dupbad=0
for tool in tofu virsh jq qemu-img curl python3 sudo; do
n="$(printf '%s\n' "$crep" | grep -cE "\][ ]+${tool}[ ]+")"
[ "$n" -le 1 ] || dupbad=1
done
[ "$dupbad" = "0" ] && ok || bad "check-prereqs printed a tool row more than once"
# 6. an absent tool's --dry-run must reach + print the dry-run plan (marker)
if pq_have jq; then
ok # jq present -> install-jq short-circuits at OK before the plan; marker not expected
else
bash "$PREQ/install-jq.sh" --dry-run 2>&1 | grep -q '\[dry-run\]' && ok || bad "install-jq --dry-run lacked [dry-run] marker"
fi
echo
total=$((pass+fail))
if [ "$fail" -eq 0 ]; then echo "prereqs: $pass/$total PASS"; exit 0; fi
echo "prereqs: $fail/$total FAIL"; exit 1