From ea257da77ad6144cc1ad89606cf823fa62adc12a Mon Sep 17 00:00:00 2001 From: pat-s Date: Mon, 31 Aug 2026 12:55:51 +0000 Subject: [PATCH] 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. --- scripts/verify-r-minor-routing.sh | 32 ++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/scripts/verify-r-minor-routing.sh b/scripts/verify-r-minor-routing.sh index 3957f67..2192cdc 100755 --- a/scripts/verify-r-minor-routing.sh +++ b/scripts/verify-r-minor-routing.sh @@ -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