Initialize repository snapshot
This commit is contained in:
110
tools/run_sentinel_testvectors.sh
Executable file
110
tools/run_sentinel_testvectors.sh
Executable file
@@ -0,0 +1,110 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
VERIFIER="$ROOT/tools/vm_verify_sentinel_bundle.py"
|
||||
TV_DIR="$ROOT/testvectors/sentinel"
|
||||
|
||||
if [[ ! -x "$VERIFIER" && ! -f "$VERIFIER" ]]; then
|
||||
echo "[ERROR] Verifier not found: $VERIFIER" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
if [[ ! -d "$TV_DIR" ]]; then
|
||||
echo "[ERROR] Testvector directory not found: $TV_DIR" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
expected_exit_for() {
|
||||
case "$1" in
|
||||
black-box-that-refused) echo 0 ;;
|
||||
rollback-duplicate-seq) echo 1 ;;
|
||||
corruption-truncated-jsonl) echo 1 ;;
|
||||
revocation-used-after-revoke) echo 1 ;;
|
||||
integrity-size-mismatch) echo 1 ;;
|
||||
*) echo "" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
expected_code_for() {
|
||||
case "$1" in
|
||||
rollback-duplicate-seq) echo "E_SEQ_NON_MONOTONIC" ;;
|
||||
corruption-truncated-jsonl) echo "E_SCHEMA_INVALID" ;;
|
||||
revocation-used-after-revoke) echo "E_REVOKED_CAPABILITY_USED" ;;
|
||||
integrity-size-mismatch) echo "E_MANIFEST_HASH_MISMATCH" ;;
|
||||
*) echo "" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
missing=0
|
||||
|
||||
for dir in "$TV_DIR"/*; do
|
||||
[[ -d "$dir" ]] || continue
|
||||
name="$(basename "$dir")"
|
||||
|
||||
expected_exit="$(expected_exit_for "$name")"
|
||||
if [[ -z "$expected_exit" ]]; then
|
||||
echo "[ERROR] Unknown testvector: $name" >&2
|
||||
missing=1
|
||||
continue
|
||||
fi
|
||||
|
||||
report1="$(mktemp)"
|
||||
report2="$(mktemp)"
|
||||
|
||||
set +e
|
||||
python3 "$VERIFIER" --bundle "$dir" --strict --report "$report1" >/dev/null 2>/dev/null
|
||||
status=$?
|
||||
set -e
|
||||
|
||||
if [[ "$status" -ne "$expected_exit" ]]; then
|
||||
echo "[FAIL] $name: exit=$status expected=$expected_exit" >&2
|
||||
python3 "$VERIFIER" --bundle "$dir" --strict --report "$report1" >&2 || true
|
||||
exit 1
|
||||
fi
|
||||
|
||||
failure_code="$(python3 -c "import json; p='$report1'; fc=json.load(open(p,'r',encoding='utf-8')).get('failure_code'); print('' if fc is None else fc)")"
|
||||
|
||||
if [[ "$expected_exit" -eq 0 ]]; then
|
||||
if [[ -n "$failure_code" ]]; then
|
||||
echo "[FAIL] $name: expected PASS but failure_code=$failure_code" >&2
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
expected_code="$(expected_code_for "$name")"
|
||||
if [[ -z "$expected_code" ]]; then
|
||||
echo "[ERROR] Missing EXPECT_CODE mapping for failing vector: $name" >&2
|
||||
exit 2
|
||||
fi
|
||||
if [[ "$failure_code" != "$expected_code" ]]; then
|
||||
echo "[FAIL] $name: failure_code=$failure_code expected=$expected_code" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Determinism: same inputs -> byte-identical report.
|
||||
set +e
|
||||
python3 "$VERIFIER" --bundle "$dir" --strict --report "$report2" >/dev/null 2>/dev/null
|
||||
status2=$?
|
||||
set -e
|
||||
|
||||
if [[ "$status2" -ne "$expected_exit" ]]; then
|
||||
echo "[FAIL] $name: second run exit=$status2 expected=$expected_exit" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! cmp -s "$report1" "$report2"; then
|
||||
echo "[FAIL] $name: report is not deterministic" >&2
|
||||
diff -u "$report1" "$report2" | head -n 200 >&2 || true
|
||||
exit 1
|
||||
fi
|
||||
|
||||
rm -f "$report1" "$report2"
|
||||
echo "[OK] $name"
|
||||
done
|
||||
|
||||
if [[ "$missing" -ne 0 ]]; then
|
||||
exit 2
|
||||
fi
|
||||
|
||||
echo "[OK] All Sentinel testvectors verified"
|
||||
Reference in New Issue
Block a user