Skip to content

Commit

Permalink
fixup! cmake: Add Coverage and CoverageFuzz scripts
Browse files Browse the repository at this point in the history
Use Clang's native code coverage compilation, gathering and result
reporting if the compiler is Clang.
  • Loading branch information
vasild committed Jun 18, 2024
1 parent 0e6a793 commit 39baec7
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 110 deletions.
3 changes: 2 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,8 @@ endif()

configure_file(cmake/script/Coverage.cmake Coverage.cmake COPYONLY)
configure_file(cmake/script/CoverageFuzz.cmake CoverageFuzz.cmake COPYONLY)
configure_file(cmake/script/CoverageInclude.cmake.in CoverageInclude.cmake @ONLY)
configure_file(cmake/script/CoverageIncludeBeforeTests.cmake.in CoverageIncludeBeforeTests.cmake @ONLY)
configure_file(cmake/script/CoverageIncludeAfterTests.cmake.in CoverageIncludeAfterTests.cmake @ONLY)
configure_file(contrib/filter-lcov.py filter-lcov.py COPYONLY)

include(cmake/optional.cmake)
Expand Down
58 changes: 5 additions & 53 deletions cmake/script/Coverage.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Distributed under the MIT software license, see the accompanying
# file COPYING or https://opensource.org/license/mit/.

include(${CMAKE_CURRENT_LIST_DIR}/CoverageInclude.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/CoverageIncludeBeforeTests.cmake)

set(functional_test_runner test/functional/test_runner.py)
if(EXTENDED_FUNCTIONAL_TESTS)
Expand All @@ -13,65 +13,17 @@ if(DEFINED JOBS)
list(APPEND functional_test_runner -j ${JOBS})
endif()

# Run the tests.

execute_process(
COMMAND ${CMAKE_CTEST_COMMAND}
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
COMMAND_ERROR_IS_FATAL ANY
)
execute_process(
COMMAND ${LCOV_COMMAND} --capture --directory src --test-name test_bitcoin --output-file test_bitcoin.info
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
)
execute_process(
COMMAND ${LCOV_COMMAND} --zerocounters --directory src
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
)
execute_process(
COMMAND ${LCOV_FILTER_COMMAND} test_bitcoin.info test_bitcoin_filtered.info
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
)
execute_process(
COMMAND ${LCOV_COMMAND} --add-tracefile test_bitcoin_filtered.info --output-file test_bitcoin_filtered.info
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
)
execute_process(
COMMAND ${LCOV_COMMAND} --add-tracefile baseline_filtered.info --add-tracefile test_bitcoin_filtered.info --output-file test_bitcoin_coverage.info
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
)
execute_process(
COMMAND ${GENHTML_COMMAND} test_bitcoin_coverage.info --output-directory test_bitcoin.coverage
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
)

execute_process(
COMMAND ${functional_test_runner}
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
COMMAND_ERROR_IS_FATAL ANY
)
execute_process(
COMMAND ${LCOV_COMMAND} --capture --directory src --test-name functional-tests --output-file functional_test.info
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
)
execute_process(
COMMAND ${LCOV_COMMAND} --zerocounters --directory src
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
)
execute_process(
COMMAND ${LCOV_FILTER_COMMAND} functional_test.info functional_test_filtered.info
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
)
execute_process(
COMMAND ${LCOV_COMMAND} --add-tracefile functional_test_filtered.info --output-file functional_test_filtered.info
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
)
execute_process(
COMMAND ${LCOV_COMMAND} --add-tracefile baseline_filtered.info --add-tracefile test_bitcoin_filtered.info --add-tracefile functional_test_filtered.info --output-file total_coverage.info
COMMAND ${GREP_EXECUTABLE} "%"
COMMAND ${AWK_EXECUTABLE} "{ print substr($3,2,50) \"/\" $5 }"
OUTPUT_FILE coverage_percent.txt
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
)
execute_process(
COMMAND ${GENHTML_COMMAND} total_coverage.info --output-directory total.coverage
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
)

include(${CMAKE_CURRENT_LIST_DIR}/CoverageIncludeAfterTests.cmake)
56 changes: 0 additions & 56 deletions cmake/script/CoverageInclude.cmake.in

This file was deleted.

86 changes: 86 additions & 0 deletions cmake/script/CoverageIncludeAfterTests.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Copyright (c) 2024-present The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or https://opensource.org/license/mit/.

if("@CMAKE_CXX_COMPILER_ID@" STREQUAL "Clang")
# https://clang.llvm.org/docs/SourceBasedCodeCoverage.html#creating-coverage-reports

# https://llvm.org/docs/CommandGuide/llvm-profdata.html#profdata-merge
file(GLOB profraw_files "${CMAKE_CURRENT_LIST_DIR}/coverage/*.profraw")
execute_process(
COMMAND ${LLVM_PROFDATA_EXECUTABLE} merge ${profraw_files} --output=coverage/all.profdata
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
COMMAND_ERROR_IS_FATAL ANY
)
# https://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-show
set(object_args "")
foreach(object_file src/test/test_bitcoin src/bitcoind src/test/fuzz/fuzz)
if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/${object_file})
list(APPEND object_args "-object=${CMAKE_CURRENT_LIST_DIR}/${object_file}")
endif()
endforeach()
execute_process(
COMMAND ${LLVM_COV_EXECUTABLE} show -format=html -output-dir=coverage/result
-Xdemangler=${LLVM_CXXFILT_EXECUTABLE}
-instr-profile=coverage/all.profdata ${object_args}
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
COMMAND_ERROR_IS_FATAL ANY
)
else()
# Collect the coverage from the unit tests.

execute_process(
COMMAND ${LCOV_COMMAND} --capture --directory src --test-name test_bitcoin --output-file test_bitcoin.info
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
)
execute_process(
COMMAND ${LCOV_COMMAND} --zerocounters --directory src
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
)
execute_process(
COMMAND ${LCOV_FILTER_COMMAND} test_bitcoin.info test_bitcoin_filtered.info
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
)
execute_process(
COMMAND ${LCOV_COMMAND} --add-tracefile test_bitcoin_filtered.info --output-file test_bitcoin_filtered.info
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
)
execute_process(
COMMAND ${LCOV_COMMAND} --add-tracefile baseline_filtered.info --add-tracefile test_bitcoin_filtered.info --output-file test_bitcoin_coverage.info
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
)
execute_process(
COMMAND ${GENHTML_COMMAND} test_bitcoin_coverage.info --output-directory test_bitcoin.coverage
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
)

# Collect the coverage from the functional tests.

execute_process(
COMMAND ${LCOV_COMMAND} --capture --directory src --test-name functional-tests --output-file functional_test.info
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
)
execute_process(
COMMAND ${LCOV_COMMAND} --zerocounters --directory src
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
)
execute_process(
COMMAND ${LCOV_FILTER_COMMAND} functional_test.info functional_test_filtered.info
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
)
execute_process(
COMMAND ${LCOV_COMMAND} --add-tracefile functional_test_filtered.info --output-file functional_test_filtered.info
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
)
execute_process(
COMMAND ${LCOV_COMMAND} --add-tracefile baseline_filtered.info --add-tracefile test_bitcoin_filtered.info --add-tracefile functional_test_filtered.info --output-file total_coverage.info
COMMAND ${GREP_EXECUTABLE} "%"
COMMAND ${AWK_EXECUTABLE} "{ print substr($3,2,50) \"/\" $5 }"
OUTPUT_FILE coverage_percent.txt
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
)
execute_process(
COMMAND ${GENHTML_COMMAND} total_coverage.info --output-directory total.coverage
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
)
endif()
59 changes: 59 additions & 0 deletions cmake/script/CoverageIncludeBeforeTests.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Copyright (c) 2024-present The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or https://opensource.org/license/mit/.

if("@CMAKE_CXX_COMPILER_ID@" STREQUAL "Clang")
set(ENV{LLVM_PROFILE_FILE} "${CMAKE_CURRENT_LIST_DIR}/coverage/%m_%p.profraw")

find_program(LLVM_PROFDATA_EXECUTABLE NAMES "$ENV{LLVM_PROFDATA}" llvm-profdata REQUIRED)
find_program(LLVM_COV_EXECUTABLE NAMES "$ENV{LLVM_COV}" llvm-cov REQUIRED)
find_program(LLVM_CXXFILT_EXECUTABLE NAMES "$ENV{LLVM_CXXFILT}" llvm-cxxfilt REQUIRED)
else()
find_program(GCOV_EXECUTABLE gcov REQUIRED)
set(COV_TOOL "${GCOV_EXECUTABLE}")

# COV_TOOL is used to replace a placeholder.
configure_file(
cmake/cov_tool_wrapper.sh.in ${CMAKE_CURRENT_LIST_DIR}/cov_tool_wrapper.sh
FILE_PERMISSIONS OWNER_READ OWNER_EXECUTE
GROUP_READ GROUP_EXECUTE
WORLD_READ
@ONLY
)

find_program(LCOV_EXECUTABLE lcov REQUIRED)
separate_arguments(LCOV_OPTS)
set(LCOV_COMMAND ${LCOV_EXECUTABLE} --gcov-tool ${CMAKE_CURRENT_LIST_DIR}/cov_tool_wrapper.sh ${LCOV_OPTS})

find_program(GENHTML_EXECUTABLE genhtml REQUIRED)
set(GENHTML_COMMAND ${GENHTML_EXECUTABLE} --show-details ${LCOV_OPTS})

find_program(GREP_EXECUTABLE grep REQUIRED)
find_program(AWK_EXECUTABLE awk REQUIRED)

set(LCOV_FILTER_COMMAND ./filter-lcov.py)
list(APPEND LCOV_FILTER_COMMAND -p "/usr/local/")
list(APPEND LCOV_FILTER_COMMAND -p "/usr/include/")
list(APPEND LCOV_FILTER_COMMAND -p "/usr/lib/")
list(APPEND LCOV_FILTER_COMMAND -p "/usr/lib64/")
list(APPEND LCOV_FILTER_COMMAND -p "src/leveldb/")
list(APPEND LCOV_FILTER_COMMAND -p "src/crc32c/")
list(APPEND LCOV_FILTER_COMMAND -p "src/bench/")
list(APPEND LCOV_FILTER_COMMAND -p "src/crypto/ctaes")
list(APPEND LCOV_FILTER_COMMAND -p "src/minisketch")
list(APPEND LCOV_FILTER_COMMAND -p "src/secp256k1")
list(APPEND LCOV_FILTER_COMMAND -p "depends")

execute_process(
COMMAND ${LCOV_COMMAND} --capture --initial --directory src --output-file baseline.info
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
)
execute_process(
COMMAND ${LCOV_FILTER_COMMAND} baseline.info baseline_filtered.info
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
)
execute_process(
COMMAND ${LCOV_COMMAND} --add-tracefile baseline_filtered.info --output-file baseline_filtered.info
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
)
endif()

0 comments on commit 39baec7

Please sign in to comment.