Files
PFVCluster/tests/unit/dns-drift-check.sh
T
mrcharles ebefbe47a7 feat(netinfra): NTP + Technitium zones into git SoR; drift-check full stack [#630]
ntp.conf captured (nodes byte-identical); 171 Technitium DZ zone files
captured from the primary; drift-check now covers dhcpd/pihole/ntp on
both nodes plus a zones md5-manifest check. Live run caught real drift:
node-02 dhcpd.conf was a stale primary copy missing the #614 minisplit
reservation — reconciled git->02 with dhcpd -t gate, serial restart,
failover "Both servers normal", all 7 checks in sync. Red-green unit
tests extended (gen_manifest, tracked-file invariants).

Results: https://projects.knownelement.com/issues/630#note-2
2026-09-02 16:33:33 -05:00

110 lines
3.2 KiB
Bash
Executable File

#!/bin/bash
# Unit tests for netinfra/dns/drift-check.sh [#420][#469]
# Tests the redaction and normalization functions without touching hosts.
set -euo pipefail
PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
SCRIPT="$PROJECT_ROOT/netinfra/dns/drift-check.sh"
failed=0
if [[ -f "$SCRIPT" ]] && (source "$SCRIPT"); then
echo "✅ script exists + sources cleanly"
else
echo "❌ script missing or fails to source: $SCRIPT"
exit 1
fi
# shellcheck disable=SC1091
source "$SCRIPT"
test_redact_strips_secrets() {
local out
out=$(printf ' pwhash = "SECRETBALLOONHASH"\n totp_secret = "ABC234"\n password = "hunter2"\n port = 53\n' | redact_config)
if grep -qE "SECRETBALLOON|ABC234|hunter2" <<<"$out"; then
echo "❌ redact_config leaked a secret"
((++failed))
elif grep -q '"REDACTED"' <<<"$out" && grep -q "port = 53" <<<"$out"; then
echo "✅ redact_config strips secrets, keeps config"
else
echo "❌ redact_config mangled output"
((++failed))
fi
}
test_normalize_drops_timestamp() {
local out
out=$(printf '# Last updated on 2026-09-01 17:01:15 CDT\n dnsmasq_lines = []\n' | normalize_toml)
if grep -q "Last updated" <<<"$out"; then
echo "❌ normalize_toml kept the timestamp churn line"
((++failed))
elif grep -q "dnsmasq_lines" <<<"$out"; then
echo "✅ normalize_toml drops timestamp, keeps config"
else
echo "❌ normalize_toml dropped config lines"
((++failed))
fi
}
test_normalize_implies_redaction() {
local out
out=$(printf ' totp_secret = "XYZ789"\n a = 1\n' | normalize_toml)
if grep -q XYZ789 <<<"$out"; then
echo "❌ normalize_toml leaked a secret"
((++failed))
else
echo "✅ normalize_toml redacts secrets"
fi
}
test_redact_strips_secrets
test_normalize_drops_timestamp
test_normalize_implies_redaction
test_ntp_conf_tracked() {
if [[ -n "${NTP_FILE:-}" && -f "$NTP_FILE" ]]; then
echo "✅ NTP_FILE points at tracked canonical config"
else
echo "❌ NTP_FILE missing or file absent: ${NTP_FILE:-unset}"
((++failed))
fi
}
test_zones_dir_tracked() {
if [[ -n "${ZONES_DIR:-}" && -d "$ZONES_DIR" ]] && compgen -G "${ZONES_DIR}/*.zone" > /dev/null; then
echo "✅ ZONES_DIR present with zone files"
else
echo "❌ ZONES_DIR missing or empty: ${ZONES_DIR:-unset}"
((++failed))
fi
}
test_gen_manifest_sorted_md5() {
local fxt out n
fxt="$(mktemp -d)"
printf 'A' > "$fxt/zz.zone"
printf 'B' > "$fxt/aa.zone"
printf 'S' > "$fxt/ignored.txt"
out="$(gen_manifest "$fxt")"
n="$(wc -l <<<"$out")"
if [[ "$n" -eq 2 ]] \
&& grep -qE '^[0-9a-f]{32} (aa|zz)\.zone$' <<<"$out" \
&& [[ "$(head -1 <<<"$out")" == *"aa.zone" ]] \
&& ! grep -q 'ignored' <<<"$out"; then
echo "✅ gen_manifest: md5 of *.zone only, name-sorted"
else
echo "❌ gen_manifest wrong output"
((++failed))
fi
rm -rf "$fxt"
}
test_ntp_conf_tracked
test_zones_dir_tracked
test_gen_manifest_sorted_md5
if ((failed > 0)); then
echo "❌ $failed drift-check test(s) failed"
exit 1
fi
echo "✅ all drift-check tests passed"