#!/usr/bin/env bash # LLVM source-coverage for the p2p-intel engine crates, with an enforced floor. # # Same design as tools/test-pdf-coverage.sh: coverage that is only ever # *printed* drifts down, so this fails the build rather than reporting. # # What is measured: the five pure-Rust crates plus the Makepad view model. # What is not: `p2p-makepad/src/dashboard.rs` and the app binary, which need # a GPU and a windowing backend. That exclusion is the reason the view model # is a separate file — see the module docs there. Excluding a file you have # not first emptied of logic is how `spreadsheet-ui/grid.rs` hid 36 pure # functions behind a file-level skip. # # Usage: # ./tools/test-p2p-coverage.sh # enforce the floor # P2P_COVERAGE_REPORT_ONLY=1 ./tools/test-p2p-coverage.sh # # Runs entirely inside one temporary directory: its own rustup, cargo home # and target dir, all removed on exit. set -Eeuo pipefail IFS=$'\n\t' ROOT="$(CDPATH= cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)" TOOLCHAIN="${RUST_TOOLCHAIN:-1.97.1}" SRC="$ROOT/crates/apps/p2p-intel" # Measured at 93.9% of lines (excluding the CLI shell) when written. TOTAL_FLOOR="${P2P_COVERAGE_TOTAL_FLOOR:-90}" # Per-file floors for the files that carry a decision. A single whole-stack # number hides the failure this exists to catch: spread.rs could fall to 5% # while the total moves a point, because the total is dominated by types.rs. PER_FILE_FLOORS="${P2P_COVERAGE_PER_FILE_FLOORS:-\ p2p-core/src/types.rs:90 p2p-core/src/config.rs:95 p2p-analyzer/src/spread.rs:96 p2p-tracker/src/inventory.rs:94 p2p-tracker/src/trade.rs:94 p2p-scanner/src/parser.rs:91 p2p-alerter/src/lib.rs:95 p2p-makepad/src/view_model.rs:93 p2p-makepad/src/chime.rs:95 p2p-scanner/src/client.rs:90 p2p-core/src/drift.rs:95 p2p-alerter/src/notify.rs:95 p2p-analyzer/src/rail.rs:88 p2p-analyzer/src/panel.rs:95 p2p-analyzer/src/deal_bridge.rs:95}" WORK="$(mktemp -d "${TMPDIR:-/tmp}/p2p-coverage.XXXXXXXX")" cleanup() { local status=$? if [ "${KEEP_TEST_ENV:-0}" = "1" ]; then printf 'kept coverage environment at %s\n' "$WORK" >&2 else chmod -R u+w "$WORK" 2>/dev/null || true rm -rf "$WORK" fi exit "$status" } trap cleanup EXIT HUP INT TERM export RUSTUP_HOME="$WORK/rustup" export CARGO_HOME="$WORK/cargo" export CARGO_TARGET_DIR="$WORK/target" export PATH="$CARGO_HOME/bin:$PATH" export LLVM_PROFILE_FILE="$WORK/profiles/%p-%m.profraw" export RUSTFLAGS="-C instrument-coverage -C codegen-units=1 -C opt-level=0" mkdir -p "$WORK/profiles" printf 'installing Rust %s with llvm-tools\n' "$TOOLCHAIN" curl --fail --silent --show-error --location https://sh.rustup.rs -o "$WORK/rustup-init" chmod 700 "$WORK/rustup-init" "$WORK/rustup-init" -y --profile minimal --default-toolchain "$TOOLCHAIN" \ --component llvm-tools-preview --no-modify-path >/dev/null printf 'running the p2p-intel suites under instrumentation\n' # --workspace without --features ui: the dashboard widget and the app binary # need a GPU. Everything with a decision in it is in the default feature set. cargo test --manifest-path "$SRC/Cargo.toml" --workspace \ >"$WORK/test.log" 2>&1 || { cat "$WORK/test.log"; exit 1; } grep -E 'test result' "$WORK/test.log" | tail -20 HOST="$(rustc -vV | sed -n 's/^host: //p')" LLVM_BIN="$RUSTUP_HOME/toolchains/$TOOLCHAIN-$HOST/lib/rustlib/$HOST/bin" "$LLVM_BIN/llvm-profdata" merge -sparse "$WORK/profiles"/*.profraw \ -o "$WORK/coverage.profdata" mapfile -t BINARIES < <( find "$CARGO_TARGET_DIR/debug/deps" -maxdepth 1 -type f -executable \ ! -name '*.d' ! -name '*.so' | sort ) OBJECTS=() for bin in "${BINARIES[@]}"; do OBJECTS+=(-object "$bin") done if [ "${#OBJECTS[@]}" -eq 0 ]; then echo 'no instrumented binaries were produced' >&2 exit 1 fi # Only the crates' own `src/` trees count. `dashboard.rs` is excluded here # because it cannot be reached without a windowing backend. # `p2p-cli/src/main.rs` is excluded and measures 0%: it is argument # parsing and println, and every decision it makes is delegated to a # library crate that is measured. This exclusion is only defensible # because the file was kept empty of logic — the moment a rule moves # into it, it must come out of this list. IGNORE='(/cargo/registry|/cargo/git|/rustc/|/tests/|/src/bin/|dashboard\.rs|p2p-cli/src/main\.rs)' printf '\n=== per-file coverage ===\n' "$LLVM_BIN/llvm-cov" report "${OBJECTS[@]}" \ -instr-profile="$WORK/coverage.profdata" \ -ignore-filename-regex="$IGNORE" \ | tee "$WORK/report.txt" TOTAL_LINE="$(grep -E '^TOTAL' "$WORK/report.txt" | tail -1)" TOTAL_COVER="$(echo "$TOTAL_LINE" | awk '{print $(NF-3)}' | tr -d '%')" printf '\ntotal line coverage: %s%% (floor %s%%)\n' "$TOTAL_COVER" "$TOTAL_FLOOR" if [ "${P2P_COVERAGE_REPORT_ONLY:-0}" = "1" ]; then echo 'report-only mode: the floor was not enforced' exit 0 fi FAILED=0 awk -v floor="$TOTAL_FLOOR" -v got="$TOTAL_COVER" 'BEGIN { exit !(got+0 < floor+0) }' \ && { printf 'FAIL: total %s%% is below the %s%% floor\n' "$TOTAL_COVER" "$TOTAL_FLOOR" >&2; FAILED=1; } while IFS= read -r entry; do [ -z "$entry" ] && continue file="${entry%:*}" floor="${entry##*:}" line="$(grep -F "$file" "$WORK/report.txt" | tail -1 || true)" if [ -z "$line" ]; then printf 'FAIL: %s has a floor but was not measured\n' "$file" >&2 FAILED=1 continue fi cover="$(echo "$line" | awk '{print $(NF-3)}' | tr -d '%')" if awk -v f="$floor" -v g="$cover" 'BEGIN { exit !(g+0 < f+0) }'; then printf 'FAIL: %s at %s%% is below its %s%% floor\n' "$file" "$cover" "$floor" >&2 FAILED=1 else printf 'ok: %s at %s%% (floor %s%%)\n' "$file" "$cover" "$floor" fi done <<< "$PER_FILE_FLOORS" exit "$FAILED"