scripts: make strict coverage source-aware
This commit is contained in:
1 parent
ed5dc9b2a7
commit
f435e62f8b
3 files changed
+415
No files matched your search
Executable
+141
@@ -0,0 +1,141 @@
|
||||
#!/usr/bin/env sh
|
||||
# Per-workspace-crate line and branch coverage report.
|
||||
#
|
||||
# This is deliberately a report over every host-testable workspace package,
|
||||
# not a misleading aggregate. STM32F7 platform/board images are target-only:
|
||||
# their `panic-halt` handler cannot link into the host test harness, so they
|
||||
# are reported as N/A and must be covered by target checks plus bench
|
||||
# evidence instead.
|
||||
#
|
||||
# Prerequisites (kept out of the firmware dependency graph):
|
||||
# cargo install cargo-llvm-cov --locked
|
||||
# rustup toolchain install nightly --component llvm-tools-preview
|
||||
# python3 (standard library only, for strict source-level accounting)
|
||||
set -eu
|
||||
|
||||
if ! cargo llvm-cov --version >/dev/null 2>&1; then
|
||||
echo "cargo-llvm-cov is required; install it with: cargo install cargo-llvm-cov --locked" >&2
|
||||
exit 127
|
||||
fi
|
||||
|
||||
if ! rustup toolchain list | grep -q '^nightly'; then
|
||||
echo "nightly with llvm-tools-preview is required for branch coverage" >&2
|
||||
exit 127
|
||||
fi
|
||||
|
||||
if ! python3 --version >/dev/null 2>&1; then
|
||||
echo "python3 is required for strict source-level coverage accounting" >&2
|
||||
exit 127
|
||||
fi
|
||||
|
||||
python3 scripts/test-summarize-test-coverage.py
|
||||
|
||||
# Keep instrumentation products outside a possibly shared target directory.
|
||||
: "${CARGO_TARGET_DIR:=/tmp/kaptan-test-coverage}"
|
||||
export CARGO_TARGET_DIR
|
||||
mkdir -p "$CARGO_TARGET_DIR"
|
||||
|
||||
# `cargo llvm-cov` merges every instrumented object below `CARGO_TARGET_DIR`.
|
||||
# A shared target directory therefore makes a later strict-core report include
|
||||
# an unexecuted copy of a shared dependency built while testing an earlier
|
||||
# package. Keep reports together but isolate each strict-core invocation. The
|
||||
# non-core packages retain the shared directory: several intentionally
|
||||
# target-only crates have no host-instrumented object to export by themselves.
|
||||
coverage_root=$CARGO_TARGET_DIR
|
||||
|
||||
core_incomplete=0
|
||||
|
||||
report_package() {
|
||||
package=$1
|
||||
source_path=$2
|
||||
shift 2
|
||||
case "$package" in
|
||||
kaptan-math|kaptan-navigation|kaptan-control|kaptan-safety)
|
||||
package_target_dir="$coverage_root/$package"
|
||||
lcov_report="$coverage_root/$package.lcov"
|
||||
json_report="$coverage_root/$package.json"
|
||||
report_format=strict-core
|
||||
;;
|
||||
*)
|
||||
package_target_dir=$coverage_root
|
||||
lcov_report="$coverage_root/$package.lcov"
|
||||
report_format=lcov
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$report_format" in
|
||||
strict-core)
|
||||
# Keep the strict core isolated, then export both representations
|
||||
# from the same test run. LCOV `DA` defines source lines; JSON
|
||||
# coordinates define branch identities across generic instances.
|
||||
RUSTC_BOOTSTRAP=1 CARGO_TARGET_DIR="$package_target_dir" cargo llvm-cov \
|
||||
--branch \
|
||||
--no-report \
|
||||
-p "$package" \
|
||||
"$@"
|
||||
RUSTC_BOOTSTRAP=1 CARGO_TARGET_DIR="$package_target_dir" cargo llvm-cov report \
|
||||
--lcov \
|
||||
--output-path "$lcov_report"
|
||||
RUSTC_BOOTSTRAP=1 CARGO_TARGET_DIR="$package_target_dir" cargo llvm-cov report \
|
||||
--json \
|
||||
--output-path "$json_report"
|
||||
totals=$(python3 scripts/summarize-test-coverage.py \
|
||||
"$lcov_report" "$json_report" "$source_path")
|
||||
;;
|
||||
lcov)
|
||||
RUSTC_BOOTSTRAP=1 CARGO_TARGET_DIR="$package_target_dir" cargo llvm-cov \
|
||||
--branch \
|
||||
--lcov \
|
||||
--output-path "$lcov_report" \
|
||||
-p "$package" \
|
||||
"$@"
|
||||
totals=$(awk -v source_path="$source_path" '
|
||||
/^SF:/ { selected = index($0, source_path) != 0 }
|
||||
selected && /^LF:/ { lines_found += substr($0, 4) }
|
||||
selected && /^LH:/ { lines_hit += substr($0, 4) }
|
||||
selected && /^BRF:/ { branches_found += substr($0, 5) }
|
||||
selected && /^BRH:/ { branches_hit += substr($0, 5) }
|
||||
END {
|
||||
printf "%d %d %d %d", lines_hit, lines_found, branches_hit, branches_found
|
||||
}
|
||||
' "$lcov_report")
|
||||
;;
|
||||
esac
|
||||
set -- $totals
|
||||
printf '%-26s lines %s/%s, branches %s/%s\n' "$package" "$1" "$2" "$3" "$4"
|
||||
|
||||
case "$package" in
|
||||
kaptan-math|kaptan-navigation|kaptan-control|kaptan-safety)
|
||||
if [ "$1" -ne "$2" ] || [ "$3" -ne "$4" ]; then
|
||||
core_incomplete=1
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
echo "Host test coverage (reports: $CARGO_TARGET_DIR; strict core unions LCOV DA lines and JSON branches)"
|
||||
report_package kaptan-actuator /libs/kaptan-actuator/
|
||||
report_package kaptan-board /libs/kaptan-board/
|
||||
report_package kaptan-control /libs/kaptan-control/
|
||||
report_package kaptan-data-channel /libs/kaptan-data-channel/
|
||||
report_package kaptan-dma /libs/kaptan-dma/
|
||||
report_package kaptan-drivers /libs/kaptan-drivers/
|
||||
report_package kaptan-i2c /libs/kaptan-i2c/
|
||||
report_package kaptan-math /libs/kaptan-math/
|
||||
report_package kaptan-mavlink /libs/kaptan-mavlink/ --features dialect-kaptan
|
||||
report_package kaptan-navigation /libs/kaptan-navigation/ --features sitl
|
||||
report_package kaptan-safety /libs/kaptan-safety/
|
||||
report_package kaptan-sensor /libs/kaptan-sensor/
|
||||
report_package kaptan-spi /libs/kaptan-spi/
|
||||
report_package kaptan-time /libs/kaptan-time/
|
||||
report_package kaptan-tx /libs/kaptan-tx/
|
||||
report_package kaptan-sitl /tools/sitl/
|
||||
|
||||
echo "platform-stm32f7 target-only/N/A (run cargo check -p platform-stm32f7 --lib)"
|
||||
echo "kaptan-geprc-f722-v2 target-only/N/A (run its thumbv7em-none-eabihf check)"
|
||||
echo "kaptan-kakute-f7-mini-v3 target-only/N/A (run its thumbv7em-none-eabihf check)"
|
||||
|
||||
if [ "$core_incomplete" -ne 0 ]; then
|
||||
echo "Strict core coverage is incomplete; reports above identify each crate." >&2
|
||||
exit 1
|
||||
fi
|
||||
Reference in new issue
Block a user