test: unit: add gcovr test coverage

Add a script to run gcovr; update contributing guide to explain usage; integrate
with vscode presents; add execution to ci.

To use this, execute `scripts/coverage.sh`. This builds with coverage
instrumentation, runs the test suite, and produces:
 * HTML report: `build_coverage/coverage/index.html` -- open in a browser to see
   per-file line-by-line coverage highlighting
 * MD report: `build_coverage/coverage/coverage.md` -- human-readable summary of
   test coverage which gets attached to the GitHub actions build
 * Cobertura XML: `build/coverage/cobertura.xml` -- machine-readable format used
   by CI; this gets archived today with the build, but no other use is in place
   yet

In the future another tool could be used to track coverage over time, or we
could institute minimum coverage requirements and have a GH actions
automatically open a comment when the coverage is not met, for instance.

Co-authored-by: GitHub Copilot <copilot@github.com> Signed-off-by: Ryan Turner
<ryan@turnrye.com>
This commit is contained in:
Ryan Turner 2026-02-25 07:49:07 -06:00 committed by silseva
parent 649eee381e
commit 2f18cdcc0c
4 changed files with 101 additions and 1 deletions

78
scripts/coverage.sh Executable file
View file

@ -0,0 +1,78 @@
#!/usr/bin/env bash
# SPDX-FileCopyrightText: Copyright 2020-2026 OpenRTX Contributors
# SPDX-License-Identifier: GPL-3.0-or-later
#
# Generate a code coverage report for OpenRTX unit tests.
#
# Usage:
# bash scripts/coverage.sh # full local workflow (setup, test, report)
# bash scripts/coverage.sh --ci BUILD # report-only mode for CI (skips setup/test)
# bash scripts/coverage.sh BUILD --ci # flags and positional args can appear in any order
set -euo pipefail
CI_MODE=false
BUILD_DIR=""
for arg in "$@"; do
case "$arg" in
--ci)
CI_MODE=true
;;
-*)
echo "Unknown option: $arg" >&2
exit 1
;;
*)
if [[ -n "$BUILD_DIR" ]]; then
echo "Unexpected argument: $arg (build dir already set to '$BUILD_DIR')" >&2
exit 1
fi
BUILD_DIR="$arg"
;;
esac
done
BUILD_DIR="${BUILD_DIR:-build_coverage}"
REPORT_DIR="${BUILD_DIR}/coverage"
if [ "$CI_MODE" = false ]; then
# Set up the build with coverage enabled (if not already configured)
if [ ! -f "${BUILD_DIR}/build.ninja" ]; then
meson setup "${BUILD_DIR}" -Db_coverage=true
fi
# Run tests (meson test automatically builds required test targets)
meson test -C "${BUILD_DIR}" --print-errorlogs
fi
# Generate coverage report
mkdir -p "${REPORT_DIR}"
GCOVR_ARGS=(
"${BUILD_DIR}"
--root .
--filter 'openrtx/src/'
--filter 'openrtx/include/'
--exclude '.*subprojects.*'
--exclude '.*test.*'
--cobertura "${REPORT_DIR}/cobertura.xml"
--markdown "${REPORT_DIR}/coverage.md"
--print-summary
)
if [ "$CI_MODE" = false ]; then
GCOVR_ARGS+=(
--html-details "${REPORT_DIR}/index.html"
--decisions
--calls
)
fi
gcovr "${GCOVR_ARGS[@]}"
echo ""
echo "Cobertura XML: ${REPORT_DIR}/cobertura.xml"
if [ "$CI_MODE" = false ]; then
echo "HTML report: ${REPORT_DIR}/index.html"
fi