Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/skills/testing/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ Configure with `-DCOVERAGE=ON`, build instrumented targets, and run the selected

These paths assume `build` is immediately under the repository root. For another layout, use the actual path to `scripts/coverage.sh` while retaining the build working directory. The script consumes `.profraw` files and the generated `coverage_binaries.txt`; building alone does not produce coverage.

Text and HTML reports include only framework sources under `src/` and `include/`, excluding test and performance code. First-party C++ static libraries are instrumented, but only linked binaries are report inputs; archives are not counted a second time. Their coverage runtime link requirement also applies to consumers of installed instrumented libraries. Rust is not instrumented by the C++ coverage flags.

For a baseline, use a fresh coverage build/profile directory and record the source revision, build options and exact test selection. Targeted tests do not establish a full-suite baseline. Reports predating library instrumentation have a different denominator and are not directly comparable; including previously invisible code can lower the headline percentage.

## End-to-end test infrastructure

E2e tests use the infrastructure in `tests/infra/`. The key classes are:
Expand Down
1 change: 1 addition & 0 deletions cmake/ccf_app.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ function(add_ccf_static_library name)
add_hardening(${name})
add_tidy(${name})
add_warning_checks(${name})
enable_coverage(${name})

install(TARGETS ${name} EXPORT ccf DESTINATION lib)

Expand Down
1 change: 1 addition & 0 deletions cmake/crypto.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ target_compile_options(
add_san(ccfcrypto)
add_hardening(ccfcrypto)
add_tidy(ccfcrypto)
enable_coverage(ccfcrypto)

target_link_libraries(ccfcrypto PUBLIC crypto ssl ccf_threading)
target_link_libraries(ccfcrypto PUBLIC ccf_rs)
Expand Down
29 changes: 15 additions & 14 deletions cmake/tools.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -114,21 +114,22 @@ function(add_tidy name)
)
endfunction()

separate_arguments(
COVERAGE_FLAGS
UNIX_COMMAND
"-fprofile-instr-generate -fcoverage-mapping"
)
separate_arguments(
COVERAGE_LINK
UNIX_COMMAND
"-fprofile-instr-generate -fcoverage-mapping"
)

function(enable_coverage name)
if(COVERAGE)
target_compile_options(${name} PRIVATE ${COVERAGE_FLAGS})
target_link_libraries(${name} PRIVATE ${COVERAGE_LINK})
set_property(GLOBAL APPEND PROPERTY CCF_COVERAGE_TARGETS ${name})
target_compile_options(
${name}
PRIVATE -fprofile-instr-generate -fcoverage-mapping
)
get_target_property(target_type ${name} TYPE)
if(target_type STREQUAL "STATIC_LIBRARY")
# Consumers need the runtime even if their own sources are not
# instrumented. This also applies to installed instrumented archives.
target_link_options(${name} INTERFACE -fprofile-instr-generate)
else()
target_link_options(${name} PRIVATE -fprofile-instr-generate)
# Report linked objects through their binaries, not again as archives
# containing implementation code that may never have been linked.
set_property(GLOBAL APPEND PROPERTY CCF_COVERAGE_TARGETS ${name})
endif()
endif()
endfunction()
10 changes: 9 additions & 1 deletion scripts/coverage.sh
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ Notes:
- Tests must be built and run with -DCOVERAGE=ON. The build system
automatically sets LLVM_PROFILE_FILE so each test writes its own
uniquely-named .profraw file.
- Coverage of code under 3rdparty/ is excluded from all reports.
- Reports include framework code under src/ and include/, excluding tests
and performance code.
- Requires llvm-profdata and llvm-cov (any of -18 / -15 suffixed variants
are also accepted).
EOF
Expand All @@ -58,6 +59,8 @@ OUTPUT_FILE=""
HTML_DIR=""
SHOW_UNCOVERED=0
BINARIES=()
SOURCE_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
FRAMEWORK_SOURCE_DIRS=("${SOURCE_DIR}/src" "${SOURCE_DIR}/include")

while [[ $# -gt 0 ]]; do
case "$1" in
Expand Down Expand Up @@ -143,14 +146,17 @@ echo "Merging coverage data into '${OUTPUT_FILE}'..."
# CCF/build/CCF/include/... Setting -compilation-dir to the parent of
# the real source tree lets llvm-cov resolve the mapped paths correctly:
# e.g. CCF/include/... relative to /workspaces -> /workspaces/CCF/include/...
# Path equivalence also handles source directories not named CCF.
# ---------------------------------------------------------------------------
COMPILATION_DIR=""
PATH_EQUIVALENCE=""
COMPILE_DB="${PROFRAW_DIR}/compile_commands.json"
if [[ -f "${COMPILE_DB}" ]]; then
prefix_map=$(grep -m1 -o '\-ffile-prefix-map=[^ "]*' "${COMPILE_DB}" | sed 's/-ffile-prefix-map=//' || true)
if [[ -n "${prefix_map}" ]]; then
real_path="${prefix_map%%=*}"
COMPILATION_DIR=$(dirname "${real_path}")
PATH_EQUIVALENCE="${COMPILATION_DIR}/${prefix_map#*=},${real_path}"
echo "Detected file-prefix-map, using compilation-dir: ${COMPILATION_DIR}"
fi
fi
Expand All @@ -170,7 +176,9 @@ build_cov_args() {
# Override compilation directory so llvm-cov can resolve mapped source paths
if [[ -n "${COMPILATION_DIR}" ]]; then
args+=("-compilation-dir=${COMPILATION_DIR}")
args+=("-path-equivalence=${PATH_EQUIVALENCE}")
fi
args+=("--sources" "${FRAMEWORK_SOURCE_DIRS[@]}")
printf '%s\n' "${args[@]}"
}

Expand Down