diff --git a/CMakeLists.txt b/CMakeLists.txt index 131a7a9a8c53bc..fb275fc8b586b7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) diff --git a/cmake/script/Coverage.cmake b/cmake/script/Coverage.cmake index 328dd8ce251367..b59f27c00cf7de 100644 --- a/cmake/script/Coverage.cmake +++ b/cmake/script/Coverage.cmake @@ -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) @@ -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) diff --git a/cmake/script/CoverageInclude.cmake.in b/cmake/script/CoverageInclude.cmake.in deleted file mode 100644 index 7a8bf2f0af2d3c..00000000000000 --- a/cmake/script/CoverageInclude.cmake.in +++ /dev/null @@ -1,56 +0,0 @@ -# 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") - find_program(LLVM_COV_EXECUTABLE llvm-cov REQUIRED) - set(COV_TOOL "${LLVM_COV_EXECUTABLE} gcov") -else() - find_program(GCOV_EXECUTABLE gcov REQUIRED) - set(COV_TOOL "${GCOV_EXECUTABLE}") -endif() - -# 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} -) diff --git a/cmake/script/CoverageIncludeAfterTests.cmake.in b/cmake/script/CoverageIncludeAfterTests.cmake.in new file mode 100644 index 00000000000000..b6b9edcd181a07 --- /dev/null +++ b/cmake/script/CoverageIncludeAfterTests.cmake.in @@ -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() diff --git a/cmake/script/CoverageIncludeBeforeTests.cmake.in b/cmake/script/CoverageIncludeBeforeTests.cmake.in new file mode 100644 index 00000000000000..181958e0366799 --- /dev/null +++ b/cmake/script/CoverageIncludeBeforeTests.cmake.in @@ -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()