#!/bin/sh # # Verify that a simulated full Queue filesystem rejects new submissions and # that an unreadable spool defers access without changing an existing message. set -eu queue_tool=${BONGO_QUEUE_TOOL:-/usr/bin/bongo-queuetool} service=${BONGO_SERVICE:-bongo.service} spool=${BONGO_QUEUE_SPOOL:-/var/lib/bongo/spool} run_as=${BONGO_TEST_RUN_AS:-bongo} as_root=${BONGO_TEST_AS_ROOT:-sudo -n} if [ "$(id -un)" = "$run_as" ]; then as_bongo= else as_bongo="sudo -n -u $run_as" 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= tmpfs_mounted=0 spool_mounted=0 blocked_mounted=0 fill_open=0 restore() { status=$? if [ "$fill_open" -eq 1 ]; then exec 9>&- fill_open=0 fi $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 [ "$spool_mounted" -eq 1 ]; then $as_root /usr/bin/umount "$spool" >/dev/null 2>&1 || true fi 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" } trap restore EXIT HUP INT TERM wait_queue() { attempts=30 while [ "$attempts" -gt 0 ]; do if $as_bongo "$queue_tool" space >/dev/null 2>&1; then return 0 fi attempts=$((attempts - 1)) sleep 1 done echo "STQ-04: Queue did not become ready after service restart" >&2 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' \ 'Subject: STQ-04 retained queue fixture' \ 'Date: Thu, 23 Jul 2026 12:34:56 +0200' \ 'Message-ID: ' \ '' \ 'This exact message must survive both simulated failures.' \ >"$work/message.eml" chmod 0644 "$work/message.eml" queue_id=$($as_bongo "$queue_tool" hold-local "$work/message.eml" 9) $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) reported_before=$4 block=$5 fill_blocks=$((reported_before / block + 1)) exec 9>"$tmpfs/.stq04-fill" fill_open=1 rm "$tmpfs/.stq04-fill" /usr/bin/dd if=/dev/zero bs="$block" count="$fill_blocks" status=none >&9 $as_root /usr/bin/systemctl restart "$service" wait_queue reported=$($as_bongo "$queue_tool" space) if [ "$reported" -ne 0 ]; then echo "STQ-04: simulated full spool reported $reported usable bytes" >&2 exit 1 fi if $as_bongo "$queue_tool" hold-local "$work/message.eml" \ >"$work/full.out" 2>"$work/full.err"; then echo "STQ-04: Queue accepted a message below its free-space reserve" >&2 exit 1 fi if ! grep -F 'Free disk space too low' "$work/full.err" >/dev/null; then echo "STQ-04: full-spool rejection did not report the expected error" >&2 sed -n '1,20p' "$work/full.err" >&2 exit 1 fi $as_bongo "$queue_tool" message "$queue_id" >"$work/after-full.eml" exec 9>&- fill_open=0 $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 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 exit 1 fi if ! grep -F "Can't read queue data" "$work/unreadable.err" >/dev/null; then echo "STQ-04: unreadable spool did not report the expected error" >&2 sed -n '1,20p' "$work/unreadable.err" >&2 exit 1 fi $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" || ! cmp -s "$work/before.eml" "$work/after-unreadable.eml"; then echo "STQ-04: retained Queue message changed during a failure" >&2 exit 1 fi after_hash=$(sha256sum "$work/after-unreadable.eml" | awk '{ print $1 }') if [ "$before_hash" != "$after_hash" ]; then echo "STQ-04: retained Queue message digest changed" >&2 exit 1 fi if [ "$($as_root /usr/bin/systemctl is-active "$service")" != active ]; then echo "STQ-04: Bongo service is not active after recovery" >&2 exit 1 fi 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 -f -c %s "$spool")"