Skip to content

Fix code coverage: instrument the library and exclude third-party code#283

Open
K20shores wants to merge 3 commits into
mainfrom
fix/coverage-exclude-deps
Open

Fix code coverage: instrument the library and exclude third-party code#283
K20shores wants to merge 3 commits into
mainfrom
fix/coverage-exclude-deps

Conversation

@K20shores

@K20shores K20shores commented Jun 26, 2026

Copy link
Copy Markdown
Collaborator

Problem

Code coverage was reporting ~30%. Investigation found two issues, the second being the dominant one.

1. The library was never instrumented (root cause)

append_coverage_compiler_flags() was called after add_subdirectory(src). That function only appends to CMAKE_CXX_FLAGS, which affects targets defined after it runs — so the src/ library was compiled without -fprofile-arcs -ftest-coverage. It produced no .gcno/.gcda data, and the report covered only a handful of header lines inlined into the test translation units (lcov aggregated just 51 lines / 10 functions → 30% of functions).

Fix: move the coverage include() + append_coverage_compiler_flags() before add_subdirectory(src) so the library is instrumented.

2. Report included third-party / system code

The lcov capture only excluded test/*, so build/_deps/* (yaml-cpp, googletest, fmt) and inlined /usr/* headers would be counted once the library is instrumented.

Fix: add _deps/* and /usr/* to the lcov EXCLUDE list, plus a codecov.yml ignore: backstop.

Verification

docker build -t mc:cov -f docker/Dockerfile.coverage .
docker run --rm mc:cov bash -c 'make coverage ARGS="-j8"'

Before this change the lcov summary reported lines: 54.9% (28 of 51 lines) — i.e. it was measuring almost nothing. After instrumenting the library, the report should cover all of src/** and the public headers, and the percentage will reflect real coverage.

🤖 Generated with Claude Code

Coverage was reporting ~30% because the lcov capture only excluded
test/*, so the totals included the FetchContent dependencies built
under build/_deps/ (yaml-cpp, googletest, optionally fmt) plus inlined
system/libstdc++ headers. The denominator was dominated by untested
third-party code, masking the project's real coverage.

- Add _deps/* and /usr/* to the lcov EXCLUDE list in CMakeLists.txt
  (BASE_DIRECTORY only sets path display, it does not restrict capture).
- Add codecov.yml with an ignore list as a backstop for Codecov's own
  path matching.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@codecov-commenter

codecov-commenter commented Jun 26, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 89.13%. Comparing base (f3203c4) to head (55ec7e2).
⚠️ Report is 5 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##             main     #283       +/-   ##
===========================================
+ Coverage   70.00%   89.13%   +19.13%     
===========================================
  Files           5       37       +32     
  Lines          10     1611     +1601     
===========================================
+ Hits            7     1436     +1429     
- Misses          3      175      +172     

see 17 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

…ory)

The real cause of the low (~30%) coverage: append_coverage_compiler_flags()
was called after add_subdirectory(src), so CMAKE_CXX_FLAGS only picked up the
coverage flags for the test targets defined later. The src/ library was built
without instrumentation, so it produced no .gcno/.gcda data and the report
covered only a handful of header lines inlined into the test TUs (51 lines).

Move the include + append_coverage_compiler_flags() ahead of
add_subdirectory(src) so the library itself is instrumented. The
setup_target_for_coverage_lcov() target definition stays in the test block.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@K20shores K20shores changed the title Fix code coverage to exclude third-party and system code Fix code coverage: instrument the library and exclude third-party code Jun 26, 2026
COVERAGE_COMPILER_FLAGS included -fcheck=bounds,do,pointer and
-ffpe-trap=zero,overflow,invalid, which are gfortran-only. This is a
CXX-only project, so cc1plus rejects them ("valid for Fortran but not
for C++"). It went unnoticed because the flags were previously only
applied to the gtest test targets (no -Werror); now that the library
is instrumented (and built with -Werror), the warnings became errors.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants