Remove boost as a unit test runner #35587

pull rustaceanrob wants to merge 19 commits into bitcoin:master from rustaceanrob:remove-boost-test changing 165 files +1346 −367
  1. rustaceanrob commented at 7:33 AM on June 23, 2026: member

    tl;dr: Make an equivalent test runner to boost with simpler macros and tighter coupling to bitcoin-specific code.

    Motivation

    There are a number of problems with using dependencies in general. Bugs must either be promptly upstreamed or patched, projects may be abandoned, and they are not tailored to a particular use case. This PR removes boost for writing and running unit tests. In the case of Boost.Test, there are a number of issues which are listed below.

    My problems with Boost.Test

    Macros

    When using boost, there are 3 ways of writing the same thing, each with different outcomes

    • BOOST_CHECK(expr1 == expr2): failures show the expression, but no values for expr1 and expr2
    • BOOST_CHECK_EQUAL(expr1, expr2): failures show the expression and values, but requires developers remember CHECK_EQUAL and does not use usual operands
    • BOOST_TEST(expr1 == expr2): failures show the expression and values, and developers may use familiar operands (==, !=)

    All three are preserved to maintain backwards compatibility - presumably, but this results in all 3 being used throughout the repository. As a bonus there is a 4th way, with added context

    • BOOST_CHECK_MESSAGE(expr1 == expr2, "the context"): failures show the expression and message, but no values for expr1 and expr2

    To make debugging and review easier, all of these should be unified to a single macro. Test sites use operands, print helpful messages - values are always included, and do not vary in approach (deciding between BOOST_TEST, CHECK, and BOOST_CHECK_EQUAL is unintuitive)

    <details> <summary>Example boost outputs</summary>

    BOOST_AUTO_TEST_CASE(mustfail)
    {
        auto a{1};
        auto b{2};
        BOOST_CHECK(a == b);
        BOOST_CHECK_EQUAL(a, b);
        BOOST_TEST(a == b);
        COutPoint outpoint_1{Txid{"0000000000000000000000000000000000000000000000000000000000000100"}, 0};
        COutPoint outpoint_2{Txid{"0000000000000000000000000000000000000000000000000000000000000100"}, 1};
        BOOST_CHECK(outpoint_1 == outpoint_2);
        // Doesn't even compile
        // BOOST_TEST(outpoint_1 == outpoint_2);
        // BOOST_CHECK_EQUAL(outpoint_1, outpoint_2);
    }
    
    Running 1 test case...
    test/argsman_tests.cpp(31): error: in "argsman_tests/mustfail": check a == b has failed
    test/argsman_tests.cpp(32): error: in "argsman_tests/mustfail": check a == b has failed [1 != 2]
    test/argsman_tests.cpp(33): error: in "argsman_tests/mustfail": check a == b has failed [1 != 2]
    test/argsman_tests.cpp(36): error: in "argsman_tests/mustfail": check outpoint_1 == outpoint_2 has failed
    

    </details>

    <details> <summary>New outputs</summary>

    TEST_CASE(mustfail)
    {
        auto a{1};
        auto b{2};
        CHECK(a == b);
        COutPoint outpoint_1{Txid{"0000000000000000000000000000000000000000000000000000000000000100"}, 0};
        COutPoint outpoint_2{Txid{"0000000000000000000000000000000000000000000000000000000000000100"}, 1};
        CHECK(outpoint_1 == outpoint_2);
    }
    
    Running 1 test cases...
    [FAIL]: test/argsman_tests.cpp:30: CHECK(a == b)
    1 == 2
    
    [FAIL]: test/argsman_tests.cpp:33: CHECK(outpoint_1 == outpoint_2)
    COutPoint(0000000000, 0) == COutPoint(0000000000, 1)
    
    [FAIL] mustfail (2/2 checks failed)
    

    </details>

    No repository context

    Many types implement ToString, but boost has no way of meaningfully using these representations (will change w/ future std::format). With a repository-specific test runner we can use these today. See example above.

    Not extensible

    With the test runner in this repository we can add things such as #35139, implement string representations for more types, and implement ideas from #8670.

    Other issues

    More issues with boost are raised in #34666, #8670. This PR does not resolve all of them, but one it does address immediately is banning comparisons of integers with different signs, previously allowed by boost. Using a test runner within the source also makes IWYU easier to work with.

    High level changes

    For those running tests, not a tremendous amount has changed in this PR. For instance, the doc page remains valid. Changes to the runner options include anything that is not help, run_test, log_level, list_content. This includes catch_system_errors which is always no. The log_levels have been reduced to 5 levels.

    Changes in writing tests

    • CHECK to compare two values with any ==, !=, >, etc
    • CHECK(a == b, "my message") to append a message
    • REQUIRE, same as CHECK, but will fail the test immediately
    • CHECK_EQUAL_RANGES(it1, it2) to compare two ranges
    • TEST_CASE(name) to add a test
    • FIXTURE_TEST_CASE(name, Fixture) to add a test with a fixture
    • TEST_SUITE_BEGIN/END to declare a suite, optionally with fixture for each test in the suite

    Migration

    Boost.Test is removed in this PR, but the macros are aliased by BOOST_* counterparts so there are no merge conflicts. The idea would be to migrate test files to the new macros when there are no/low number of conflicts on that file.

    Commits

    The addition of the framework:

    • test: Add header-only framework to util

    Migration script (majority of the file changes):

    • scripted-diff: Migrate tests to header-only framework

    Low usage count macro removals:

    • test: Remove use of BOOST_FAIL
    • test: Remove use of BOOST_TEST_INFO_*
    • test: Remove use of BOOST_CHECK_CLOSE

    Required for expression decomposition:

    • crypto: Use constexpr to define output size
    • util: Use constexpr in LockedPool definitions
    • net: Make AddressPosition comparitor const
    • test: Unroll && conditions in macros
    • test: Wrap || expressions in macros
    • test: Wrap bitwise & expressions in macros

    To pass CI

    • test: Use lambda for CRecipient to avoid gcc12 uninitialized warning
    • test: Include memory in result_tests for IWYU
    • test: Initialize variables in dbwrapper_tests

    Build and config

    • depends: drop test from Boost libraries
    • cmake: drop vcpkg Boost Test check
    • vcpkg: drop boost-test dependency
  2. DrahtBot commented at 7:33 AM on June 23, 2026: contributor

    <!--e57a25ab6845829454e8d69fc972939a-->

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    <!--006a51241073e994b41acfe9ec718e94-->

    Code Coverage & Benchmarks

    For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/35587.

    <!--021abf342d371248e50ceaed478a90ca-->

    Reviews

    See the guideline and AI policy for information on the review process.

    Type Reviewers
    Concept ACK purpleKarrot, josibake, janb84, w0xlt, optout21

    If your review is incorrectly listed, please copy-paste <code>&lt;!--meta-tag:bot-skip--&gt;</code> into the comment that the bot should ignore.

    <!--174a7506f384e20aa4161008e828411d-->

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #35662 (script: make txdata non-default-constructible by l0rinc)
    • #35531 (txindex: hash keys and pack positions to reduce disk usage by andrewtoth)
    • #35511 (RFC: consensus: Make CAmount a class by hodlinator)
    • #35195 (coins: cache UTXO outpoint hash codes by l0rinc)
    • #34864 (coins: tighten cache entry state invariants by l0rinc)
    • #34075 (fees: Introduce Mempool Based Fee Estimation to reduce overestimation by ismaelsadeeq)
    • #33540 (argsman, cli: GNU-style command-line option parsing (allows options after non-option arguments) by pablomartin4btc)
    • #31682 ([IBD] specialize CheckBlock's input & coinbase checks by l0rinc)
    • #29278 (Wallet: Add maxfeerate wallet startup option by ismaelsadeeq)
    • #17783 (common: Disallow calling IsArgSet() on ALLOW_LIST options by ryanofsky)
    • #17581 (refactor: Remove settings merge reverse precedence code by ryanofsky)
    • #17580 (refactor: Add ALLOW_LIST flags and enforce usage in CheckArgFlags by ryanofsky)
    • #17493 (util: Forbid ambiguous multiple assignments in config file by ryanofsky)

    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.

    <!--5faf32d7da4f0f540f40219e4f7537a3-->

    LLM Linter (✨ experimental)

    Possible typos and grammar issues:

    • Path that the test binary -> Path to the test binary [the comment is incomplete as written]
    • evalution -> evaluation [misspelling in the comment about operator precedence]

    Possible places where named args for integral literals may be used (e.g. func(x, /*named_arg=*/0) in C++, and func(x, named_arg=0) in Python):

    • [TaprootBuilder::Add(…, …, 0xc0)] in src/test/script_standard_tests.cpp
    • [Lookup(..., 1, false)] in src/test/pcp_tests.cpp
    • [close_to(double, double, double)] in src/test/validation_chainstatemanager_tests.cpp

    <sup>2026-07-13 09:40:05</sup>

  3. purpleKarrot commented at 8:43 AM on June 23, 2026: contributor

    Strong Concept ACK

    My problems with boost

    Boost may have multiple problems on its own, but the problems that you list are specific to Boost.Test. You should not conflate the two.

    CHECK_EQUAL_RANGES(it1, it2) to compare two iterators

    Iterators or Ranges?

    TEST_SUITE_BEGIN/END to declare a suite

    Boost.Test allows arbitrary deep nesting of test suites. When integrating Boost.Test into CTest, this causes headaches for little benefit. I hope we can follow-up on this and restrict the test hierarchy to exactly one test suite (no more and no less) using something along the TEST(TestSuiteName, TestName) macro from GoogleTest.

    Why no concurrency?

    In my opinion, concurrency does not belong in a testing framework. Many testing frameworks have a test driver built-in. But separating test framework and test driver into two orthogonal components allows much more powerful composition. I would even go so far and claim that a test framework should not provide a way to run more than one test; neither concurrently, nor sequentially.

    What a test framework needs to be able to provide, is a way to launch a single test and a way to tell the test driver about the list of tests that are available. The test driver can then orchestrate tests from different testing frameworks from potentially different programming languages and invoke tests individually, sequentially, concurrently, or even distributed across multiple hosts.

    This kind of integration is exactly the reason why I implemented discover_tests, which will be available in CMake 4.4.

    The Boost.Test framework is notoriously bad at this. When selecting a single test, it spams out information about all tests that are not selected. While it can provide information about what tests are available, that output is optimized for human readability and very hard to parse by a test driver. We can definitely do better with a custom test framework!

  4. fjahr commented at 9:06 AM on June 23, 2026: contributor

    There are a number of problems with using dependencies in general. Bugs must either be promptly upstreamed or patched, projects may be abandoned, and they are not tailored to a particular use case. bitcoind has a small number of dependencies and will have fewer very soon (https://github.com/bitcoin/bitcoin/pull/34411). One of the final remaining dependencies is boost, which is responsible for the unit tests and multi-index. This PR removes boost for writing and running unit tests.

    Boost.Test is not a dependency of bitcoind, only of test_bitcoin so this is not comparable to the libevent removal. Also boost::multi_index removal was rejected very recently: #34586.

  5. rustaceanrob commented at 9:21 AM on June 23, 2026: member

    only of test_bitcoin

    Correct me if I'm wrong but it appears the config here still builds test_bitcoin: https://github.com/bitcoin/bitcoin/blob/master/contrib/guix/libexec/build.sh#L125

    Also boost::multi_index removal was rejected very recently: #34586

    That approach used STL containers. An actual replacement would need to use something like this: https://www.mail-archive.com/digitalmars-d@puremagic.com/msg33920.html

  6. fjahr commented at 9:43 AM on June 23, 2026: contributor

    Correct me if I'm wrong but it appears the config here still builds test_bitcoin

    Yes, but what does that have to with my comment? I just said that it's a dependency of test_bitcoin not bitcoind. Reducing the dependencies of bitcoind is a lot more interesting than those of test_bitcoin for obvious security reasons. I don't think the fact that test_bitcoin is built in a release and installed changes much of that. Maybe it does for other people but I think your motivation should be more clear on this if this is what you are after. Particularly this part:

    bitcoind has a small number of dependencies and will have fewer very soon (https://github.com/bitcoin/bitcoin/pull/34411). One of the final remaining dependencies is boost, which is responsible for the unit tests and multi-index.

    I would read this very clearly as boost (including Boost.Test) is a dependency of bitcoind if I didn't know better.

    That approach used STL containers.

    The pull was rejected on conceptual basis, not approach, so I don't think this matters.

  7. rustaceanrob commented at 10:15 AM on June 23, 2026: member

    I would read this very clearly as boost (including Boost.Test) is a dependency of bitcoind if I didn't know better.

    Sure, PR description updated.

    Reducing the dependencies of bitcoind is a lot more interesting than those of test_bitcoin for obvious security reasons

    I find this less obvious then the comment implies. A repository going stale is far more likely than some backdoor or high severity CVE, so "a lot more interesting" feels subjective.

  8. josibake commented at 12:19 PM on June 23, 2026: member

    Yes, but what does that have to with my comment?

    A lot. @rustaceanrob correctly points out that even though Boost.Test is not strictly a dependency of bitcoind, it is included in the release flow that creates and packages bitcoind, along with test_bitcoin. It is correct to say that Boost.Test is a dependency of our release process.

  9. josibake commented at 12:20 PM on June 23, 2026: member

    A repository going stale is far more likely than some backdoor or high severity CVE, so "a lot more interesting" feels subjective.

    Precisely. It's also worth remembering the xzutils backdoor was introduced through test code.

  10. josibake commented at 12:27 PM on June 23, 2026: member

    Strong Concept ACK!

    Love to see it. While I broadly agree with the author's reasons stated in the PR, the ones I'll highlight specifically are:

    • No repository context
    • Not extensible

    Having our own simple, in house test framework gives us the ability to customise it for exactly our needs. I believe we should do everything in our power to make testing an easy, intuitive, and feature rich experience as this helps to remove barriers to people writing and interpreting tests.

    In particular, as a longer term project I am looking at ways to improve concurrency in our testing to help speed up CI. As @purpleKarrot points out:

    The Boost.Test framework is notoriously bad at this. When selecting a single test, it spams out information about all tests that are not selected. While it can provide information about what tests are available, that output is optimized for human readability and very hard to parse by a test driver. We can definitely do better with a custom test framework!

  11. hebasto commented at 1:30 PM on June 23, 2026: member

    996832947dd1053b2e31acd1ef3e2933804fd580 "test: Separate mock_process into a standalone binary"

    This approach seems incompatible with the release process.

    For example, I downloaded the bitcoin-e6e8d1f00a08-win64-unsigned.zip "release" binaries on a Windows machine, unpacked them, and ran:

    >.\bitcoin-e6e8d1f00a08\libexec\test_bitcoin.exe
    Running 770 test cases...
    EXCEPTION in run_command: CreateProcess failed: The system cannot find the file specified.
    [FAIL] run_command (0/1 checks failed)
    [WARN]: Variable DIR_UNIT_TEST_DATA unset, skipping script_assets_test
    
    770 tests: 769 passed, 1 failed, 0 skipped (26566129 checks)
    
    
  12. rustaceanrob force-pushed on Jun 23, 2026
  13. rustaceanrob commented at 5:12 PM on June 23, 2026: member

    This approach seems incompatible with the release process.

    a0d535a78b63df4d04411efb1b2c0f98ee87211e uses an environment variable to determine if the test should run as the mock process or the actual test runner. No added files and should not effect the release.

  14. DrahtBot added the label Needs rebase on Jun 23, 2026
  15. rustaceanrob force-pushed on Jun 23, 2026
  16. DrahtBot removed the label Needs rebase on Jun 23, 2026
  17. in src/test/util/framework.h:463 in 7974316a1a
     458 | +                return ExitStatus::UnknownArgs;
     459 | +            }
     460 | +            opts.log_level = log_level;
     461 | +            continue;
     462 | +        }
     463 | +        if (arg.starts_with("-l")) {
    


    janb84 commented at 9:56 AM on June 24, 2026:

    Is this what we want ? -t foo => correct -tfoo => silently mis-parses

    --run_test foo ==> reject with message (BOOST would accept this) --run_test=foo ==> correct

    (same for --log_level and -l)


    rustaceanrob commented at 12:01 PM on June 24, 2026:

    f90b9b97a85bb923e2ec2b48e7719381bd5c2a99

    -tfoo -> errors and prints usage

    --run_test foo -> runs the foo tests

  18. in src/test/util/framework.h:417 in 7974316a1a
     412 | +struct RuntimeOptions {
     413 | +    const char* prog;
     414 | +    std::string_view filter;
     415 | +    LogLevel log_level = LogLevel::Error;
     416 | +    bool show_list;
     417 | +    bool show_help;
    


    janb84 commented at 10:06 AM on June 24, 2026:
        const char* prog{nullptr};
        std::string_view filter;
        LogLevel log_level = LogLevel::Error;
        bool show_list{false};
        bool show_help{false};
    

    NIT, Core code has a Initializing members at the point of declaration style. This is not wrong (by means of used RuntimeOptions opts{} ) but not matching style.

  19. in src/test/util/framework.h:195 in 7974316a1a
     190 | +        if (!result.is_ok()) {
     191 | +            m_failed.fetch_add(1, std::memory_order_relaxed);
     192 | +        }
     193 | +    }
     194 | +
     195 | +    void exception_occured()
    


    janb84 commented at 10:08 AM on June 24, 2026:
        void exception_occurred()
    

    NIT: spelling

  20. janb84 commented at 10:13 AM on June 24, 2026: contributor

    Concept ACK 7974316a1a5e9e84be446f86fed52564ee954b4b

    This change has enough pro's for me to support it;

    • Unification of all the different BOOS_CHECK*
    • Better orchestrate-able, see #35587 (comment)
    • Removal of dependency.
  21. josibake commented at 11:33 AM on June 24, 2026: member

    The pull was rejected on conceptual basis, not approach, so I don't think this matters. @fjahr this is not an accurate framing of the discussion on #34586. It is acknowledged that fewer dependencies are desirable, if the replacements are an improvement. The critique that follows is specifically about the use of STL containers (which are indeed worse). The second push back from a different reviewer echos the sentiment: boost multi index is better than the alternatives (STL containers, in this case).

    I think this PR stands on its own merit as better than using Boost.Test, regardless of whether or not we end up fully removing boost. However, if a better alternative to boost multi index were to be proposed (e.g., @rustaceanrob 's link), this PR and that perhaps future PR only strengthen each other, not weaken.

  22. rustaceanrob force-pushed on Jun 24, 2026
  23. fanquake commented at 2:11 PM on June 24, 2026: member

    @rustaceanrob if you want, couple commits here to prune out the Boost Test dep: https://github.com/fanquake/bitcoin/commits/35587_drop_pkg/.

  24. rustaceanrob commented at 5:47 PM on June 24, 2026: member

    Nice, I picked those up, thanks

  25. DrahtBot added the label Needs rebase on Jun 24, 2026
  26. rustaceanrob force-pushed on Jun 25, 2026
  27. DrahtBot removed the label Needs rebase on Jun 25, 2026
  28. w0xlt commented at 8:36 PM on June 25, 2026: contributor

    Concept ACK

  29. in src/test/kernel/test_kernel.cpp:415 in fab3d3bf8e outdated
     411 | @@ -412,9 +412,9 @@ BOOST_AUTO_TEST_CASE(btck_transaction_tests)
     412 |      auto empty_data = hex_string_to_byte_vec("");
     413 |      BOOST_CHECK_THROW(Transaction{empty_data}, std::runtime_error);
     414 |  
     415 | -    BOOST_CHECK_EQUAL(tx.CountOutputs(), 2);
     416 | -    BOOST_CHECK_EQUAL(tx.CountInputs(), 1);
     417 | -    BOOST_CHECK_EQUAL(tx.GetLocktime(), 510826);
     418 | +    BOOST_CHECK_EQUAL(tx.CountOutputs(), 2U);
    


    maflcko commented at 3:59 PM on June 27, 2026:

    in fab3d3bf8e9557b92003d5719a6e9781e7cb1886: Not sure why this is needed.

    What are the steps to reproduce and what is the exact output? It would be good to explain this in the commit message.

    Recall that integers in C++ are not type safe (as opposed to e.g. Rust), and C++ has integer promotion rules. This means that literals, such as 0 or 2 can be converted by the compiler to fit in whatever type they should fit for this comparison operation. Specifying U here is harmless, but also useless.

    The correct fix would be to drop this commit, not only because it is large (500+ lines modified), but also because it is not needed.

    See also https://www.github.com/bitcoin/bitcoin/pull/35139/changes/fa0ca71f6964153650a8d5b5d410eceb56460a9c, which makes this work properly:

    template <typename L, typename R, typename OpFunc>
    void check_op(const L& lhs, const R& rhs, std::string_view expr, const char* inv_op, const OpFunc& op,
                  std::source_location loc = std::source_location::current()) noexcept
    {
        if constexpr (std::is_integral_v<L> && std::is_integral_v<R>) {
            // Reject mixed signs for integrals after integral promotion.
            if constexpr (std::is_signed_v<decltype(std::declval<L>() + 0)> != std::is_signed_v<decltype(std::declval<R>() + 0)>) {
                static_assert(std::is_signed_v<L> == std::is_signed_v<R>,
                              "ERROR: Mixed signed/unsigned comparison! Ensure both sides have the same type of signedness.");
            }
        }
        if (!op(lhs, rhs)) {
            std::string explanation{"[" + format_value(lhs) + " " + inv_op + " " + format_value(rhs) + "]"};
            fail_report(expr, explanation, loc);
        }
    }
    
  30. maflcko commented at 4:17 PM on June 27, 2026: member

    I like the changes, but I wonder if another approach could be done here, because replacing the check macros and replacing the framework are not tied together and can be done subsequently and independently.

    Given that this has ~100 direct merge conflicts and possibly a few more silent merge conflicts, I wonder if this should be made easier to review and rebase against.

    My preference would be to:

    • First add the new macros (and the required changes to use them), similar to #35139
    • Then, switch to them in a commit that is easier to review than a commit that also changes the framework in the same diff.
    • Then introduce the new framework.
    • Then switch to the new framework and remove boost.

    Just my preference, though. Not sure what other reviewers prefer.

    Edit: An alternative approach could be to keep this pull as-is, but drop the large "macro rewrite" and instead provide legacy aliases, which can be used temporarily (#define BOOST_CHECK_EQUAL(a, b) CHECK(a == b) // or CHECK_EQUAL(a, b) or whatever the name of the new macro is). This way, many conflicts/rebases during the review of this pull can be avoided, which should make re-review less tedious here. The "simple"/mechanical replacement can then be done later, hopefully at a pre-defined time to minimize the conflicts/rebases and thus minimize the re-review load again?

  31. rustaceanrob commented at 1:34 PM on June 29, 2026: member

    An alternative approach could be to keep this pull as-is, but drop the large "macro rewrite" and instead provide legacy aliases, which can be used temporarily (#define BOOST_CHECK_EQUAL(a, b) CHECK(a == b) // or CHECK_EQUAL(a, b) or whatever the name of the new macro is).

    Makes sense

  32. rustaceanrob force-pushed on Jun 30, 2026
  33. rustaceanrob commented at 2:50 PM on June 30, 2026: member

    Updated with legacy aliases

  34. DrahtBot added the label Needs rebase on Jun 30, 2026
  35. rustaceanrob force-pushed on Jun 30, 2026
  36. DrahtBot removed the label Needs rebase on Jun 30, 2026
  37. maflcko commented at 8:31 AM on July 1, 2026: member

    This only has 24 comments, but is already tedious to review on GitHub, because GitHub decides to hide even a 4 day old comment (https://github.com/bitcoin/bitcoin/pull/35587#discussion_r3486342364). This GitHub behavior was triggered by the (no longer relevant) long list of conflicts.

    Maybe open as a fresh pull request? This should be easy, given that there are no outstanding review comments. (Except maybe mine)

    <img width="1010" height="78" alt="Screenshot 2026-07-01 at 10-30-44 Remove boost as a unit test runner by rustaceanrob · Pull Request [#35587](/bitcoin-bitcoin/35587/) · bitcoin_bitcoin" src="https://github.com/user-attachments/assets/b54ef02f-863f-4a42-9a38-17a513f36f10" />

  38. l0rinc commented at 5:24 PM on July 1, 2026: contributor

    This only has 24 comments, but is already tedious to review on GitHub

    Maybe open as a fresh pull request?

    We need to find a more sustainable/scalable way to do this; GitHub is basically unusable for non-trivial PRs.

    GitHub decides to hide even a 4 day old comment

    https://github.com/refined-github/refined-github has a browser extension to work around that (command+clicking these opens all hidden sections). I also added automatic open to my helper in https://github.com/l0rinc/ACKtopus.

  39. maflcko commented at 8:13 AM on July 2, 2026: member

    This only has 24 comments, but is already tedious to review on GitHub Maybe open as a fresh pull request?

    We need to find a more sustainable/scalable way to do this; GitHub is basically unusable for non-trivial PRs.

    I think here it is really only related to the long list of conflicting pulls. I guess each conflict was an "event" (like a comment). E.g., #35402 is another pull request with roughly 24 comments, and it works just fine.

    I think here opening a fresh pull is trivial and sufficient, but of course I won't object moving off of GitHub :sweat_smile:

    GitHub decides to hide even a 4 day old comment

    https://github.com/refined-github/refined-github has a browser extension to work around that (command+clicking these opens all hidden sections). I also added automatic open to my helper in https://github.com/l0rinc/ACKtopus.

    Thx. Browser extensions, in combination with javascript and LLM integration give me a bit of unease. I think I'll just click the mouse button thrice for now here :sweat_smile:

    A third alternative could be to not trigger GitHub events for each conflict, by using a click-jacking URL. Opened a brainstorming issue in https://github.com/maflcko/DrahtBot/issues/83

  40. optout21 commented at 11:01 AM on July 3, 2026: contributor

    Concept ACK

    A net benefit, both due to reducing Boost usage and improvements (current and future) to the unit test framework.

    Some minor/quick observations:

    • It's a large diff, as all test code is affected. Could be broken up as: introduce new framework, change testers (in chunks), remove boost framework leftovers. Testers that are touched in pending PRs could be left at the end.
    • Once this is over, the macros could be renamed to not have the BOOST prefix (scripted diff)
    • I've seen some seemingly unrelated change to non-test code (const -> constexpr)
  41. in src/test/dbwrapper_tests.cpp:359 in 613a43b5d0 outdated
     355 | @@ -356,18 +356,18 @@ BOOST_AUTO_TEST_CASE(iterator_ordering)
     356 |      for (const int seek_start : {0x00, 0x80}) {
     357 |          it->Seek((uint8_t)seek_start);
     358 |          for (unsigned int x=seek_start; x<255; ++x) {
     359 | -            uint8_t key;
     360 | -            uint32_t value;
     361 | +            uint8_t key{};
    


    l0rinc commented at 6:31 PM on July 3, 2026:

    The diff is already huge and there are a lot of seemingly unrelated changes here - can you please revert these to minimize the diff?


    rustaceanrob commented at 10:15 AM on July 9, 2026:

    No, MSan fails without it. I updated the commit message to be more useful in explaining this.

  42. in src/test/dbwrapper_tests.cpp:337 in 613a43b5d0


    l0rinc commented at 6:32 PM on July 3, 2026:

    Is there any way to keep the IDE supports somehow - since other tools already have test/debug/coverage/profile support for it, e.g. current behavior on CLion: <img width="445" height="150" alt="Image" src="https://github.com/user-attachments/assets/6da4f6ca-b6b0-4b54-bbe7-fcecd823b6fa" />

    PR behavior: <img width="465" height="80" alt="Image" src="https://github.com/user-attachments/assets/34f5249e-c89c-46e4-b34e-577e4e93d61d" />


    rustaceanrob commented at 10:16 AM on July 9, 2026:

    In asking an LLM, for the case of CLion this should still work as 1. this PR preserves the BOOST_* naming 2. there is CTest support in CLion when using add_test. Did you check this branch out and confirm IDE support actually regressed?

  43. l0rinc changes_requested
  44. l0rinc commented at 6:53 PM on July 3, 2026: contributor

    Not yet sure about this, another huge change (that kills the GitHub UI) - I'd be interested in a gradual/minimal approach here that doesn't touch so many files.

  45. maflcko commented at 8:35 AM on July 4, 2026: member

    I think it is nice to have a self-contained and complete patchset that applies globally all at once. Of course, if there are specific unrelated changes that truly make sense on their own and where it makes sense to split them up, it can be done. However, some of the changes seem not needed and possibly even going in the wrong direction, as pointed out in review (https://github.com/bitcoin/bitcoin/pull/35587#discussion_r3486342364, or #35587 (review), or #35625 (comment)). So there is somewhat of a chance that some of those may be dropped and the result here will be slim enough to go in as mostly a single pull request.

  46. DrahtBot added the label Needs rebase on Jul 8, 2026
  47. rustaceanrob force-pushed on Jul 8, 2026
  48. DrahtBot removed the label Needs rebase on Jul 8, 2026
  49. rustaceanrob force-pushed on Jul 8, 2026
  50. DrahtBot added the label CI failed on Jul 8, 2026
  51. DrahtBot commented at 4:51 PM on July 8, 2026: contributor

    <!--85328a0da195eb286784d51f73fa0af9-->

    🚧 At least one of the CI tasks failed. <sub>Task previous releases: https://github.com/bitcoin/bitcoin/actions/runs/28954672394/job/85910327486</sub> <sub>LLM reason (✨ experimental): CI failed due to a C++ build error: a static_assert in /usr/include/c++/12/utility (from std::cmp_equal) when compiling src/test/util_tests.cpp.</sub>

    <details><summary>Hints</summary>

    Try to run the tests locally, according to the documentation. However, a CI failure may still happen due to a number of reasons, for example:

    • Possibly due to a silent merge conflict (the changes in this pull request being incompatible with the current code in the target branch). If so, make sure to rebase on the latest commit of the target branch.

    • A sanitizer issue, which can only be found by compiling with the sanitizer and running the affected test.

    • An intermittent issue.

    Leave a comment here, if you need help tracking down a confusing failure.

    </details>

  52. rustaceanrob force-pushed on Jul 8, 2026
  53. DrahtBot removed the label CI failed on Jul 8, 2026
  54. rustaceanrob force-pushed on Jul 9, 2026
  55. sedited referenced this in commit 81405fc7ab on Jul 9, 2026
  56. willcl-ark added the label Tests on Jul 9, 2026
  57. willcl-ark added the label Upstream on Jul 9, 2026
  58. rustaceanrob force-pushed on Jul 9, 2026
  59. rustaceanrob force-pushed on Jul 9, 2026
  60. hebasto referenced this in commit 907e284e30 on Jul 12, 2026
  61. rustaceanrob force-pushed on Jul 12, 2026
  62. crypto: Use `constexpr` to define output size
    Makes the output size of each hash known at compile time for other TU.
    When using expression decomposition, like in `BOOST_TEST` or the
    framework introduced later, expressions are captured as `const T&`
    function arguments whose values must be known at compile time.
    c2dc5d5d70
  63. util: Use `constexpr` in `LockedPool` definitions
    Makes the size of the pool known at compile time for other TU.
    When using expression decomposition, like in `BOOST_TEST` or the
    framework introduced later, expressions are captured as `const T&`
    function arguments whose values must be known at compile time.
    fcb6eb1b3e
  64. net: Make `AddressPosition` comparitor `const`
    Needed to use `==` operator in tests.
    44f11c3c15
  65. test: Include `memory` in `result_tests` for IWYU
    This is being brought in transitively by boost
    420152deac
  66. test: Initialize variables in `dbwrapper_tests`
    libboost_unit_test_framework is prebuilt without MSan/UBSan,
    so these uninitialized reads were not flagged. The test framework
    introduced in later commits is compiled with the sanitizers.
    6eaefedb79
  67. test: Remove use of `BOOST_FAIL`
    There is only a single case of this macro and the if conditional that
    triggers it may simply be used in a `BOOST_REQUIRE`
    a7bbe96fed
  68. test: Remove use of `BOOST_TEST_INFO_*`
    In the case of `descriptor_tests.cpp`, the info is only used to get the
    diagonsics of `BOOST_CHECK_EQUAL` along with the human readable form of
    the descriptor. This is irrelevant if the test framework implements
    expression decomposition, which will print the string representation on
    failure (e.g. `BOOST_TEST`).
    
    Removing `BOOST_TEST_INFO_SCOPE` requires a few duplications, but these are
    very little cost compared to a port of this macro, which does not appear
    very useful.
    9caf9233da
  69. test: Remove use of `BOOST_CHECK_CLOSE`
    This is only used in a single test and would be a low-motivation add to
    porting the test framework. A lambda is sufficient to enforce the check.
    f0f01a0935
  70. rustaceanrob force-pushed on Jul 13, 2026
  71. test: Move `Coin` `==` operator out of anon namespace c80eeef853
  72. test: Use lambda for `CRecipient` to avoid gcc12 uninitialized warning
    gcc12 warns with uninitialized when boost is not used for this test.
    This side-steps the warning.
    38d67bcdef
  73. test: Avoid unnecessary type conversions in check conditions
    `EraseTx` already returns a `bool`, so these implicit casts within the
    comparisons are not necessary.
    8eccc5a143
  74. test: Unroll `&&` conditions in macros
    Using `&&` in `BOOST_CHECK` is problematic as failures will not indicate
    which condition failed. By unrolling these checks, the user knows
    exactly which expression is the failing case.
    
    This is also required when using test macros that support value
    decomposition, which requires `&&` and `||` are `delete`. Examples
    include `BOOST_TEST`, doctest, Catch2, etc.
    
    ref: https://fekir.info/post/decomposing-an-expression/
    fdbd7d974d
  75. test: Wrap `||` expressions in macros
    The `||` is not usable with `BOOST_TEST` and other modern test
    frameworks like Catch2. This is due to operator precedence used in such
    macros. Here is an additional opinion from Catch2:
    
    > There is no simple rewrite rule for ||, but I generally believe
    that if you have || in your test expression, you should rethink your tests.
    
    ref: https://catch2-temp.readthedocs.io/en/latest/assertions.html#other-limitations
    ref: https://fekir.info/post/decomposing-an-expression/
    4b54385305
  76. test: Wrap bitwise `&` expressions in macros f7f90d1ee6
  77. test: Add header-only framework to util ae1ee1b007
  78. scripted-diff: Migrate tests to header-only framework
    -BEGIN VERIFY SCRIPT-
    mv src/test/new_main.cpp src/test/main.cpp
    git grep -l '<boost/test/unit_test.hpp>' | xargs sed -i 's|<boost/test/unit_test.hpp>|<test/util/framework.h>|'
    sed -i 's|BOOST_TEST_MODULE Bitcoin Kernel Test Suite|BITCOIN_TEST_MAIN|; s|<boost/test/included/unit_test.hpp>|<test/util/framework.h>|' src/test/kernel/test_kernel.cpp
    sed -i 's|boost::unit_test::framework::master_test_suite().argv\[0\]|framework::executable_path()|' src/test/system_tests.cpp
    sed -i '/boost\/test\/\(included\/\)\?unit_test.hpp/d' test/lint/lint-includes.py
    sed -i 's| --catch_system_error=no||' src/test/CMakeLists.txt
    -END VERIFY SCRIPT-
    1ec090d9fa
  79. depends: drop test from Boost libraries 8b2f0ab3a1
  80. cmake: drop vcpkg Boost Test check 3c52a46333
  81. vcpkg: drop boost-test dependency 421271dbcc
  82. rustaceanrob force-pushed on Jul 13, 2026
  83. rustaceanrob commented at 12:47 PM on July 13, 2026: member

    Closing and reopening to remove the github UI items

  84. rustaceanrob closed this on Jul 13, 2026

  85. sedited reopened this on Jul 13, 2026

  86. rustaceanrob commented at 1:38 PM on July 13, 2026: member

    <img width="930" height="130" alt="Screenshot 2026-07-13 at 3 38 22 PM" src="https://github.com/user-attachments/assets/3bcea2ce-644d-4163-93cb-6243bfadc410" />

    is this a UI bug or was this reopened @sedited

  87. yancyribbens commented at 1:42 PM on July 13, 2026: contributor

    is this a UI bug or was this reopened @sedited

    Yeah I thought that was curious too. My email said you closed it and then two minutes later @sedited re-opened. I figured you had pinged him to re-open it for some reason.

  88. sedited commented at 1:59 PM on July 13, 2026: contributor

    Oh, I completely misunderstood what you wanted to do here. Closing.

  89. sedited closed this on Jul 13, 2026


github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-07-14 16:51 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me