test(verify): follow redirects, and allow the guard's deliberate drops

Two checks that no longer matched the system.

fetch() did not pass -L, so every --live check against a routed index read
a 302 body instead of the index a client receives. It also did not bypass
the edge, so a run right after a reindex measured stale copies. Both were
fixed on the branch behind #180 but the merge captured that PR at an
earlier commit, so neither reached main.

The union check asserted flat is a subset of every per-minor index. Since
bincraft learned to drop an ABI-risky package whose only binary was built
under another R minor, that is deliberately false: amd64/resolute drops
2228 from its 4.6 index, and those absences are the fix working.

What must never go missing is a generic package built under this very
minor - safe to serve, no reason to disappear. That is what it now
asserts, reporting the deliberate drops alongside.
This commit is contained in:
Patrick Schratz 2026-08-31 12:55:51 +00:00
commit ea257da77a
No known key found for this signature in database
GPG key ID: 62050D5BC68AB6DC

View file

@ -104,10 +104,15 @@ fetch() {
return 0
fi
local status
# -L: the router answers an index request with a redirect, so the bytes a
# client ends up with are only visible by following it.
#
# no-cache: a purge is asynchronous, so a run started right after a reindex
# otherwise measures whatever the edge still holds.
if [ -n "$ua" ]; then
status=$(curl -sS -A "$ua" -o "$dest" -w '%{http_code}' --max-time 120 "$url" 2>/dev/null)
status=$(curl -sSL -A "$ua" -H 'Cache-Control: no-cache' -o "$dest" -w '%{http_code}' --max-time 120 "$url" 2>/dev/null)
else
status=$(curl -sS -o "$dest" -w '%{http_code}' --max-time 120 "$url" 2>/dev/null)
status=$(curl -sSL -H 'Cache-Control: no-cache' -o "$dest" -w '%{http_code}' --max-time 120 "$url" 2>/dev/null)
fi
echo "$status" > "$dest.status"
echo "$status"
@ -214,12 +219,25 @@ for arch in $ARCHES; do
minor_count=$(wc -l < "$minor_file.names")
# Union property: nothing the flat index carries may be missing here.
missing=$(comm -23 "$flat_file.names" "$minor_file.names" | head -5)
missing_count=$(comm -23 "$flat_file.names" "$minor_file.names" | wc -l)
if [ "$missing_count" -ne 0 ]; then
bad "$slot R $minor index is not a union: $missing_count flat packages absent (e.g. $(echo "$missing" | tr '\n' ' '))"
# bincraft deliberately drops an ABI-risky package whose only binary was
# built under another R minor: serving it is the load-time crash the
# per-minor slots exist to prevent. Those absences are correct.
#
# What must never go missing is a generic package built under *this*
# minor, which is safe to serve and has no reason to disappear.
comm -23 "$flat_file.names" "$minor_file.names" > "$minor_file.absent"
absent_count=$(wc -l < "$minor_file.absent")
gunzip -c "$flat_file" 2>/dev/null | awk -v m="$minor" '
/^Package:/ { pkg = $2; built = "" }
/^Built:/ { built = $2 " " $3 }
/^$/ { if (pkg != "" && built ~ ("^R " m "\\.")) print pkg; pkg = "" }
' | sort -u > "$minor_file.flatsame"
lost=$(comm -12 "$minor_file.absent" "$minor_file.flatsame" | wc -l)
if [ "${lost:-0}" -ne 0 ]; then
bad "$slot R $minor index dropped $lost generic package(s) built under R $minor, which were safe to serve"
else
ok "$slot R $minor index: $minor_count packages, union holds"
ok "$slot R $minor index: $minor_count packages, union holds ($absent_count ABI-unsafe dropped)"
fi
# A per-minor entry that is a source fallback resolves fine but makes the