mirror of
https://github.com/rustfs/rustfs.git
synced 2026-07-26 16:28:15 +00:00
b9e5e818a9
ci: count migration-gate tests via nextest JSON, not human-format indentation The count-floor guard (#4673) parsed nextest's human list format with grep -c '^ '. CI's newer nextest emits a different indentation, so the count collapsed to 0 and the gate failed on every PR based on current main (first observed on #4683, then #4674/#4677/#4680). Count via --message-format json + jq instead, which is stable across versions, and fail loudly if the JSON shape ever changes.
86 lines
3.9 KiB
Bash
Executable File
86 lines
3.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Count-floor guard for the migration-critical test gate (backlog#1153 infra-12).
|
|
#
|
|
# ci.yml's migration gate selects tests BY NAME SUBSTRING. A rename that drops
|
|
# a test out of the filter silently thins the gate — potentially to zero —
|
|
# without any CI signal (this is how the layered gate died when #878 closed).
|
|
# This script owns the filter expression so the count check and the test run
|
|
# cannot drift, and fails fast when the number of selected tests drops below
|
|
# the committed floor in .config/migration-gate-floor.txt.
|
|
#
|
|
# NAMING CONVENTION DEPENDENCY: migration-gate tests are matched by these
|
|
# reserved name substrings:
|
|
#
|
|
# data_movement, rebalance, decommission, source_cleanup, delete_marker
|
|
#
|
|
# Renaming a test away from all of these substrings removes it from the gate.
|
|
# The floor equals the exact selected-test count at the time it was last
|
|
# committed, so ANY reduction fails CI. To shrink the gate intentionally
|
|
# (test removed or consciously renamed), update the floor file in the same PR
|
|
# so the reduction is visible in the diff. Adding tests never requires a floor
|
|
# bump (the floor is a lower bound), but bumping it keeps the guard tight.
|
|
#
|
|
# Per-pattern floors are deliberately omitted: with an exact-count total floor,
|
|
# a single test dropping out of any pattern already fails the check, so
|
|
# per-pattern bookkeeping would add churn without detection power.
|
|
#
|
|
# Usage:
|
|
# scripts/check_migration_gate_count.sh # count check + run the gate
|
|
# scripts/check_migration_gate_count.sh check # count check only
|
|
# scripts/check_migration_gate_count.sh run # run the gate only
|
|
|
|
set -euo pipefail
|
|
|
|
cd "$(dirname "$0")/.."
|
|
|
|
# Single source of truth for the migration-gate filter. ci.yml must invoke
|
|
# this script instead of inlining the expression.
|
|
MIGRATION_GATE_FILTER='test(data_movement) or test(rebalance) or test(decommission) or test(source_cleanup) or test(delete_marker)'
|
|
FLOOR_FILE=".config/migration-gate-floor.txt"
|
|
|
|
mode="${1:-all}"
|
|
case "$mode" in
|
|
all | check | run) ;;
|
|
*)
|
|
echo "usage: $0 [all|check|run]" >&2
|
|
exit 2
|
|
;;
|
|
esac
|
|
|
|
if [[ "$mode" == "all" || "$mode" == "check" ]]; then
|
|
floor="$(grep -Ev '^[[:space:]]*(#|$)' "$FLOOR_FILE" | head -n1 | tr -d '[:space:]')"
|
|
if ! [[ "$floor" =~ ^[0-9]+$ ]]; then
|
|
echo "error: $FLOOR_FILE does not contain a numeric floor (got: '$floor')" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Count via the structured JSON listing, not the human format: the
|
|
# human format's indentation varies across nextest versions (CI's newer
|
|
# nextest emitted a layout where no line matched '^ ', collapsing the
|
|
# count to 0 and failing every PR). A nextest failure aborts via set -e
|
|
# with its stderr visible; a JSON schema change makes jq fail loudly
|
|
# rather than silently passing.
|
|
count="$(cargo nextest list -p rustfs-ecstore --lib -E "$MIGRATION_GATE_FILTER" --message-format json \
|
|
| jq '[."rust-suites"[].testcases[] | select(."filter-match".status == "matches")] | length')"
|
|
if ! [[ "$count" =~ ^[0-9]+$ ]]; then
|
|
echo "error: could not parse nextest JSON listing (got count: '$count')" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if ((count < floor)); then
|
|
echo "error: migration gate selects $count tests, below the committed floor of $floor." >&2
|
|
echo "" >&2
|
|
echo "The gate matches tests by name substring (data_movement / rebalance /" >&2
|
|
echo "decommission / source_cleanup / delete_marker). A rename or removal has" >&2
|
|
echo "thinned the selection. Either restore the test names, or — if the" >&2
|
|
echo "reduction is intentional — update $FLOOR_FILE in this PR so the" >&2
|
|
echo "gate change is explicit and reviewable." >&2
|
|
exit 1
|
|
fi
|
|
echo "migration gate count OK: $count selected tests (floor: $floor)"
|
|
fi
|
|
|
|
if [[ "$mode" == "all" || "$mode" == "run" ]]; then
|
|
cargo nextest run -p rustfs-ecstore --lib -E "$MIGRATION_GATE_FILTER"
|
|
fi
|