Skip to content

Commit 052b8fa

Browse files
purpleKarrotwillcl-ark
authored andcommitted
CMake: Add dynamic test discovery
1 parent ac7949d commit 052b8fa

File tree

3 files changed

+93
-41
lines changed

3 files changed

+93
-41
lines changed

cmake/module/DiscoverTests.cmake

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# Copyright (c) 2025-present The Bitcoin Core developers
2+
# Distributed under the MIT software license, see the accompanying
3+
# file COPYING or https://opensource.org/license/mit/.
4+
5+
# TODO: rework/remove once test discovery is implemented upstream:
6+
# https://gitlab.kitware.com/cmake/cmake/-/issues/26920
7+
function(discover_tests target)
8+
set(oneValueArgs DISCOVERY_MATCH TEST_NAME_REPLACEMENT TEST_ARGS_REPLACEMENT)
9+
set(multiValueArgs DISCOVERY_ARGS PROPERTIES)
10+
cmake_parse_arguments(PARSE_ARGV 1 arg "" "${oneValueArgs}" "${multiValueArgs}")
11+
12+
set(file_base "${CMAKE_CURRENT_BINARY_DIR}/${target}")
13+
set(include_file "${file_base}_include.cmake")
14+
15+
set(properies_content)
16+
list(LENGTH arg_PROPERTIES properties_len)
17+
if(properties_len GREATER "0")
18+
set(properies_content " set_tests_properties(\"\${test_name}\" PROPERTIES\n")
19+
math(EXPR num_properties "${properties_len} / 2")
20+
foreach(i RANGE 0 ${num_properties} 2)
21+
math(EXPR value_index "${i} + 1")
22+
list(GET arg_PROPERTIES ${i} name)
23+
list(GET arg_PROPERTIES ${value_index} value)
24+
string(APPEND properies_content " \"${name}\" \"${value}\"\n")
25+
endforeach()
26+
string(APPEND properies_content " )\n")
27+
endif()
28+
29+
string(CONCAT include_content
30+
"set(runner [[$<TARGET_FILE:${target}>]])\n"
31+
"set(launcher [[$<TARGET_PROPERTY:${target},TEST_LAUNCHER>]])\n"
32+
"set(emulator [[$<$<BOOL:${CMAKE_CROSSCOMPILING}>:$<TARGET_PROPERTY:${target},CROSSCOMPILING_EMULATOR>>]])\n"
33+
"\n"
34+
"execute_process(\n"
35+
" COMMAND \${launcher} \${emulator} \${runner} ${arg_DISCOVERY_ARGS}\n"
36+
" OUTPUT_VARIABLE output OUTPUT_STRIP_TRAILING_WHITESPACE\n"
37+
" ERROR_VARIABLE output ERROR_STRIP_TRAILING_WHITESPACE\n"
38+
" RESULT_VARIABLE result\n"
39+
")\n"
40+
"\n"
41+
"if(NOT result EQUAL 0)\n"
42+
" add_test([[${target}_DISCOVERY_FAILURE]] \${launcher} \${emulator} \${runner} ${arg_DISCOVERY_ARGS})\n"
43+
"else()\n"
44+
" string(REPLACE \"\\n\" \";\" lines \"\${output}\")\n"
45+
" foreach(line IN LISTS lines)\n"
46+
" if(line MATCHES [[${arg_DISCOVERY_MATCH}]])\n"
47+
" string(REGEX REPLACE [[${arg_DISCOVERY_MATCH}]] [[${arg_TEST_NAME_REPLACEMENT}]] test_name \"\${line}\")\n"
48+
" string(REGEX REPLACE [[${arg_DISCOVERY_MATCH}]] [[${arg_TEST_ARGS_REPLACEMENT}]] test_args \"\${line}\")\n"
49+
" separate_arguments(test_args)\n"
50+
" add_test(\"\${test_name}\" \${launcher} \${emulator} \${runner} \${test_args})\n"
51+
${properies_content}
52+
" endif()\n"
53+
" endforeach()\n"
54+
"endif()\n"
55+
)
56+
57+
get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
58+
if(is_multi_config)
59+
file(GENERATE
60+
OUTPUT "${file_base}_include-$<CONFIG>.cmake"
61+
CONTENT "${include_content}"
62+
)
63+
file(WRITE "${include_file}"
64+
"include(\"${file_base}_include-\${CTEST_CONFIGURATION_TYPE}.cmake\")"
65+
)
66+
else()
67+
file(GENERATE
68+
OUTPUT "${include_file}"
69+
CONTENT "${include_content}"
70+
)
71+
endif()
72+
73+
set_property(DIRECTORY APPEND PROPERTY TEST_INCLUDE_FILES "${include_file}")
74+
endfunction()

