Files
bongo/contrib/testing/queue-failure-safety-check.sh
T
Mario Fetka ffd0e4d4f3
Debian Trixie package bundle / packages (push) Successful in 21m34s
Use recoverable target in STQ-04 fixture
2026-07-23 09:29:32 +02:00

164 lines
4.9 KiB
Bash
Executable File

#!/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 <stq04@bongo.test>' \
'To: stqqueue@bongo.test' \
'Subject: STQ-04 retained queue fixture' \
'Date: Thu, 23 Jul 2026 12:34:56 +0200' \
'Message-ID: <stq04-retained@bongo.test>' \
'' \
'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")"