diff --git a/cmake/modules/TestSuite.cmake b/cmake/modules/TestSuite.cmake index 8b0256239..40988a4cc 100644 --- a/cmake/modules/TestSuite.cmake +++ b/cmake/modules/TestSuite.cmake @@ -1,225 +1,226 @@ # Allow to easily build test suites option(ENABLE_JUNIT_REPORT "Enable Junit report generation for targets that support it" OFF) set(JUNIT_REPORT_DIRECTORY "${CMAKE_BINARY_DIR}/test/junit") set(TEST_LOG_DIRECTORY "${CMAKE_BINARY_DIR}/test/log") set_property( DIRECTORY "${CMAKE_SOURCE_DIR}" APPEND PROPERTY ADDITIONAL_CLEAN_FILES "${CMAKE_BINARY_DIR}/test/tmp" "${JUNIT_REPORT_DIRECTORY}" "${TEST_LOG_DIRECTORY}" ) macro(add_test_environment VARIABLE VALUE) set_property(GLOBAL APPEND PROPERTY TEST_ENVIRONMENT "${VARIABLE}=${VALUE}") endmacro() function(add_test_custom_target TARGET) cmake_parse_arguments(ARG "" "" "CUSTOM_TARGET_ARGS;TEST_COMMAND" ${ARGN}) get_property(TEST_ENVIRONMENT GLOBAL PROPERTY TEST_ENVIRONMENT) add_custom_target(${TARGET} ${ARG_CUSTOM_TARGET_ARGS} COMMAND ${CMAKE_COMMAND} -E make_directory "${JUNIT_REPORT_DIRECTORY}" COMMAND ${CMAKE_COMMAND} -E make_directory "${TEST_LOG_DIRECTORY}" COMMAND ${CMAKE_COMMAND} -E env ${TEST_ENVIRONMENT} ${ARG_TEST_COMMAND} ) endfunction() # Define a new target property to hold the list of tests associated with a test # suite. This property is named UNIT_TESTS to avoid confusion with the directory # level property TESTS. define_property(TARGET PROPERTY UNIT_TESTS BRIEF_DOCS "List of tests" FULL_DOCS "A list of the tests associated with a test suite" ) macro(get_target_from_suite SUITE TARGET) set(${TARGET} "check-${SUITE}") endmacro() macro(get_pool_from_suite SUITE POOL) set(${POOL} "${SUITE}-pool") endmacro() include(Coverage) function(create_test_suite_with_parent_targets NAME) get_target_from_suite(${NAME} TARGET) add_custom_target(${TARGET} COMMENT "Running ${NAME} test suite" COMMAND "${CMAKE_COMMAND}" -E echo "PASSED: ${NAME} test suite" ) foreach(PARENT_TARGET ${ARGN}) if(TARGET ${PARENT_TARGET}) add_dependencies(${PARENT_TARGET} ${TARGET}) endif() endforeach() add_custom_target_coverage(${TARGET}) endfunction() macro(create_test_suite NAME) create_test_suite_with_parent_targets(${NAME} check-all check-extended) endmacro() # After this call, all the tests added to the suite will also be added to the # pool. Works only with the Ninja generators. function(test_suite_create_pool SUITE JOBS) # Create a pool for the test suite get_pool_from_suite(${SUITE} POOL) set_property(GLOBAL APPEND PROPERTY JOB_POOLS ${POOL}=${JOBS}) endfunction() include(InstallationHelper) function(install_test SUITE NAME) # Allow for installing all tests ... if(NOT TARGET install-tests) add_custom_target(install-tests) endif() # ... a complete test suite ... if(NOT TARGET install-test-suite-${SUITE}) add_custom_target(install-test-suite-${SUITE}) endif() if(NOT TARGET install-${SUITE}-${NAME}) # ... or a single test install_target(${NAME} COMPONENT ${SUITE}-${NAME} EXCLUDE_FROM_ALL ) add_dependencies(install-test-suite-${SUITE} install-${SUITE}-${NAME}) add_dependencies(install-tests install-${SUITE}-${NAME}) endif() endfunction() set(TEST_RUNNER_TEMPLATE "${CMAKE_CURRENT_LIST_DIR}/../templates/TestRunner.cmake.in") function(add_test_runner SUITE NAME EXECUTABLE) cmake_parse_arguments(ARG "JUNIT" "" "" ${ARGN}) get_target_from_suite(${SUITE} SUITE_TARGET) set(TARGET "${SUITE_TARGET}-${NAME}") # If there is a pool associated to the test suite, then add the test to the # pool. get_property(JOB_POOLS GLOBAL PROPERTY JOB_POOLS) get_pool_from_suite(${SUITE} POOL) if(JOB_POOLS MATCHES ${POOL}) set(JOB_POOL_ARG JOB_POOL ${POOL}) endif() add_test_custom_target(${TARGET} TEST_COMMAND "${CMAKE_SOURCE_DIR}/cmake/utils/log-and-print-on-failure.sh" "${TEST_LOG_DIRECTORY}/${SUITE}-${NAME}.log" ${CMAKE_CROSSCOMPILING_EMULATOR} "$" ${ARG_UNPARSED_ARGUMENTS} CUSTOM_TARGET_ARGS COMMENT "${SUITE}: testing ${NAME}" DEPENDS ${EXECUTABLE} VERBATIM ${JOB_POOL_ARG} ) add_dependencies(${SUITE_TARGET} ${TARGET}) if(ENABLE_JUNIT_REPORT AND ARG_JUNIT) add_custom_command(TARGET ${TARGET} POST_BUILD COMMENT "Processing junit report for test ${NAME} from suite ${SUITE}" COMMAND_EXPAND_LISTS COMMAND "${Python_EXECUTABLE}" "${CMAKE_SOURCE_DIR}/cmake/utils/junit-reports-merge.py" "${JUNIT_REPORT_DIRECTORY}" "${CMAKE_BINARY_DIR}/test/tmp" "${SUITE}" "${NAME}" ) endif() install_test(${SUITE} ${EXECUTABLE}) endfunction() function(add_test_to_suite SUITE NAME) add_executable(${NAME} EXCLUDE_FROM_ALL ${ARGN}) add_test_runner(${SUITE} ${NAME} ${NAME}) get_target_from_suite(${SUITE} TARGET) set_property( TARGET ${TARGET} APPEND PROPERTY UNIT_TESTS ${NAME} ) endfunction(add_test_to_suite) function(add_boost_unit_tests_to_suite SUITE NAME) cmake_parse_arguments(ARG "" "" "TESTS" ${ARGN} ) get_target_from_suite(${SUITE} SUITE_TARGET) add_executable(${NAME} EXCLUDE_FROM_ALL ${ARG_UNPARSED_ARGUMENTS}) add_dependencies("${SUITE_TARGET}" ${NAME}) set(HRF_LOGGER "HRF,test_suite") foreach(_test_source ${ARG_TESTS}) target_sources(${NAME} PRIVATE "${_test_source}") get_filename_component(_test_name "${_test_source}" NAME_WE) if(ENABLE_JUNIT_REPORT) set(JUNIT_REPORT_FILE "${SUITE}-${_test_name}.xml") set(JUNIT_LOGGER ":JUNIT,message,${JUNIT_REPORT_FILE}") set_property( DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" APPEND PROPERTY ADDITIONAL_CLEAN_FILES "${JUNIT_REPORT_FILE}" ) endif() add_test_runner( ${SUITE} ${_test_name} ${NAME} JUNIT "--run_test=${_test_name}" "--logger=${HRF_LOGGER}${JUNIT_LOGGER}" + "--catch_system_errors=no" ) set_property( TARGET ${SUITE_TARGET} APPEND PROPERTY UNIT_TESTS ${_test_name} ) endforeach() # We don't want to add a dependency to the host system boost during cross # compilation. If this is a native build, we still create the executable to # let cmake know the target exists but we don't add the boost dependency. is_native_build(IS_NATIVE_BUILD) if(IS_NATIVE_BUILD) return() endif() find_package(Boost 1.59 REQUIRED unit_test_framework) target_link_libraries(${NAME} Boost::unit_test_framework) # We need to detect if the BOOST_TEST_DYN_LINK flag is required include(CheckCXXSourceCompiles) set(CMAKE_REQUIRED_LIBRARIES Boost::unit_test_framework) check_cxx_source_compiles(" #define BOOST_TEST_DYN_LINK #define BOOST_TEST_MAIN #include " BOOST_REQUIRES_TEST_DYN_LINK) if(BOOST_REQUIRES_TEST_DYN_LINK) target_compile_definitions(${NAME} PRIVATE BOOST_TEST_DYN_LINK) endif() endfunction(add_boost_unit_tests_to_suite) diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index b5ae9ba22..75d7f0325 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -1,249 +1,250 @@ # Copyright (c) 2018 The Bitcoin developers project(bitcoin-test) # Process json files. file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/data") function(gen_json_header NAME) set(HEADERS "") foreach(f ${ARGN}) set(h "${CMAKE_CURRENT_BINARY_DIR}/${f}.h") # Get the proper name for the test variable. get_filename_component(TEST_NAME ${f} NAME_WE) add_custom_command(OUTPUT ${h} COMMAND "${Python_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/data/generate_header.py" "${TEST_NAME}" "${CMAKE_CURRENT_SOURCE_DIR}/${f}" > ${h} MAIN_DEPENDENCY ${f} DEPENDS "data/generate_header.py" VERBATIM ) list(APPEND HEADERS ${h}) endforeach(f) set(${NAME} "${HEADERS}" PARENT_SCOPE) endfunction() gen_json_header(JSON_HEADERS data/base58_encode_decode.json data/blockfilters.json data/key_io_valid.json data/key_io_invalid.json data/script_tests.json data/sighash.json data/tx_invalid.json data/tx_valid.json ) include(TestSuite) create_test_suite(bitcoin) add_dependencies(check check-bitcoin) # An utility library for bitcoin related test suites. add_library(testutil OBJECT util/blockfilter.cpp util/logging.cpp util/mining.cpp util/setup_common.cpp util/str.cpp util/transaction_utils.cpp util/wallet.cpp ) target_link_libraries(testutil server) if(BUILD_BITCOIN_WALLET) set(BITCOIN_WALLET_TEST_FIXTURE ../wallet/test/init_test_fixture.cpp ../wallet/test/wallet_test_fixture.cpp ) set(BITCOIN_WALLET_TESTS ../wallet/test/db_tests.cpp ../wallet/test/coinselector_tests.cpp ../wallet/test/init_tests.cpp ../wallet/test/ismine_tests.cpp ../wallet/test/psbt_wallet_tests.cpp ../wallet/test/wallet_tests.cpp ../wallet/test/walletdb_tests.cpp ../wallet/test/wallet_crypto_tests.cpp ) endif() add_boost_unit_tests_to_suite(bitcoin test_bitcoin fixture.cpp jsonutil.cpp scriptflags.cpp sigutil.cpp # Tests generated from JSON ${JSON_HEADERS} # Wallet test fixture ${BITCOIN_WALLET_TEST_FIXTURE} TESTS activation_tests.cpp addrman_tests.cpp allocator_tests.cpp amount_tests.cpp arith_uint256_tests.cpp base32_tests.cpp base58_tests.cpp base64_tests.cpp bip32_tests.cpp bitmanip_tests.cpp blockchain_tests.cpp blockcheck_tests.cpp blockencodings_tests.cpp blockfilter_tests.cpp blockfilter_index_tests.cpp blockindex_tests.cpp blockstatus_tests.cpp bloom_tests.cpp bswap_tests.cpp cashaddr_tests.cpp cashaddrenc_tests.cpp checkdatasig_tests.cpp checkpoints_tests.cpp checkqueue_tests.cpp coins_tests.cpp compilerbug_tests.cpp compress_tests.cpp config_tests.cpp core_io_tests.cpp crypto_tests.cpp cuckoocache_tests.cpp dbwrapper_tests.cpp denialofservice_tests.cpp descriptor_tests.cpp dstencode_tests.cpp excessiveblock_tests.cpp feerate_tests.cpp finalization_tests.cpp flatfile_tests.cpp fs_tests.cpp getarg_tests.cpp hash_tests.cpp interfaces_tests.cpp inv_tests.cpp key_io_tests.cpp key_tests.cpp lcg_tests.cpp limitedmap_tests.cpp mempool_tests.cpp merkle_tests.cpp merkleblock_tests.cpp miner_tests.cpp monolith_opcodes_tests.cpp multisig_tests.cpp net_tests.cpp netbase_tests.cpp op_reversebytes_tests.cpp pmt_tests.cpp policyestimator_tests.cpp prevector_tests.cpp radix_tests.cpp raii_event_tests.cpp random_tests.cpp rcu_tests.cpp ref_tests.cpp reverselock_tests.cpp rpc_tests.cpp rpc_server_tests.cpp rwcollection_tests.cpp sanity_tests.cpp scheduler_tests.cpp schnorr_tests.cpp script_bitfield_tests.cpp script_commitment_tests.cpp script_p2sh_tests.cpp script_standard_tests.cpp script_tests.cpp scriptnum_tests.cpp serialize_tests.cpp settings_tests.cpp sigcache_tests.cpp sigencoding_tests.cpp sighash_tests.cpp sighashtype_tests.cpp sigcheckcount_tests.cpp skiplist_tests.cpp streams_tests.cpp sync_tests.cpp timedata_tests.cpp torcontrol_tests.cpp transaction_tests.cpp txindex_tests.cpp txvalidation_tests.cpp txvalidationcache_tests.cpp uint256_tests.cpp undo_tests.cpp util_tests.cpp util_threadnames_tests.cpp validation_block_tests.cpp validation_tests.cpp validationinterface_tests.cpp versionbits_tests.cpp work_comparator_tests.cpp # RPC Tests ../rpc/test/server_tests.cpp # Wallet tests ${BITCOIN_WALLET_TESTS} ) function(add_boost_test_runners_with_upgrade_activated SUITE EXECUTABLE) set(SUITE_UPGRADE_ACTIVATED "${SUITE}-upgrade-activated") get_target_from_suite(${SUITE_UPGRADE_ACTIVATED} TARGET_UPGRADE_ACTIVATED) if(NOT TARGET ${TARGET_UPGRADE_ACTIVATED}) create_test_suite_with_parent_targets( ${SUITE_UPGRADE_ACTIVATED} check-upgrade-activated check-upgrade-activated-extended ) add_dependencies(${TARGET_UPGRADE_ACTIVATED} ${EXECUTABLE}) endif() get_target_from_suite(${SUITE} SUITE_TARGET) get_target_property(BOOST_TESTS ${SUITE_TARGET} UNIT_TESTS) get_target_from_suite(${SUITE_UPGRADE_ACTIVATED} SUITE_UPGRADE_ACTIVATED_TARGET) set(HRF_LOGGER "HRF,test_suite") foreach(_test_name ${BOOST_TESTS}) if(ENABLE_JUNIT_REPORT) set(JUNIT_LOGGER ":JUNIT,message,${SUITE_UPGRADE_ACTIVATED}-${_test_name}.xml") endif() add_test_runner( ${SUITE_UPGRADE_ACTIVATED} "${_test_name}" ${EXECUTABLE} JUNIT "--run_test=${_test_name}" "--logger=${HRF_LOGGER}${JUNIT_LOGGER}" + "--catch_system_errors=no" # Dec. 1st, 2019 at 00:00:00 -- "-testsuitename=Bitcoin ABC unit tests with next upgrade activated" -axionactivationtime=1575158400 ) endforeach() endfunction() add_boost_test_runners_with_upgrade_activated(bitcoin test_bitcoin) target_link_libraries(test_bitcoin rpcclient testutil) if(TARGET bitcoinconsensus-shared) target_link_libraries(test_bitcoin bitcoinconsensus-shared) else() target_link_libraries(test_bitcoin bitcoinconsensus) endif() add_subdirectory(fuzz)