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:
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… ?
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