Files
counters/contrib/pull-domains_test.sh

103 lines
4.7 KiB
Bash
Executable File

#!/usr/bin/env bash
# Tests for pull-domains.sh against a local "agent" directory (RSYNC_SRC
# override) instead of ssh. Needs tinycdb's `cdb` and rsync in PATH.
# Run with `make test-contrib`.
set -u
HERE=$(cd "$(dirname "$0")" && pwd)
SCRIPT=$HERE/pull-domains.sh
TMP=$(mktemp -d)
trap 'rm -rf "$TMP"' EXIT
export RSYNC_SRC=$TMP/agent/rspamd_domains_db
export MAPS_DIR=$TMP/maps
export DOMAINS_DIR=$TMP/db
export DOMAINS_CDB=$DOMAINS_DIR/rspamd_domains_db
export LOG_FILE=$TMP/pull.log
export LOCK_FILE=$TMP/.pull-lock
export RELOAD_CMD="touch $TMP/reloaded"
mkdir -p "$TMP/agent" "$DOMAINS_DIR"
fails=0
pass() { echo "ok - $1"; }
fail() { echo "FAIL - $1"; fails=$((fails + 1)); }
check() { if eval "$2"; then pass "$1"; else fail "$1"; fi; }
# make_cdb FILE KEY VALUE: build a one-record CDB the way the agent does (cdb -c).
make_cdb() {
printf '+%d,%d:%s->%s\n\n' "${#2}" "${#3}" "$2" "$3" | cdb -c "$1"
}
inode() { stat -f %i "$1" 2>/dev/null || stat -c %i "$1"; }
# --- 1. first install -------------------------------------------------------
make_cdb "$RSYNC_SRC" example.com "1049|A/i=200,A/o=20"
rm -f "$TMP/reloaded"
"$SCRIPT" >/dev/null 2>&1; rc=$?
check "first run exits 0" "[ $rc -eq 0 ]"
check "first run installs the CDB" "[ -f '$DOMAINS_CDB' ] && cmp -s '$RSYNC_SRC' '$DOMAINS_CDB'"
check "first run keeps the .orig baseline" "cmp -s '$RSYNC_SRC' '$DOMAINS_CDB.orig'"
check "first run reloads the daemon" "[ -f '$TMP/reloaded' ]"
check "no temp file left behind" "! ls '$DOMAINS_DIR'/.rspamd_domains_db.* >/dev/null 2>&1"
check "lock released" "[ ! -f '$LOCK_FILE' ]"
check "log written" "grep -q 'rspamd_domains_db' '$LOG_FILE'"
# --- 2. unchanged source ----------------------------------------------------
before=$(inode "$DOMAINS_CDB")
rm -f "$TMP/reloaded"
"$SCRIPT" >/dev/null 2>&1; rc=$?
check "unchanged run exits 0" "[ $rc -eq 0 ]"
check "unchanged run does not replace the file (same inode)" "[ '$(inode "$DOMAINS_CDB")' = '$before' ]"
check "unchanged run does not reload" "[ ! -f '$TMP/reloaded' ]"
check "unchanged run logs the skip" "grep -q 'unchanged' '$LOG_FILE'"
# --- 3. changed source -------------------------------------------------------
make_cdb "$RSYNC_SRC" example.com "1049|A/i=500,A/o=50"
rm -f "$TMP/reloaded"
"$SCRIPT" >/dev/null 2>&1; rc=$?
check "changed run exits 0" "[ $rc -eq 0 ]"
check "changed run installs atomically (new inode)" "[ '$(inode "$DOMAINS_CDB")' != '$before' ]"
check "changed run installs the new content" "cmp -s '$RSYNC_SRC' '$DOMAINS_CDB'"
check "changed run updates .orig" "cmp -s '$RSYNC_SRC' '$DOMAINS_CDB.orig'"
check "changed run reloads the daemon" "[ -f '$TMP/reloaded' ]"
check "changed run logs the install" "grep -q 'installed' '$LOG_FILE'"
# --- 4. corrupt source -------------------------------------------------------
good_inode=$(inode "$DOMAINS_CDB")
cp "$DOMAINS_CDB" "$TMP/good.copy"
printf 'garbage' > "$RSYNC_SRC"
rm -f "$TMP/reloaded"
"$SCRIPT" >/dev/null 2>&1; rc=$?
check "corrupt source exits non-zero" "[ $rc -ne 0 ]"
check "corrupt source leaves the installed file untouched" "[ '$(inode "$DOMAINS_CDB")' = '$good_inode' ] && cmp -s '$DOMAINS_CDB' '$TMP/good.copy'"
check "corrupt source does not touch .orig" "cmp -s '$DOMAINS_CDB.orig' '$TMP/good.copy'"
check "corrupt source does not reload" "[ ! -f '$TMP/reloaded' ]"
check "corrupt source leaves no temp file" "! ls '$DOMAINS_DIR'/.rspamd_domains_db.* >/dev/null 2>&1"
check "corrupt source releases the lock" "[ ! -f '$LOCK_FILE' ]"
check "corrupt source is logged" "grep -q 'not a valid CDB' '$LOG_FILE'"
# An empty CDB (zero records) is just as useless: refused too.
printf '\n' | cdb -c "$RSYNC_SRC"
"$SCRIPT" >/dev/null 2>&1; rc=$?
check "empty CDB is refused" "[ $rc -ne 0 ] && cmp -s '$DOMAINS_CDB' '$TMP/good.copy'"
# --- 5. lock file -------------------------------------------------------------
make_cdb "$RSYNC_SRC" example.com "1049|A/i=1,A/o=1"
touch "$LOCK_FILE"
"$SCRIPT" >/dev/null 2>&1; rc=$?
check "fresh lock skips the run (exit 0)" "[ $rc -eq 0 ]"
check "fresh lock leaves the file alone" "cmp -s '$DOMAINS_CDB' '$TMP/good.copy'"
check "fresh lock is logged" "grep -q 'still running' '$LOG_FILE'"
touch -t 200001010000 "$LOCK_FILE" # stale
"$SCRIPT" >/dev/null 2>&1; rc=$?
check "stale lock is ignored" "[ $rc -eq 0 ] && cmp -s '$RSYNC_SRC' '$DOMAINS_CDB'"
# --- 6. the pull itself fails ------------------------------------------------
rm -f "$RSYNC_SRC"
"$SCRIPT" >/dev/null 2>&1; rc=$?
check "missing source exits non-zero and keeps the installed file" "[ $rc -ne 0 ] && [ -f '$DOMAINS_CDB' ]"
check "failed pull releases the lock" "[ ! -f '$LOCK_FILE' ]"
echo
if [ $fails -eq 0 ]; then echo "all contrib tests passed"; else echo "$fails contrib test(s) FAILED"; exit 1; fi