mirror of
https://github.com/uutils/coreutils.git
synced 2025-07-07 13:35:00 +00:00
create a script for automating code coverage
This commit is contained in:
parent
7eb267ddcd
commit
73faa50ac3
3 changed files with 123 additions and 0 deletions
|
@ -4,3 +4,10 @@ status-level = "all"
|
|||
final-status-level = "skip"
|
||||
failure-output = "immediate-final"
|
||||
fail-fast = false
|
||||
|
||||
[profile.coverage]
|
||||
retries = 0
|
||||
status-level = "all"
|
||||
final-status-level = "skip"
|
||||
failure-output = "immediate-final"
|
||||
fail-fast = false
|
||||
|
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,6 +1,7 @@
|
|||
# spell-checker:ignore (misc) direnv
|
||||
|
||||
target/
|
||||
coverage/
|
||||
/src/*/gen_table
|
||||
/build/
|
||||
/tmp/
|
||||
|
|
115
util/build-run-test-coverage-linux.sh
Executable file
115
util/build-run-test-coverage-linux.sh
Executable file
|
@ -0,0 +1,115 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# spell-checker:ignore (env/flags) Ccodegen Cinstrument Coverflow Cpanic Zpanic
|
||||
# spell-checker:ignore PROFDATA PROFRAW coreutil librairies nextest profdata profraw rustlib
|
||||
|
||||
# This script will build, run and generate coverage reports for the whole
|
||||
# testsuite.
|
||||
# The biggest challenge of this process is managing the overwhelming generation
|
||||
# of trace files that are generated after EACH SINGLE invocation of a coreutil
|
||||
# in the testsuite. Moreover, because we run the testsuite against the multicall
|
||||
# binary, each trace file contains coverage information about the WHOLE
|
||||
# multicall binary, dependencies included, which results in a 5-6 MB file.
|
||||
# Running the testsuite easily creates +80 GB of trace files, which is
|
||||
# unmanageable in a CI environment.
|
||||
#
|
||||
# A workaround is to run the testsuite util per util, generate a report per
|
||||
# util, and remove the trace files. Therefore, we end up with several reports
|
||||
# that will get uploaded to codecov afterwards. The issue with this
|
||||
# approach is that the `grcov` call, which is responsible for transforming
|
||||
# `.profraw` trace files into a `lcov` file, takes a lot of time (~20s), mainly
|
||||
# because it has to browse all the sources. So calling it for each of the 100
|
||||
# utils (with --all-features) results in an absurdly long execution time
|
||||
# (almost an hour).
|
||||
|
||||
# TODO: Do not instrument 3rd party librairies to save space and performance
|
||||
|
||||
# Exit the script if an unexpected error arise
|
||||
set -e
|
||||
# Treat unset variables as errors
|
||||
set -u
|
||||
# Print expanded commands to stdout before running them
|
||||
set -x
|
||||
|
||||
ME="${0}"
|
||||
ME_dir="$(dirname -- "$(readlink -fm -- "${ME}")")"
|
||||
REPO_main_dir="$(dirname -- "${ME_dir}")"
|
||||
|
||||
# Features to enable for the `coreutils` package
|
||||
FEATURES_OPTION=${FEATURES_OPTION:-"--features=feat_os_unix"}
|
||||
COVERAGE_DIR=${COVERAGE_DIR:-"${REPO_main_dir}/coverage"}
|
||||
|
||||
LLVM_PROFDATA="$(find "$(rustc --print sysroot)" -name llvm-profdata)"
|
||||
|
||||
PROFRAW_DIR="${COVERAGE_DIR}/traces"
|
||||
PROFDATA_DIR="${COVERAGE_DIR}/data"
|
||||
REPORT_DIR="${COVERAGE_DIR}/report"
|
||||
REPORT_PATH="${REPORT_DIR}/total.lcov.info"
|
||||
|
||||
rm -rf "${PROFRAW_DIR}" && mkdir -p "${PROFRAW_DIR}"
|
||||
rm -rf "${PROFDATA_DIR}" && mkdir -p "${PROFDATA_DIR}"
|
||||
rm -rf "${REPORT_DIR}" && mkdir -p "${REPORT_DIR}"
|
||||
|
||||
#shellcheck disable=SC2086
|
||||
UTIL_LIST=$("${ME_dir}"/show-utils.sh ${FEATURES_OPTION})
|
||||
|
||||
export CARGO_INCREMENTAL=0
|
||||
export RUSTFLAGS="-Cinstrument-coverage -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort"
|
||||
export RUSTDOCFLAGS="-Cpanic=abort"
|
||||
export RUSTUP_TOOLCHAIN="nightly-gnu"
|
||||
export LLVM_PROFILE_FILE="${PROFRAW_DIR}/coverage-%m-%p.profraw"
|
||||
|
||||
# Disable expanded command printing for the rest of the program
|
||||
set +x
|
||||
|
||||
run_test_and_aggregate() {
|
||||
echo "# Running coverage tests for ${1}"
|
||||
|
||||
# Build and run tests for the UTIL
|
||||
cargo nextest run \
|
||||
--profile coverage \
|
||||
--no-fail-fast \
|
||||
--color=always \
|
||||
2>&1 \
|
||||
${2} \
|
||||
| grep -v 'SKIP'
|
||||
# Note: Do not print the skipped tests on the output as there will be many.
|
||||
|
||||
echo "## Tests for (${1}) generated $(du -h -d1 ${PROFRAW_DIR} | cut -f 1) of profraw files"
|
||||
|
||||
# Aggregate all the trace files into a profdata file
|
||||
PROFDATA_FILE="${PROFDATA_DIR}/${1}.profdata"
|
||||
echo "## Aggregating coverage files under ${PROFDATA_FILE}"
|
||||
"${LLVM_PROFDATA}" merge \
|
||||
-sparse \
|
||||
-o ${PROFDATA_FILE} \
|
||||
${PROFRAW_DIR}/*.profraw \
|
||||
|| true
|
||||
# We don't want an error in `llvm-profdata` to abort the whole program
|
||||
}
|
||||
|
||||
for UTIL in ${UTIL_LIST}; do
|
||||
|
||||
run_test_and_aggregate \
|
||||
"${UTIL}" \
|
||||
"-p coreutils -E test(/^test_${UTIL}::/) ${FEATURES_OPTION}"
|
||||
|
||||
echo "## Clear the trace directory to free up space"
|
||||
rm -rf "${PROFRAW_DIR}" && mkdir -p "${PROFRAW_DIR}"
|
||||
done;
|
||||
|
||||
echo "Running coverage tests over uucore"
|
||||
run_test_and_aggregate "uucore" "-p uucore --all-features"
|
||||
|
||||
echo "# Aggregating all the profraw files under ${REPORT_PATH}"
|
||||
grcov \
|
||||
"${PROFDATA_DIR}" \
|
||||
--binary-path "${REPO_main_dir}/target/debug/coreutils" \
|
||||
--output-types lcov \
|
||||
--output-path ${REPORT_PATH} \
|
||||
--llvm \
|
||||
--keep-only "${REPO_main_dir}"'/src/*'
|
||||
|
||||
|
||||
# Notify the report file to github
|
||||
echo "report=${REPORT_PATH}" >> $GITHUB_OUTPUT
|
Loading…
Add table
Add a link
Reference in a new issue