Code Coverage Incorrect for C GCOV project

I’m trying to get the code coverage to be correct for sonarcloud. Below is the project I’m working on.

Both locally via lcov & also Code coverage done right. are showing consistent results, but sonarcloud is way off. Based on a fair bit of trying to solve this problem, it looks like sonarcloud can’t merge multiple test runs into a unified set of coverage numbers, but I’m not sure:

  1. If that is actually the problem
  2. how to fix it

sonarcloud.log (71.2 KB)

Hello @schmidtw,
Sorry for the late reply.
I had a look at your project and at your coverage results. To better understand the problem, could you point out a file where you noticed a significant coverage difference between lcov/“Code coverage done right” and SonarCloud?

Yes, it largely stems from the assumption that sonarsource makes that there will be a single, unified coverage report per file with the gcov report. If you use multiple programs to cover a file (say a unit test, then a function test) only one set of results is chosen despite there being multiple sections in the gcov document.

The process to actually get something working was pretty complex and not documented well at all.

Things that didn’t work

  • Despite lcov reports being accepted for the javascript, sonarcloud either rejected it or ignored it because this is the c plugin.
  • The gcov plugin can only process 1 of many blocks, silently ignoring the others. It also requires the user to deal with converting the gcno & gcda files into meaningful gcov files (not as trivial as you’d think) when you have multiple runs & a c file is included by another c file to work around static keywords.
  • Using gcov-tool to merge reports together didn’t work for an unknown reason, but it had the same issues where some coverage reports were just randomly dropped.
  • Using the jacoco coverage didn’t work.
  • sonar.coverage.xmlReportPaths didn’t work.
  • sonar.coverage.ReportPaths didn’t work.

The one thing that did work
From the build directory (using cmake) this command properly gathers the report:
gcovr --sonarqube coverage.xml -r …

With the instruction to include the report in my .sonar-project.properties file:
sonar.coverageReportPaths=build/coverage.xml

But it’s amounted to a bunch of guesses & I kept trying random versions to try to get one that works. The documentation acts like sonarcloud != sonarsource != sonarqube, but the parameters for each are similar… ?

Hi @schmidtw ,

looking at the current status of GitHub - xmidt-org/curlws at 5dc90389507c36dc2544d291d754f2fa2b018f55 it seems like you solved your issue, am I correct?

Coverage in C/C++ is not easy in general, in short the steps are:

  • instrument binary by adding -fprofile-arcs -ftest-coverage to gcc compiler calls
  • execute all your tests

At this point you need to merge reports, on your side you solved it with:

gcovr --sonarqube coverage.xml -r ..
# and adding the following property to sonar-project.properties
sonar.coverageReportPaths=build/coverage.xml

An alternative is the following, which is by using gcov format:

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-9 -o ${f} x
done
ls | wc -l
popd

and add the following property to the analysis:

-Dsonar.cfamily.gcov.reportsPath=${GCOV_DIR_NAME}