-
Notifications
You must be signed in to change notification settings - Fork 38.7k
CMake: Add dynamic test discovery #33483
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
|
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. Code Coverage & BenchmarksFor details see: https://corecheck.dev/bitcoin/bitcoin/pulls/33483. ReviewsSee the guideline for information on the review process.
If your review is incorrectly listed, please copy-paste ConflictsReviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first. |
|
Seems nice, but in the great picture there is still room for improvement:
I am not going to block this pull, because it is a clear improvement over master, and the other issues should be fixed in separate pulls. However, I wanted to bring it up, so that it is clear that more work will be needed if we don't want to end up in a local minimum. |
|
Can you explain the difference in ctest tests-cases? Is the script double discovering tests ? Master : 150 See also: |
Previously there was a single bench sanity check, now there is one bench sanity check for each bench target. (This is the goal of this pull request, but maybe it isn't obvious from the description) |
janb84
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approach ACK 6318195b8ecea6d4ced57c8aac97e1ca713d9822
This PR changes how (en when) we do test discovery. From configure time -> Test time and by use of a CMake module.
NIT: Please extend the PR description of the intended changed behaviour of bench sanity check tests. From single bench sanity check to one bench sanity check for each bench target.
| # Distributed under the MIT software license, see the accompanying | ||
| # file COPYING or https://opensource.org/license/mit/. | ||
|
|
||
| # https://gitlab.kitware.com/cmake/cmake/-/issues/26920 |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
hebasto
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of parsing the test names from the source code at configure time, query the list of tests from the test executables at testing time.
It might also be helpful to explain why this approach is an improvement.
The current implementation does not handle skipped tests correctly:
- on the master branch:
$ ctest --test-dir build -j 20
<snip>
73/148 Test #88: script_assets_tests ..................***Skipped 0.13 sec
<snip>
100% tests passed, 0 tests failed out of 148
Total Test time (real) = 37.05 sec
The following tests did not run:
88 - script_assets_tests (Skipped)
- this PR @ 6318195b8ecea6d4ced57c8aac97e1ca713d9822:
$ ctest --test-dir build -j 20
<snip>
73/148 Test #88: bitcoin.test.script_assets_tests .................. Passed 0.14 sec
<snip>
100% tests passed, 0 tests failed out of 148
Label Time Summary:
test = 96.99 sec*proc (142 tests)
Total Test time (real) = 38.24 sec
cmake/module/DiscoverTests.cmake
Outdated
| set(multiValueArgs DISCOVERY_ARGS PROPERTIES) | ||
| cmake_parse_arguments(PARSE_ARGV 1 arg "" "${oneValueArgs}" "${multiValueArgs}") | ||
|
|
||
| get_property(has_counter TARGET ${target} PROPERTY CTEST_DISCOVERED_TEST_COUNTER SET) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The property name started with CTEST_ seems to be reserved, no?
6318195 to
2bedad4
Compare
janb84
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Concept ACK 2bedad4
Thanks for incorporating my suggestion (and those form the other reviewers) !
Found one typo in the cmake file
| set(properies_content) | ||
| list(LENGTH arg_PROPERTIES properties_len) | ||
| if(properties_len GREATER "0") | ||
| set(properies_content " set_tests_properties(\"\${test_name}\" PROPERTIES\n") | ||
| math(EXPR num_properties "${properties_len} / 2") | ||
| foreach(i RANGE 0 ${num_properties} 2) | ||
| math(EXPR value_index "${i} + 1") | ||
| list(GET arg_PROPERTIES ${i} name) | ||
| list(GET arg_PROPERTIES ${value_index} value) | ||
| string(APPEND properies_content " \"${name}\" \"${value}\"\n") | ||
| endforeach() | ||
| string(APPEND properies_content " )\n") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NIT small typo in variable :
properies_content -> properties_content
| set(properies_content) | |
| list(LENGTH arg_PROPERTIES properties_len) | |
| if(properties_len GREATER "0") | |
| set(properies_content " set_tests_properties(\"\${test_name}\" PROPERTIES\n") | |
| math(EXPR num_properties "${properties_len} / 2") | |
| foreach(i RANGE 0 ${num_properties} 2) | |
| math(EXPR value_index "${i} + 1") | |
| list(GET arg_PROPERTIES ${i} name) | |
| list(GET arg_PROPERTIES ${value_index} value) | |
| string(APPEND properies_content " \"${name}\" \"${value}\"\n") | |
| endforeach() | |
| string(APPEND properies_content " )\n") | |
| set(properties_content) | |
| list(LENGTH arg_PROPERTIES properties_len) | |
| if(properties_len GREATER "0") | |
| set(properies_content " set_tests_properties(\"\${test_name}\" PROPERTIES\n") | |
| math(EXPR num_properties "${properties_len} / 2") | |
| foreach(i RANGE 0 ${num_properties} 2) | |
| math(EXPR value_index "${i} + 1") | |
| list(GET arg_PROPERTIES ${i} name) | |
| list(GET arg_PROPERTIES ${value_index} value) | |
| string(APPEND properties_content " \"${name}\" \"${value}\"\n") | |
| endforeach() | |
| string(APPEND properties_content " )\n") |
| " string(REGEX REPLACE [[${arg_DISCOVERY_MATCH}]] [[${arg_TEST_ARGS_REPLACEMENT}]] test_args \"\${line}\")\n" | ||
| " separate_arguments(test_args)\n" | ||
| " add_test(\"\${test_name}\" \${launcher} \${emulator} \${runner} \${test_args})\n" | ||
| ${properies_content} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| ${properies_content} | |
| ${properties_content} |
|
Concept ACK. |
| "execute_process(\n" | ||
| " COMMAND \${launcher} \${emulator} \${runner} ${arg_DISCOVERY_ARGS}\n" | ||
| " OUTPUT_VARIABLE output OUTPUT_STRIP_TRAILING_WHITESPACE\n" | ||
| " ERROR_VARIABLE output ERROR_STRIP_TRAILING_WHITESPACE\n" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this needed?
hebasto
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The following comments no longer seem needed:
bitcoin/src/test/CMakeLists.txt
Lines 7 to 8 in 2bedad4
| # Do not use generator expressions in test sources because the | |
| # SOURCES property is processed to gather test suite macros. |
bitcoin/src/wallet/test/CMakeLists.txt
Lines 5 to 6 in 2bedad4
| # Do not use generator expressions in test sources because the | |
| # SOURCES property is processed to gather test suite macros. |
|
Concept ACK. I have picked this commit into my master branch at https://github.com/willcl-ark/bitcoin along with a CDash config (and a nightly rebase job) so that I can have my nightly CI jobs upload to a demo cdash instance I configured: https://my.cdash.org/index.php?project=core Seems to work pretty nicely so far :) The cdash is currently open to all submissions so if anyone else would like to submit jobs, then feel free. |
Nice. I think all of this sounds great, but I still haven't seen the larger picture, as the cross-tests and functional tests are left out (#33483 (comment)), among many other things. Again, not a blocker for this pull, and I am happy to continue discussion elsewhere. Though, generally my thinking is that the dashboard should not discriminate against tests written in other programming languages, or even tests written outside the tree of Bitcoin Core. For example, it would be great to have a dashboard with third party integrations of Bitcoin Core to answer the long standing QA problem of us (and the third parties) not knowing when an integration is broken and if it can be fixed. (Usually the rc phase or post-final phase is too late). Also, #18816 has been waiting for years with no one to implement it, as it is not trivial 5 minute task. I am just saying this to clarify that this pull request is not the first and final step in getting a dashboard up. In fact, the benchmarks are already run through ctest, so this pull request here seems even optional on the topic of the dashboard. So I'd love to see a larger design document around the dashboard. This may also help to get more people's wishlist items on it. (I've heard that corecheck could be fully or partially moved to the dashboard). Such a design document could help to ensure we are moving toward a shared goal (ideally with people already signed up to share the workload of moving there), instead of risking to end up with an even more fragmented CI/QA jungle. |
|
concept ACK, fwiw |
|
Looks like there are a bunch of code review comments. Are you still working on this? |
|
|
🐙 This pull request conflicts with the target branch and needs rebase. |
BrandonOdiwuor
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approach ACK 2bedad4, shifting test discovery from static source code parsing at configure time to dynamic runtime querying of the executables(e.g., via --list_content for Boost.Test-based unit tests and -list for benchmarks). This change facilitates integration with CTest, beginning with unit tests and now including benchmark tests, with clear potential extensions for Qt tests (noted as TODO: -function support) and even functional tests.
I have been running CTest nightly builds using Github actions against my fork that incorporate these changes, along with a custom solution for functional test discovery (inspired by the mechanism in this PR). I upload the results to a demo CDash instance at https://my.cdash.org/index.php?project=core. This approach has been effective for unified reporting and visualization, emphasizing the need for a comprehensive dashboard that could also include third-party integrations. However, as @maflcko pointed out, this PR is a positive step but not the final step in getting a dashboard. A larger design document around the dashboard would be valuable to incorporate more people's wishlist items, align on shared goals, and avoid ending up with a fragmented CI/QA.
I have a few questions
-
on test counts: CTest reports ~150 tests on master, but only ~142 on this branch in my local runs:
Tested on macOS 26.1 with ctest version 4.0.2
<branch: master>
<branch 2bedad455934c9b407329d0bf58521cf24510465>
script_assets_testsis reported aspassedbyCTestwhile it is shown asskippedwhen run directly bytest_bitcoin
<using: CTest>
<using: test_bitcoin>
$ ./build/bin/test_bitcoin --run_test=script_assets_tests --log_level=test_suite
Instead of parsing the test names from the source code at configure time, query the list of tests from the test executables at testing time.
This should be upstreamed to CMake: https://gitlab.kitware.com/cmake/cmake/-/issues/26920
Left to do: The
test_bitcoin-qtexecutable should be fixed to support the-functionoption documented here: https://doc.qt.io/qt-6/qtest-overview.html#testing-options so that its test cases can be discovered as well.