test: do an initial coverage capture

I noticed that our coverage reports miss some files completely - this
happens when the test doesn't touch the code in them at all, so the
generated coverage data (and resulting reports) have no information
about them. Let's fix this by doing an initial zero coverage capture
that contains a zeroed counter for every instrumented line in every
file, so when we later merge it with a capture from the test, it shows up
with a missing coverage instead of not showing at all.
This commit is contained in:
Frantisek Sumsal 2023-03-24 21:15:28 +01:00 committed by Luca Boccassi
parent ff155c8162
commit 7fdd6e157a

View file

@ -1488,21 +1488,28 @@ check_coverage_reports() {
dest="${TESTDIR:?}/coverage-info"
fi
if [[ ! -e "${TESTDIR:?}/coverage-base" ]]; then
# This shouldn't happen, as the report is generated during the setup
# phase (test_setup()).
derror "Missing base coverage report"
return 1
fi
# Create a coverage report that will later be uploaded. Remove info about
# system libraries/headers, as we don't really care about them.
lcov --directory "${root}/${BUILD_DIR:?}" --capture --output-file "${dest}.new"
lcov --remove "${dest}.new" -o "${dest}.new" '/usr/include/*' '/usr/lib/*'
if [[ -f "$dest" ]]; then
# If the destination report file already exists, don't overwrite it, but
# dump the new report in a temporary file and then merge it with the already
# present one - this usually happens when running both "parts" of a test
# in one run (the qemu and the nspawn part).
lcov --directory "${root}/${BUILD_DIR:?}" --capture --output-file "${dest}.new"
lcov --remove "${dest}.new" -o "${dest}.new" '/usr/include/*' '/usr/lib/*'
# merge it with the already present one - this usually happens when
# running both "parts" of a test in one run (the qemu and the nspawn part).
lcov --add-tracefile "${dest}" --add-tracefile "${dest}.new" -o "${dest}"
rm -f "${dest}.new"
else
lcov --directory "${root}/${BUILD_DIR:?}" --capture --output-file "${dest}"
lcov --remove "${dest}" -o "${dest}" '/usr/include/*' '/usr/lib/*'
# If there's no prior coverage report, merge the new one with the base
# report we did during the setup phase (see test_setup()).
lcov --add-tracefile "${TESTDIR:?}/coverage-base" --add-tracefile "${dest}.new" -o "${dest}"
fi
rm -f "${dest}.new"
# If the test logs contain lines like:
#
@ -1512,6 +1519,10 @@ check_coverage_reports() {
# usually due to the sandbox being too restrictive (e.g. ProtectSystem=yes,
# ProtectHome=yes) or the $BUILD_DIR being inaccessible to non-root users - see
# `setfacl` stuff in install_compiled_systemd().
#
# Also, a note: some tests, like TEST-46, overmount /home with tmpfs, which
# means if your build dir is under /home/your-user (which is usually the
# case) you might get bogus erorrs and missing coverage.
if ! get_bool "${IGNORE_MISSING_COVERAGE:=}" && \
"${JOURNALCTL:?}" -q --no-pager -D "${root:?}/var/log/journal" --grep "profiling:.+?gcda:[Cc]annot open"; then
derror "Detected possibly missing coverage, check the journal"
@ -3115,6 +3126,12 @@ test_setup() {
printf '[Service]\nStandardOutput=journal+console\nStandardError=journal+console' >"$dropin_dir/99-stdout.conf"
fi
if get_bool "$IS_BUILT_WITH_COVERAGE"; then
# Do an initial coverage capture, to make sure the final report includes
# files that the tests didn't touch at all
lcov --initial --capture --directory "${initdir}/${BUILD_DIR:?}" --output-file "${TESTDIR:?}/coverage-base"
fi
if get_bool "$hook_defined"; then
test_append_files "${initdir:?}"
fi