zupt/tests/test_audit_flake.sh
Cristian Cezar Moisés 544a2cd647
Some checks failed
CI / build-and-test (clang) (push) Has been cancelled
CI / build-and-test (gcc) (push) Has been cancelled
CI / strict-warnings (clang, -Wall -Wextra -Wpedantic -Wshadow -Wcast-align -Wstrict-prototypes -Wmissing-prototypes -Wnull-dereference -O2 -std=c11 -Werror) (push) Has been cancelled
CI / strict-warnings (gcc, -Wall -Wextra -Wpedantic -Wshadow -Wcast-align -Wstrict-prototypes -Wmissing-prototypes -Wnull-dereference -Wformat-security -Wlogical-op -Wjump-misses-init -Wdouble-promotion -O2 -std=c11 -Werror) (push) Has been cancelled
CI / sanitizers (push) Has been cancelled
CI / pie-hardening (push) Has been cancelled
CI / cross-aarch64 (push) Has been cancelled
CI / dist-reproducibility (push) Has been cancelled
CI / packaging-syntax (push) Has been cancelled
CI / release (push) Has been cancelled
v4.0.0: codec 2.60.4 security release, --pq-box sealed-box mode, F-16 fix
Major release. Highlights:

- Codec: vendored VaptVupt codec moves to canonical 2.60.4 security
  release. Fixes a high-severity OOB heap write in the AVX2 decode fast
  path (reachable on a valid stream sized to exactly content_size, both
  tail variants). Brings CBMC-formally-verified BCJ filters with
  automatic ELF/PE/Mach-O detection. Compressed output stays
  byte-identical (ratio gate Δ 0.00%); wire format unchanged at v1.6.
- New --pq-box sealed-box recipient mode (vendored libpqvaptvupt 0.6.0):
  ML-KEM-768 + X25519 combined via HKDF-SHA256 with domain separation,
  AES-256-CTR + HMAC-SHA256 EtM. Legacy --pq and --pq-sdk stay readable.
- F-16: discloses and fixes a pre-existing data-loss defect in the
  <= 3.8.0 in-tree BCJ encoder. Full back-compat matrix decodes
  byte-exact under 4.0.0; every readable pre-4.0 archive remains readable.

Repository hygiene:
- Sync full 4.0.0 source tree (codec, crypto, SDK, GUI, packaging, tests).
- Remove internal scratch files (PROMPT.md, FORMAL_AUDIT_PROMPT.md)
  and superseded version-specific docs (INTEGRATION_PROTOCOL_2.60.4.md,
  docs/FINDINGS-2.x.md) and a stray test binary.
- Refresh README download/install section to real 4.0.0 release assets;
  bump version badge to 4.0.0.
- Add .gitignore for build outputs (keeps vendored prebuilt libraries).
2026-06-10 18:48:58 -03:00

85 lines
3.4 KiB
Shell
Executable file
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# SPDX-License-Identifier: AGPL-3.0-or-later
# Copyright (c) 2025-2026 Cristian Cezar Moisés
#
# Flake-stress harness — §3 of PROMPT.md.
#
# Runs every short test suite N times (default 50) and aborts on the
# first non-deterministic outcome. Specifically targeted at the audit
# suite, which historically flaked when archive-size variance caused a
# byte-position-based tamper to land in unauthenticated bytes
# (finding F-02 in docs/FINDINGS-2.x.md).
#
# Usage: bash tests/test_audit_flake.sh [N]
#
# Exit codes:
# 0 — all N runs of every targeted suite passed identically.
# 1 — at least one run differed (test is flaky). Output names the run.
set -u
# Default N=20 across 5 suites (~10 min). Pass an arg to override.
# F-02's repro needed 50 runs to be statistically convincing (~10%
# baseline flake rate), but at 20 runs we still have ~88% chance of
# catching a 10%-flake — fine for routine CI. For a hardened audit
# pass, invoke with 50 or 100 (see PROMPT.md §3).
N="${1:-20}"
ZUPT_BIN="${ZUPT_BIN:-./zupt}"
if [ ! -x "$ZUPT_BIN" ]; then
echo "$ZUPT_BIN not found or not executable. Run 'make' first." >&2
exit 1
fi
run_suite() {
local name="$1"; shift
local cmd="$*"
local pass=0 fail=0 i first_failed_log=""
echo ""
echo " ─── $name × $N ───"
for i in $(seq 1 "$N"); do
local out
out=$(bash -c "$cmd" 2>&1)
# The convention used by every short suite under tests/ is to
# finish with "<N> passed, 0 failed" when the suite is green.
if echo "$out" | grep -qE '[0-9]+ passed, 0 failed'; then
pass=$((pass+1))
else
fail=$((fail+1))
if [ -z "$first_failed_log" ]; then
first_failed_log=$(mktemp)
printf '%s\n' "$out" > "$first_failed_log"
fi
fi
done
if [ "$fail" -eq 0 ]; then
echo "$name: $pass/$N green (deterministic)"
return 0
else
echo "$name: $pass passed, $fail failed — FLAKY"
echo " First failing run captured at: $first_failed_log"
echo " --- first 30 lines of failing output ---"
head -30 "$first_failed_log" | sed 's/^/ /'
return 1
fi
}
GLOBAL_FAIL=0
run_suite "tests/test_audit.sh" "bash tests/test_audit.sh" || GLOBAL_FAIL=1
run_suite "tests/test_path_traversal.sh" "bash tests/test_path_traversal.sh" || GLOBAL_FAIL=1
run_suite "tests/test_arg_order.sh" "bash tests/test_arg_order.sh" || GLOBAL_FAIL=1
run_suite "tests/test_block_swap.sh" "bash tests/test_block_swap.sh" || GLOBAL_FAIL=1
run_suite "tests/test_dedup_props.sh" "bash tests/test_dedup_props.sh" || GLOBAL_FAIL=1
echo ""
if [ "$GLOBAL_FAIL" -eq 0 ]; then
echo " ═══════════════════════════════════════════"
echo " Flake-stress PASS — $N runs × 5 suites all deterministic"
echo " ═══════════════════════════════════════════"
exit 0
else
echo " ═══════════════════════════════════════════"
echo " Flake-stress FAIL — see captured log above"
echo " ═══════════════════════════════════════════"
exit 1
fi