Moved from KNEL/PFVCluster tests/unit with repo-relative paths. https://projects.knownelement.com/issues/769#note-4152
129 lines
3.2 KiB
Bash
Executable File
129 lines
3.2 KiB
Bash
Executable File
#!/bin/bash
|
|
# Unit tests for dns-cluster-setup/sync-zones.sh [#469]
|
|
# Verifies reload-on-change behavior: Technitium restart fires only when
|
|
# rsync actually changed zone files, and never on clean syncs.
|
|
set -euo pipefail
|
|
|
|
PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
SCRIPT="$PROJECT_ROOT/dns-cluster-setup/sync-zones.sh"
|
|
|
|
failed=0
|
|
|
|
TMP="$(mktemp -d)"
|
|
trap 'rm -rf "$TMP"' EXIT
|
|
export LOG_FILE="$TMP/sync.log"
|
|
|
|
# Script must exist and source cleanly (main guarded for sourcing)
|
|
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"
|
|
|
|
# Fake command log: record invocations of rsync / reload / find
|
|
FAKE_BIN="$TMP/bin"
|
|
mkdir -p "$FAKE_BIN"
|
|
export PATH="$FAKE_BIN:$PATH"
|
|
|
|
make_rsync() {
|
|
# $1 = exit code, $2 = "changed" or "clean" (stdout of rsync)
|
|
cat > "$FAKE_BIN/rsync" <<EOF
|
|
#!/bin/bash
|
|
echo "$2"
|
|
exit $1
|
|
EOF
|
|
chmod +x "$FAKE_BIN/rsync"
|
|
}
|
|
|
|
make_reload() {
|
|
cat > "$FAKE_BIN/reload" <<'EOF'
|
|
#!/bin/bash
|
|
echo "reload-fired" >> "$RELOAD_LOG"
|
|
EOF
|
|
chmod +x "$FAKE_BIN/reload"
|
|
}
|
|
|
|
RELOAD_LOG="$TMP/reload.log"
|
|
touch "$RELOAD_LOG"
|
|
export RELOAD_LOG
|
|
|
|
# find: minimal fake so zone counting works
|
|
mkdir -p "$FAKE_BIN/find-dir"
|
|
cat > "$FAKE_BIN/find" <<'EOF'
|
|
#!/bin/bash
|
|
# report 3 fake zone files regardless of args
|
|
for i in 1 2 3; do echo "/zones/zone$i"; done
|
|
EOF
|
|
chmod +x "$FAKE_BIN/find"
|
|
|
|
test_reload_fires_on_change() {
|
|
make_rsync 0 "knel.net.zone"
|
|
make_reload
|
|
RELOAD_CMD=("$FAKE_BIN/reload")
|
|
export RELOAD_CMD
|
|
if sync_and_reload >/dev/null 2>&1 && [[ "$(cat "$RELOAD_LOG")" == "reload-fired" ]]; then
|
|
echo "✅ reload fires when rsync reports changed zones"
|
|
else
|
|
echo "❌ reload did not fire on changed sync"
|
|
((++failed))
|
|
fi
|
|
: > "$RELOAD_LOG"
|
|
}
|
|
|
|
test_no_reload_on_clean_sync() {
|
|
make_rsync 0 ""
|
|
make_reload
|
|
RELOAD_CMD=("$FAKE_BIN/reload")
|
|
export RELOAD_CMD
|
|
if sync_and_reload >/dev/null 2>&1 && [[ ! -s "$RELOAD_LOG" ]]; then
|
|
echo "✅ no reload on clean sync"
|
|
else
|
|
echo "❌ reload fired (or errored) on clean sync"
|
|
((++failed))
|
|
fi
|
|
}
|
|
|
|
test_rsync_failure_propagates() {
|
|
make_rsync 23 ""
|
|
RELOAD_CMD=("$FAKE_BIN/reload")
|
|
export RELOAD_CMD
|
|
if ! sync_and_reload >/dev/null 2>&1; then
|
|
echo "✅ rsync failure propagates non-zero rc"
|
|
else
|
|
echo "❌ rsync failure was swallowed"
|
|
((++failed))
|
|
fi
|
|
if [[ ! -s "$RELOAD_LOG" ]]; then
|
|
echo "✅ no reload attempted after rsync failure"
|
|
else
|
|
echo "❌ reload fired despite rsync failure"
|
|
((++failed))
|
|
fi
|
|
}
|
|
|
|
test_reload_failure_does_not_break_sync() {
|
|
make_rsync 0 "knel.net.zone"
|
|
RELOAD_CMD=("/bin/false")
|
|
export RELOAD_CMD
|
|
if sync_and_reload >/dev/null 2>&1; then
|
|
echo "✅ reload failure does not fail the sync run"
|
|
else
|
|
echo "❌ reload failure failed the whole sync"
|
|
((++failed))
|
|
fi
|
|
}
|
|
|
|
test_reload_fires_on_change
|
|
test_no_reload_on_clean_sync
|
|
test_rsync_failure_propagates
|
|
test_reload_failure_does_not_break_sync
|
|
|
|
if ((failed > 0)); then
|
|
echo "❌ $failed sync-zones test(s) failed"
|
|
exit 1
|
|
fi
|
|
echo "✅ all sync-zones tests passed"
|