Files
bfe-core1106-sdk/tests/fetch-buildroot-tarball/run-fetch-buildroot-tarball-tests.sh
NoahandClaude Fable 5.1 2b6e8a2098 qemu and build: review fixes across the rig driver, boot script, and fetch helpers
Bounded waits and validated arguments in run.sh and ui-drive.sh, a seeded
settings directory and root-only staged rootfs permissions with their own
tests, qmp.py and imgtools.py hardening, the fetch scripts checking what they
download, and ASCII typography throughout. Each fix carries its test under
qemu/tests or tests/.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N3G6m9Aw5RyVY4ZowtKzEj
2026-09-09 19:17:54 -06:00

136 lines
4.6 KiB
Bash
Executable File

#!/usr/bin/env bash
# Regression tests for build/fetch-buildroot-tarball.sh's retry/verify path.
#
# The script had never been exercised by anything (nothing calls it yet --
# see its own header) or by a test, so its retry-on-mismatch, cleanup, and
# already-verified short-circuit had never actually run. It also fetched with
# no --connect-timeout/--max-time, so a connection that opens and then stalls
# (a blackholed route, a hung proxy) would block forever instead of retrying;
# issue tracked separately.
#
# Runs the real script (copied into a fixture dir so its own HERE-relative pin
# lookup finds a pin we control) with a fake curl first on PATH, so no network
# is used and the outcome of each attempt is exact.
set -uo pipefail
HERE="$(cd "$(dirname "$0")" && pwd)"
SCRIPT="$HERE/../../build/fetch-buildroot-tarball.sh"
[ -f "$SCRIPT" ] || { echo "FAIL: script not found at $SCRIPT"; exit 1; }
FAIL=0
ok() { printf '[PASS] %s\n' "$1"; }
bad() { printf '[FAIL] %s\n' "$1"; FAIL=1; }
TMP="$(mktemp -d)"
trap 'rm -rf "$TMP"' EXIT
WANT_SHA="$(printf 'good-bytes' | sha256sum | awk '{print $1}')"
# A private copy of the real script plus a pin file we control, in its own
# directory: the script resolves its pin relative to itself, so this is the
# shipping file under test, not a reimplementation of it.
setup() { # setup <case-name> -> prints the fixture dir
local dir="$TMP/$1"
mkdir -p "$dir/bin"
cp "$SCRIPT" "$dir/fetch-buildroot-tarball.sh"
printf '%s buildroot-2025.02.8.tar.xz\n' "$WANT_SHA" \
> "$dir/buildroot-2025.02.8.tar.xz.sha256"
printf '%s' "$dir"
}
run() { # run <dir> <dest> -> stdout+stderr on stdout, $? in $RC
local dir="$1" dest="$2"
OUT="$(PATH="$dir/bin:$PATH" bash "$dir/fetch-buildroot-tarball.sh" "$dest" 2>&1)"
RC=$?
}
# --- case A: destination already matches the pin -> curl never runs -------
dir="$(setup case-a)"
printf 'good-bytes' > "$dir/dest.tar.xz"
cat > "$dir/bin/curl" <<'FAKE'
#!/bin/sh
echo "curl should not have run" >&2
exit 1
FAKE
chmod +x "$dir/bin/curl"
run "$dir" "$dir/dest.tar.xz"
if [ "$RC" -eq 0 ] && printf '%s' "$OUT" | grep -q 'already present and verified'; then
ok "already-verified destination: curl never invoked"
else
bad "already-verified destination: curl never invoked (rc=$RC, out=$OUT)"
fi
# --- case B: fails once, succeeds on retry -> verified, no extra attempts -
dir="$(setup case-b)"
cat > "$dir/bin/curl" <<FAKE
#!/bin/sh
cnt_file="$dir/curl-calls"
n=0
[ -f "\$cnt_file" ] && n=\$(cat "\$cnt_file")
n=\$((n + 1))
echo "\$n" > "\$cnt_file"
out="" prev=""
for a in "\$@"; do
[ "\$prev" = "-o" ] && out="\$a"
prev="\$a"
done
if [ "\$n" -lt 2 ]; then printf 'bad-bytes' > "\$out"
else printf 'good-bytes' > "\$out"
fi
FAKE
chmod +x "$dir/bin/curl"
run "$dir" "$dir/dest.tar.xz"
calls="$(cat "$dir/curl-calls" 2>/dev/null || echo 0)"
if [ "$RC" -eq 0 ] && [ "$calls" -eq 2 ] && printf '%s' "$OUT" | grep -q 'sha256 verified'; then
ok "mismatch then match: verified on attempt 2, stops retrying"
else
bad "mismatch then match: verified on attempt 2, stops retrying (rc=$RC calls=$calls out=$OUT)"
fi
# --- case C: every attempt mismatches -> fails closed, no partial file left
dir="$(setup case-c)"
cat > "$dir/bin/curl" <<'FAKE'
#!/bin/sh
out="" prev=""
for a in "$@"; do
[ "$prev" = "-o" ] && out="$a"
prev="$a"
done
printf 'always-bad' > "$out"
FAKE
chmod +x "$dir/bin/curl"
run "$dir" "$dir/dest.tar.xz"
if [ "$RC" -ne 0 ] && printf '%s' "$OUT" | grep -q 'FATAL: could not fetch'; then
ok "persistent mismatch: exits nonzero with FATAL"
else
bad "persistent mismatch: exits nonzero with FATAL (rc=$RC, out=$OUT)"
fi
if [ ! -e "$dir/dest.tar.xz" ]; then
ok "persistent mismatch: no partial/corrupt tarball left at the destination"
else
bad "persistent mismatch: no partial/corrupt tarball left at the destination"
fi
attempts="$(printf '%s' "$OUT" | grep -c '== fetching')"
if [ "$attempts" -eq 3 ]; then
ok "persistent mismatch: exactly 3 attempts"
else
bad "persistent mismatch: exactly 3 attempts (got $attempts)"
fi
# --- guard: the fetch carries a connect and overall timeout ---------------
# Without these, --retry never fires (it only re-attempts a transfer curl has
# already decided failed) and a connection that opens then stalls blocks
# forever -- exactly the routing failure this workspace sees from some hosts.
if grep -q -- '--connect-timeout' "$SCRIPT" && grep -q -- '--max-time' "$SCRIPT"; then
ok "fetch carries --connect-timeout and --max-time"
else
bad "fetch carries --connect-timeout and --max-time"
fi
if [ "$FAIL" -eq 0 ]; then
echo "ALL FETCH-BUILDROOT-TARBALL TESTS PASSED"
else
echo "FETCH-BUILDROOT-TARBALL TESTS FAILED"
fi
exit "$FAIL"