src/bench/CMakeLists.txt

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
# Distributed under the MIT software license, see the accompanying
33
# file COPYING or https://opensource.org/license/mit/.
44

5+
include(DiscoverTests)
6+
57
add_executable(bench_bitcoin
68
bench_bitcoin.cpp
79
bench.cpp
@@ -84,8 +86,12 @@ if(ENABLE_WALLET)
8486
target_link_libraries(bench_bitcoin bitcoin_wallet)
8587
endif()
8688

87-
add_test(NAME bench_sanity_check
88-
COMMAND bench_bitcoin -sanity-check
89+
discover_tests(bench_bitcoin
90+
DISCOVERY_ARGS [[-list]]
91+
DISCOVERY_MATCH [[.+]]
92+
TEST_NAME_REPLACEMENT [[bitcoin.bench.\0]]
93+
TEST_ARGS_REPLACEMENT [[-filter='^\0$']]
94+
PROPERTIES LABELS bench
8995
)
9096

9197
install_binary_component(bench_bitcoin INTERNAL)

src/test/CMakeLists.txt

Lines changed: 11 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
# Distributed under the MIT software license, see the accompanying
33
# file COPYING or https://opensource.org/license/mit/.
44

5+
include(DiscoverTests)
6+
57
# Do not use generator expressions in test sources because the
68
# SOURCES property is processed to gather test suite macros.
79
add_executable(test_bitcoin
@@ -182,44 +184,14 @@ if(ENABLE_IPC)
182184
target_link_libraries(test_bitcoin bitcoin_ipc_test bitcoin_ipc)
183185
endif()
184186

185-
function(add_boost_test source_file)
186-
if(NOT EXISTS ${source_file})
187-
return()
188-
endif()
189-
190-
file(READ "${source_file}" source_file_content)
191-
string(REGEX
192-
MATCHALL "(BOOST_FIXTURE_TEST_SUITE|BOOST_AUTO_TEST_SUITE)\\(([A-Za-z0-9_]+)"
193-
test_suite_macro "${source_file_content}"
194-
)
195-
list(TRANSFORM test_suite_macro
196-
REPLACE "(BOOST_FIXTURE_TEST_SUITE|BOOST_AUTO_TEST_SUITE)\\(" ""
197-
)
198-
foreach(test_suite_name IN LISTS test_suite_macro)
199-
add_test(NAME ${test_suite_name}
200-
COMMAND test_bitcoin --run_test=${test_suite_name} --catch_system_error=no --log_level=test_suite -- DEBUG_LOG_OUT
201-
)
202-
set_property(TEST ${test_suite_name} PROPERTY
203-
SKIP_REGULAR_EXPRESSION
204-
"no test cases matching filter"
205-
"skipping script_assets_test"
206-
"skipping total_ram"
207-
)
208-
endforeach()
209-
endfunction()
210-
211-
function(add_all_test_targets)
212-
get_target_property(test_source_dir test_bitcoin SOURCE_DIR)
213-
get_target_property(test_sources test_bitcoin SOURCES)
214-
foreach(test_source ${test_sources})
215-
cmake_path(IS_RELATIVE test_source result)
216-
if(result)
217-
cmake_path(APPEND test_source_dir ${test_source} OUTPUT_VARIABLE test_source)
218-
endif()
219-
add_boost_test(${test_source})
220-
endforeach()
221-
endfunction()
222-
223-
add_all_test_targets()
187+
discover_tests(test_bitcoin
188+
DISCOVERY_ARGS [[--list_content]]
189+
DISCOVERY_MATCH [[^([^ ].*)\*$]]
190+
TEST_NAME_REPLACEMENT [[bitcoin.test.\1]]
191+
TEST_ARGS_REPLACEMENT [[--run_test=\1 --catch_system_error=no --log_level=test_suite -- DEBUG_LOG_OUT]]
192+
PROPERTIES
193+
LABELS "test"
194+
SKIP_REGULAR_EXPRESSION "no test cases matching filter;skipping script_assets_test;skipping total_ram"
195+
)
224196

225197
install_binary_component(test_bitcoin INTERNAL)

0 commit comments

Comments
 (0)