Sonarcloud code coverage of C++ in GitHub Actions

Using GitHub Actions, I can get build-wrapper and sonar-scanner to analyze my C++ code.

What doesn’t work, so far, is obtaining Code Coverage.

I’m using lcov in the same way I use it on Travis-CI to generate coverage reports in CodeCov:

https://app.codecov.io/gh/acgetchell/CDT-plusplus/

That is, essentially:

cmake -G Ninja -D CMAKE_BUILD_TYPE=Debut -D ENABLE_COVERAGE:BOOL=TRUE -S . -B build
build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build
cd $GITHUB_WORKSPACE/build
ctest ctest --schedule-random -j2
lcov --capture --directory . --output-file coverage.info
lcov --remove coverage.info '/usr/*' '*/usr/include/*' '*/vcpkg_installed/*' --output-file coverage.info

(The test step is set to continue-on-error, because some random number tests will fail and I don’t want that to abort the run.)

I used sonar-project.properties to specify the location of the lcov report:

If I have to use gcov instead, is there a way to specify the location of all the gcda files, similar to what lcov does?

adam@hapkido ~/projects/CDT-plusplus/build (develop*) $ lcov --capture --directory . --output-file coverage.info
Capturing coverage data from .
Found LLVM gcov version 12.0.5, which emulates gcov version 4.2.0
Using intermediate gcov format
Scanning . for .gcda files ...
Found 21 data files in .
Processing tests/CMakeFiles/CDT_test.dir/Move_always_test.cpp.gcda
Processing tests/CMakeFiles/CDT_test.dir/main.cpp.gcda
Processing tests/CMakeFiles/CDT_test.dir/Foliated_triangulation_test.cpp.gcda
Processing tests/CMakeFiles/CDT_test.dir/Move_tracker_test.cpp.gcda
Processing tests/CMakeFiles/CDT_test.dir/Apply_move_test.cpp.gcda
Processing tests/CMakeFiles/CDT_test.dir/Ergodic_moves_3_test.cpp.gcda
Processing tests/CMakeFiles/CDT_test.dir/Metropolis_test.cpp.gcda
Processing tests/CMakeFiles/CDT_test.dir/Settings_test.cpp.gcda
Processing tests/CMakeFiles/CDT_test.dir/Move_command_test.cpp.gcda
Processing tests/CMakeFiles/CDT_test.dir/Function_ref_test.cpp.gcda
Processing tests/CMakeFiles/CDT_test.dir/S3Action_test.cpp.gcda
Processing tests/CMakeFiles/CDT_test.dir/Tetrahedron_test.cpp.gcda
Processing tests/CMakeFiles/CDT_test.dir/Geometry_test.cpp.gcda
Processing tests/CMakeFiles/CDT_test.dir/Torus_test.cpp.gcda
Processing tests/CMakeFiles/CDT_test.dir/Sphere_test.cpp.gcda
Processing tests/CMakeFiles/CDT_test.dir/Manifold_test.cpp.gcda
Processing tests/CMakeFiles/CDT_test.dir/Vertex_test.cpp.gcda
Processing tests/CMakeFiles/CDT_test.dir/Utilities_test.cpp.gcda
Processing src/CMakeFiles/initialize.dir/initialize.cpp.gcda
Processing src/CMakeFiles/cdt-opt.dir/cdt-opt.cpp.gcda
Processing src/CMakeFiles/cdt-gv.dir/cdt-gv.cpp.gcda
Finished .info-file creation

The remaining steps on lcov are useful for filtering out coverage on included libraries, I don’t know how to do that with gcov here.

Thanks for any suggestions.

Hi @acgetchell ,

this is what we do to import gcov reports for our project:

mkdir ${GCOV_DIR_NAME}
pushd ${GCOV_DIR_NAME}
for f in `find ../build/cmake/CMakeFiles/core.dir -name '*.o'`; do
  echo "Processing $f file..."
  gcov -o ${f} x
done
ls | wc -l
popd

and then we pass -Dsonar.cfamily.gcov.reportsPath=${GCOV_DIR_NAME} to sonar-scanner.

Another option, which I haven’t tried myself but should work, is to use gcovr using --sonarqube option and then passing the output result to sonar.coverageReportPaths property.

Hi @mpaladin,

I tried the method suggested above.

The problem is that it generates coverage on 226 files, most of which are libraries installed via vcpkg. There are only 21 relevant files, and my coverage reports are dramatically affected including everything.

lcov solves that problem by being able to filter extensively.

For whatever reason, it did not upload to SonarCloud.

https://sonarcloud.io/summary/new_code?id=acgetchell_CDT-plusplus

I believe I set the correct path for the reports:

Hello @acgetchell ,

The reason it did not upload to SonarCloud may be that there is a typo in sonar-project.properties: it should be sonar.cfamily.gcov.reportsPath, with an “s” in “reports”.

(About the filtering, I don’t know gcov well enough to guide you, but it may be easier by using gcovr and the sonar.coverageReportPaths property that Massimo mentioned)

Thank you @Amelie! That indeed resolved the issue.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

Hi @acgetchell,

what do you mean with dramatically affected?