Code Coverage with SonarQube#
This guide explains how to build the project with gcov instrumentation, run the unit tests, and feed the resulting coverage data into SonarQube.
Prerequisites#
GCC toolchain with
gcov(installed alongsideg++)CMake 3.20+
CUDA 12.x+ and TensorRT 10.x+
gcovr (required, generates SonarQube coverage reports) — install with
pip install gcovrsonar-scanner (for uploading results to SonarQube)
Quick Start#
A convenience script handles the full workflow — configure, build, test, and report — in a single command:
./scripts/run_coverage.sh --trt-package-dir /path/to/TensorRT
The TRT_PACKAGE_DIR can also be supplied as an environment variable:
export TRT_PACKAGE_DIR=/usr/local/TensorRT-10.x.x
./scripts/run_coverage.sh
After the script completes, coverage data is available in build_coverage/
and SonarQube can be run immediately with sonar-scanner.
Script Options#
Flag |
Description |
Default |
|---|---|---|
|
Path to TensorRT installation (required unless |
— |
|
CUDA version to use |
|
|
Build output directory |
|
|
Google Test filter expression |
|
|
Parallel build jobs |
|
Manual Workflow#
If you need finer control you can run each step individually.
1. Configure#
mkdir -p build_coverage
cmake -S . -B build_coverage \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
-DBUILD_UNIT_TESTS=ON \
-DENABLE_COVERAGE=ON \
-DTRT_PACKAGE_DIR=/path/to/TensorRT
The key CMake options for coverage are:
Option |
Description |
Default |
|---|---|---|
|
Enable gcov instrumentation ( |
|
|
Build the Google Test unit test binary |
|
|
Must be |
— |
|
Generate |
|
Note:
ENABLE_COVERAGEwarns at configure time ifCMAKE_BUILD_TYPEis notDebug, because compiler optimizations can cause misleading coverage results.
2. Build#
Build only the unit test target to keep compile times short:
cmake --build build_coverage --target unitTest -j$(nproc)
The build produces .gcno files alongside every object file. These contain the
control-flow graph that gcov needs to map execution counts back to source lines.
3. Clear Stale Data#
If you are re-running tests after a previous coverage run, delete old .gcda
files so results are not accumulated:
find build_coverage -name '*.gcda' -delete
4. Run Tests#
./build_coverage/unitTest \
--gtest_output="xml:build_coverage/test_results.xml"
Running the instrumented binary produces .gcda files that record how many
times each basic block was executed.
You can run a subset of tests with --gtest_filter:
./build_coverage/unitTest --gtest_filter="LoggerTest.*"
5. Generate Reports#
Use gcovr to convert the raw gcov data into reports. The SonarQube generic
coverage XML (--sonarqube) is required for coverage import:
GCOVR_COMMON="--root . \
--filter cpp/ \
--filter unittests/ \
--exclude 3rdParty/ \
--exclude '.*\.cu$' \
--gcov-ignore-errors=no_working_dir_found \
--gcov-ignore-parse-errors=all"
# SonarQube generic coverage format (required for sonar.coverageReportPaths)
gcovr $GCOVR_COMMON \
--sonarqube build_coverage/sonarqube-coverage.xml
# Cobertura XML (optional, for other CI integrations)
gcovr $GCOVR_COMMON \
--xml-pretty \
--output build_coverage/coverage.xml
# HTML with per-file detail (optional, for local viewing)
gcovr $GCOVR_COMMON \
--html-details build_coverage/coverage.html
Open build_coverage/coverage.html in a browser for a quick local overview.
SonarQube Integration#
The project’s sonar-project.properties is pre-configured for coverage:
sonar.cfamily.compile-commands=build_coverage/compile_commands.json
sonar.coverageReportPaths=build_coverage/sonarqube-coverage.xml
sonar.coverageReportPathspoints to the SonarQube generic coverage XML generated bygcovr --sonarqube. This is the format SonarQube uses to import line coverage data.sonar.cfamily.compile-commandspoints to the compilation database so SonarQube can accurately parse the C++ source files.build_coverage/**is not listed insonar.sourcesto prevent SonarQube from scanning build artifacts (object files, HTML reports, etc.) as source code.
After a coverage build and test run, upload results with:
sonar-scanner
Tip: If your build directory is not
build_coverage, override the properties on the command line:sonar-scanner \ -Dsonar.coverageReportPaths=my_build/sonarqube-coverage.xml \ -Dsonar.cfamily.compile-commands=my_build/compile_commands.json
What Gets Instrumented#
C++ source files (
.cpp) — fully instrumented with line and branch coverage.CUDA files (
.cu) — not instrumented. nvcc generates temporary stub files in/tmp/during compilation that are deleted after the build. The resulting.gcnofiles contain unresolvable source references, which causes gcov and gcovr to fail. Coverage is therefore limited to.cppfiles.Third-party code (
3rdParty/) — excluded from coverage reports viasonar.exclusionsand gcovr--excludefilters.
CI Integration Example#
Below is a minimal CI job that produces coverage for SonarQube:
coverage:
stage: test
script:
- pip install gcovr
- ./scripts/run_coverage.sh --trt-package-dir $TRT_PACKAGE_DIR
- sonar-scanner
artifacts:
paths:
- build_coverage/sonarqube-coverage.xml
- build_coverage/coverage.xml
- build_coverage/coverage.html
- build_coverage/test_results.xml
reports:
junit: build_coverage/test_results.xml
Troubleshooting#
gcov not found during CMake configure
gcov is part of the GCC toolchain. Install it with:
sudo apt install gcc
No .gcda files after running tests
Verify the binary was built with
ENABLE_COVERAGE=ON(--coverageshould appear in the compile commands).Ensure the test binary runs to completion (or at least exits normally). Coverage data is flushed on
exit().
Coverage percentages seem too low
Use
CMAKE_BUILD_TYPE=Debugto prevent the compiler from optimizing away branches.Make sure you cleared old
.gcdafiles before the test run so you are not mixing stale data.
SonarQube shows 0% coverage
Confirm
sonar.coverageReportPathspoints to thesonarqube-coverage.xmlfile generated bygcovr --sonarqube.Confirm
sonar.cfamily.compile-commandspoints to a validcompile_commands.jsongenerated by the same build.Run
sonar-scannerfrom the repository root so relative paths insonar-project.propertiesresolve correctly.Verify the source file paths inside
sonarqube-coverage.xmlmatch the files that SonarQube is analyzing (paths must be relative to the project root or absolute).