diff --git a/contrib/testing/README.md b/contrib/testing/README.md index 5088ece..97f8b07 100644 --- a/contrib/testing/README.md +++ b/contrib/testing/README.md @@ -94,19 +94,19 @@ reserve was subtracted without 32-bit truncation: ./contrib/testing/queue-disk-space-check.sh ``` -The Queue failure-safety check retains one isolated message while it first -raises the operative reserve above the filesystem's available bytes and then -makes the spool unreadable. It verifies rejection/defer responses, restores -the configuration and permissions through traps, and compares the retained -message byte-for-byte after both recoveries: +The Queue failure-safety check retains one isolated message in an 8 MiB tmpfs +fixture while it first fills that filesystem below the operative reserve and +then overlays the spool with an unreadable directory. It verifies +rejection/defer responses, restores all mounts through traps, and compares the +retained message byte-for-byte after both recoveries: ```sh ./contrib/testing/queue-failure-safety-check.sh ``` -It requires passwordless permission for `bongo-admin __config-read` and -`__config-replace`, Bongo service restarts, and `stat`/`chmod` on the -dedicated test spool. Run it only on a disposable test installation. +It requires passwordless permission for Bongo service start/stop/restart, +`mount`, `umount`, and `stat` on the dedicated test spool. Run it only on a +disposable test installation. The Debian source probes and package-build commands used by BLD-14/BLD-15 are consolidated in `contrib/debian/build-trixie-bundle.sh`; they are not maintained diff --git a/contrib/testing/queue-failure-safety-check.sh b/contrib/testing/queue-failure-safety-check.sh index 6d049c1..efdd4f0 100755 --- a/contrib/testing/queue-failure-safety-check.sh +++ b/contrib/testing/queue-failure-safety-check.sh @@ -6,7 +6,6 @@ set -eu queue_tool=${BONGO_QUEUE_TOOL:-/usr/bin/bongo-queuetool} -admin_tool=${BONGO_ADMIN_TOOL:-/usr/bin/bongo-admin} service=${BONGO_SERVICE:-bongo.service} spool=${BONGO_QUEUE_SPOOL:-/var/lib/bongo/spool} run_as=${BONGO_TEST_RUN_AS:-bongo} @@ -20,24 +19,30 @@ fi work=$(mktemp -d "${TMPDIR:-/tmp}/bongo-stq04.XXXXXX") chmod 0755 "$work" +tmpfs="$work/tmpfs" +blocked="$work/blocked" +mkdir "$tmpfs" "$blocked" +chmod 0777 "$tmpfs" +chmod 000 "$blocked" queue_id= -spool_mode= -config_changed=0 +tmpfs_mounted=0 +spool_mounted=0 +blocked_mounted=0 restore() { status=$? - if [ -n "$spool_mode" ]; then - $as_root /usr/bin/chmod "$spool_mode" "$spool" >/dev/null 2>&1 || true + $as_root /usr/bin/systemctl stop "$service" >/dev/null 2>&1 || true + if [ "$blocked_mounted" -eq 1 ]; then + $as_root /usr/bin/umount "$spool" >/dev/null 2>&1 || true fi - if [ "$config_changed" -eq 1 ]; then - $as_root "$admin_tool" __config-replace queue \ - <"$work/queue.original" >/dev/null 2>&1 || true - $as_root /usr/bin/systemctl restart "$service" >/dev/null 2>&1 || true + if [ "$spool_mounted" -eq 1 ]; then + $as_root /usr/bin/umount "$spool" >/dev/null 2>&1 || true fi - if [ -n "$queue_id" ]; then - $as_bongo "$queue_tool" delete "$queue_id" >/dev/null 2>&1 || true + if [ "$tmpfs_mounted" -eq 1 ]; then + $as_root /usr/bin/umount "$tmpfs" >/dev/null 2>&1 || true fi + $as_root /usr/bin/systemctl start "$service" >/dev/null 2>&1 || true rm -rf "$work" exit "$status" } @@ -57,6 +62,15 @@ wait_queue() return 1 } +$as_root /usr/bin/systemctl stop "$service" +$as_root /usr/bin/mount -t tmpfs \ + -o size=8m,mode=0777 bongo-stq04 "$tmpfs" +tmpfs_mounted=1 +$as_root /usr/bin/mount --bind "$tmpfs" "$spool" +spool_mounted=1 +$as_root /usr/bin/systemctl start "$service" +wait_queue + printf '%s\r\n' \ 'From: STQ-04 ' \ 'To: stqqueue@bongo.test' \ @@ -68,32 +82,16 @@ printf '%s\r\n' \ >"$work/message.eml" chmod 0644 "$work/message.eml" -$as_root "$admin_tool" __config-read queue >"$work/queue.original" queue_id=$($as_bongo "$queue_tool" hold-local "$work/message.eml") $as_bongo "$queue_tool" message "$queue_id" >"$work/before.eml" before_hash=$(sha256sum "$work/before.eml" | awk '{ print $1 }') set -- $($as_bongo "$queue_tool" space details) -free_before=$1 -free_after=$2 +reported_before=$4 block=$5 -python3 - "$work/queue.original" "$work/queue.full" \ - "$free_before" "$free_after" "$block" <<'PY' -import json -import sys - -source, destination = sys.argv[1:3] -free_before, free_after, block = map(int, sys.argv[3:]) -with open(source, "r", encoding="utf-8") as stream: - config = json.load(stream) -config["minimumfreespace"] = max(free_before, free_after) + block + 1 -with open(destination, "w", encoding="utf-8") as stream: - json.dump(config, stream, indent=2, sort_keys=True) - stream.write("\n") -PY - -$as_root "$admin_tool" __config-replace queue <"$work/queue.full" -config_changed=1 +fill_blocks=$((reported_before / block + 1)) +/usr/bin/dd if=/dev/zero of="$tmpfs/fill" bs="$block" \ + count="$fill_blocks" status=none $as_root /usr/bin/systemctl restart "$service" wait_queue @@ -114,13 +112,11 @@ if ! grep -F 'Free disk space too low' "$work/full.err" >/dev/null; then fi $as_bongo "$queue_tool" message "$queue_id" >"$work/after-full.eml" -$as_root "$admin_tool" __config-replace queue <"$work/queue.original" -config_changed=0 -$as_root /usr/bin/systemctl restart "$service" +$as_root /usr/bin/systemctl stop "$service" +$as_root /usr/bin/mount --bind "$blocked" "$spool" +blocked_mounted=1 +$as_root /usr/bin/systemctl start "$service" wait_queue - -spool_mode=$($as_root /usr/bin/stat -c %a "$spool") -$as_root /usr/bin/chmod 000 "$spool" if $as_bongo "$queue_tool" message "$queue_id" \ >"$work/unreadable.out" 2>"$work/unreadable.err"; then echo "STQ-04: Queue read a deliberately unreadable spool" >&2 @@ -131,8 +127,11 @@ if ! grep -F "Can't read queue data" "$work/unreadable.err" >/dev/null; then sed -n '1,20p' "$work/unreadable.err" >&2 exit 1 fi -$as_root /usr/bin/chmod "$spool_mode" "$spool" -spool_mode= +$as_root /usr/bin/systemctl stop "$service" +$as_root /usr/bin/umount "$spool" +blocked_mounted=0 +$as_root /usr/bin/systemctl start "$service" +wait_queue $as_bongo "$queue_tool" message "$queue_id" >"$work/after-unreadable.eml" if ! cmp -s "$work/before.eml" "$work/after-full.eml" || @@ -150,6 +149,6 @@ if [ "$($as_root /usr/bin/systemctl is-active "$service")" != active ]; then exit 1 fi -printf 'STQ-04 PASS queue=%s sha256=%s full-reported=%s spool-mode=%s\n' \ +printf 'STQ-04 PASS queue=%s sha256=%s full-reported=%s tmpfs-bytes=%s\n' \ "$queue_id" "$after_hash" "$reported" \ - "$($as_root /usr/bin/stat -c %a "$spool")" + "$($as_root /usr/bin/stat -f -c %s "$spool")"