- §7 step 4 as the text stands: a refinement of the pick is one whose refines.base, read
on its own, is the pick's id (container::refinements_naming, refinements_naming in
http_verify.py), so one whose refines is otherwise malformed is reported dropped
(components_nonconforming). Of a conforming envelope the set is the same as before.
- Objects OCF (ONC's conforming twin: refinements [2], dropped []), ONM (refines
{base: b} alone: reported) and ONX (refines {base: x}: not reported), on the whole and
the range paths; fetch_OR_malformed_refines now reports its refinement; the generator
checks each outcome.
- falsify: conforming-withheld and refines-read-whole, each with an http_verify.py
--mutate, wired into falsify/run.sh; nonconforming-offered's must-fail list extended.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
74 lines
4.1 KiB
Shell
Executable file
74 lines
4.1 KiB
Shell
Executable file
#!/usr/bin/env bash
|
|
# Falsify the HTTP corpus tool: each patch here breaks one function of wai-rs. For each,
|
|
# in a fresh worktree of HEAD: apply it, require the build to succeed, and require
|
|
# `wai_http_vectors verify` to exit non-zero and to name every case the patch's first
|
|
# line lists. Then the Python side: each `http_verify.py --mutate` must fail, and the
|
|
# differential must verify every proof and refuse exactly the flipped ones.
|
|
#
|
|
# bash wai/http-conformance/falsify/run.sh [work-dir [patch-name…]]
|
|
#
|
|
# With patch names, only those patches run (and nothing else).
|
|
# Run from the repository root. CARGO_TARGET_DIR, if set, is shared by the builds, which
|
|
# need the features http and video_manifest (the playlist receipts).
|
|
set -uo pipefail
|
|
ROOT="$(git rev-parse --show-toplevel)"
|
|
WORK="${1:-${RUNNER_TEMP:-/tmp}/wai-http-falsify}"
|
|
shift || true
|
|
ONLY="$*"
|
|
mkdir -p "$WORK"
|
|
fail=0
|
|
for patch in "$ROOT"/wai/http-conformance/falsify/*.patch; do
|
|
name="$(basename "$patch" .patch)"
|
|
if [ -n "$ONLY" ] && ! printf ' %s ' $ONLY | grep -q " $name "; then continue; fi
|
|
wt="$WORK/f-$name"
|
|
rm -rf "$wt"
|
|
git -C "$ROOT" worktree add --detach --quiet "$wt" HEAD
|
|
must="$(head -1 "$patch" | sed 's/^# must fail: //')"
|
|
if ! git -C "$wt" apply "$patch"; then
|
|
echo "::error::$name: the patch does not apply"; fail=1
|
|
elif ! (cd "$wt/wai/wai-rs" && cargo build --release --no-default-features --features http,video_manifest --bin wai_http_vectors) > "$WORK/$name.build.log" 2>&1; then
|
|
echo "::error::$name: the patched tree does not build"; tail -20 "$WORK/$name.build.log"; fail=1
|
|
else
|
|
bin="${CARGO_TARGET_DIR:-$wt/wai/wai-rs/target}/release/wai_http_vectors"
|
|
"$bin" verify "$wt/wai/http-conformance" > "$WORK/$name.verify.log" 2>&1
|
|
rc=$?
|
|
missing=""
|
|
for c in $must; do grep -q "^FAIL $c:" "$WORK/$name.verify.log" || missing="$missing $c"; done
|
|
if [ $rc -eq 0 ] || [ -n "$missing" ]; then
|
|
echo "::error::$name: verify exited $rc; cases not failed:$missing"; fail=1
|
|
else
|
|
echo "ok $name: verify exited $rc and failed$(printf ' %s' $must) ($(grep -c '^FAIL' "$WORK/$name.verify.log") failures)"
|
|
fi
|
|
fi
|
|
git -C "$ROOT" worktree remove --force "$wt"
|
|
done
|
|
|
|
[ -n "$ONLY" ] && exit $fail
|
|
cd "$ROOT/wai/http-conformance"
|
|
for m in left-half no-root counter-zero floor-as-codecs blake3-iv base-at-done tick-noop refinement-unclipped \
|
|
pdt-ignored dseq-ignored parts-after-extinf average-floor render-digest-off name-unchecked chain-unchecked \
|
|
ilog2-no-interp bola-waits unlabelled-as-zero round-half-down small-order-key small-order-r \
|
|
rebind-uri rebind-sequence key-unchecked walk-unbounded reload-walked \
|
|
xml-char-unchecked xml-attribute-twice dash-start-ignored dash-timescale-ignored \
|
|
unlabelled-escapes abr-unbounded gap-carries receipt-duplicates receipt-surrogates session-data-anywhere \
|
|
dash-r-expanded xml-attributes-scanned dash-timelines-unbounded budget-raises \
|
|
uri-unresolved gap-withdraws reanchor-backwards walk-exceeded-wedges walk-name-unchecked walk-verify-unchecked bindings-unbounded \
|
|
file-numbers-unbounded nonconforming-offered conforming-withheld refines-read-whole; do
|
|
if python3 http_verify.py . --mutate "$m" > "$WORK/py-$m.log" 2>&1; then
|
|
echo "::error::http_verify.py --mutate $m passed"; fail=1
|
|
else
|
|
echo "ok http_verify.py --mutate $m: $(grep -c '^FAIL' "$WORK/py-$m.log") failures"
|
|
fi
|
|
done
|
|
# The differential runs the unpatched tool: build it again (the patched builds shared
|
|
# its output path).
|
|
(cd "$ROOT/wai/wai-rs" && cargo build --release --no-default-features --features http,video_manifest --bin wai_http_vectors) > "$WORK/unpatched.build.log" 2>&1 || fail=1
|
|
bin="${CARGO_TARGET_DIR:-$ROOT/wai/wai-rs/target}/release/wai_http_vectors"
|
|
if [ -x "$bin" ]; then
|
|
"$bin" diff . --seed 7 --count 500 --out "$WORK/diff.jsonl" > /dev/null || fail=1
|
|
python3 http_verify.py diff "$WORK/diff.jsonl" || fail=1
|
|
python3 http_verify.py diff "$WORK/diff.jsonl" --flip 10 --seed 3 || fail=1
|
|
else
|
|
echo "::error::no release wai_http_vectors at $bin for the differential"; fail=1
|
|
fi
|
|
exit $fail
|