test: Fixup MAX_BODY_SIZE http throttling test #36324

pull maflcko wants to merge 1 commits into bitcoin:master from maflcko:2609-test-http-max-size-throttling changing 1 files +12 −9
  1. maflcko commented at 7:17 AM on September 24, 2026: member

    The check_slow_read_throttle test asserts that throttling happens during a hard-coded time limit, via a hard-coded tries limit.

    This is mostly fine, but can intermittently fail on slow CPUs or when using unoptimized sanitizers.

    Fix it by waiting for a time scaled by --timeout-factor, without a hard-coded tries limit. Also, retain the hard-coded 5s sleep to "verify" throttling happened.

  2. DrahtBot added the label Tests on Sep 24, 2026
  3. DrahtBot commented at 7:17 AM on September 24, 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/36324.

    <!--021abf342d371248e50ceaed478a90ca-->

    Reviews

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

    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.

    <!--5faf32d7da4f0f540f40219e4f7537a3-->

    LLM Linter (✨ experimental)

    Possible places where comparison-specific test macros should replace generic comparisons:

    • [test/functional/interface_http.py] assert count < num_req, f"Server handled the whole batch of {num_req}: nothing was throttled" -> use assert_greater_than(num_req, count) instead of a bare comparison assert

    <sup>2026-09-24 08:40:43</sup>

  4. maflcko added the label Needs Backport (32.x) on Sep 24, 2026
  5. maflcko added this to the milestone 32.0 on Sep 24, 2026
  6. maflcko commented at 7:19 AM on September 24, 2026: member

    To reproduce the failure, one can simulate a slow CPU on large requests via:

    diff --git a/src/httpserver.cpp b/src/httpserver.cpp
    index 6c9a569d42..587a5b4679 100644
    --- a/src/httpserver.cpp
    +++ b/src/httpserver.cpp
    @@ -600,2 +600,6 @@ void HTTPRequest::WriteReply(HTTPStatusCode status, std::span<const std::byte> r
     
    +    if (reply_body.size() > 1'000'000) {
    +        UninterruptibleSleep(5123ms);
    +    }
    +
         if (std::shared_ptr client{m_client.lock()}) {
    

    The failure will be:

    ./test/functional/interface_http.py", line 847, in check_slow_read_throttle
        assert tries > 0, f"Progress failed to stall after {count} requests were handled."
               ^^^^^^^^^
    AssertionError: Progress failed to stall after 5 requests were handled.
    
  7. DrahtBot added the label CI failed on Sep 24, 2026
  8. maflcko marked this as a draft on Sep 24, 2026
  9. test: Fixup MAX_BODY_SIZE http throttling test fa2c62036b
  10. maflcko marked this as ready for review on Sep 24, 2026
  11. maflcko force-pushed on Sep 24, 2026
  12. fanquake commented at 8:51 AM on September 24, 2026: member
  13. DrahtBot removed the label CI failed on Sep 24, 2026
  14. in test/functional/interface_http.py:851 in fa2c62036b
     855 | -                time.sleep(5)
     856 | +                return False
     857 | +
     858 | +        # Large enough interval, to ensure throttling occurred, rather than
     859 | +        # merely slow JSON serialization.
     860 | +        self.wait_until(progress_stalled, check_interval=5)
    


    pinheadmz commented at 8:38 PM on September 24, 2026:

    Non blocking, but In #36303 I put a try/catch around this so if the timeout expires I still get the error message I like ("Progress failed to stall after...")


    maflcko commented at 8:51 PM on September 24, 2026:

    Heh, yeah, I don't like those extra logic steps just to print a seemingly nicer error message. Seems harder to read the code then. Also, when it fails, it is already clear that the timeout is due the the stall not happening:

    ./bld-cmake/test/functional/interface_http.py", line 851, in check_slow_read_throttle
        self.wait_until(progress_stalled, check_interval=5)
        ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    ...
    ./test/functional/test_framework/util.py", line 451, in wait_until_helper_internal
        raise AssertionError("Predicate {} not true after {} seconds".format(predicate_source, timeout))
    ...
    

    Seems like a common pattern used in all tests.

    Also, when a test fails, one has to fully understand the test code and source code anyway, so trying to make the error messages minimally nicer probably doesn't help with that.


    maflcko commented at 7:13 AM on September 25, 2026:

    Same for the other asserts in this file :sweat_smile: Basically what the DrahtBot comment says:

    [test/functional/interface_http.py] assert count < num_req, f"Server handled the whole batch of {num_req}: nothing was throttled" -> use assert_greater_than(num_req, count) instead of a bare comparison assert

    The latter seems cleaner, more idiomatic in this codebase and possibly more useful, as it prints both sides on failure, not just num_req. (Recall there could also be a bug in the test code and count is wrong).

    But I didn't want to re-write this file here and just keep this as minimal fixup :)

  15. pinheadmz approved
  16. pinheadmz commented at 8:39 PM on September 24, 2026: member

    ACK fa2c62036b1d1a1f5858e7ea96cbc719503a942d

    Built and tested on macos/arm64. Reviewed the changes and confirmed the test still catches a regression in the throttle introduced in #36174

    <details><summary>Show Signature</summary>

    -----BEGIN PGP SIGNED MESSAGE-----
    Hash: SHA256
    
    ACK fa2c62036b1d1a1f5858e7ea96cbc719503a942d
    -----BEGIN PGP SIGNATURE-----
    
    iQJPBAEBCAA5FiEE5hdzzW4BBA4vG9eM5+KYS2KJyToFAmq1ijcbFIAAAAAABAAO
    bWFudTIsMi41KzEuMTIsMCwzAAoJEOfimEtiick6ZTwQAJihC3cUX6aHV0VcTvi4
    6wyZj6IBdNVStl6/i+5NWvR1gCsDmCNxQxOPtfsG2/jjLMrr5EDqZuINmgPLhbm4
    6fkuMoIFJaEz/x0u1jjtOrfjpOl/J9lA89jtX8vpb61nFZQRZcSNHpQsgjEmoVvl
    GODhA56AK5TaC63ZAD4gv6bETwbg0gzmmI0rxl2HAQg3A/k4cVDS8+vmPX6RjuoP
    tRbLRTsgEtuwwHIT5VrAaquzQSGJf9CIN4SbeIQcJmYb57bc5pP6qcvxzDMEd48y
    xWdqTXXQL7adYmv3L1CntZS6Zs/R0fL6UXLGhI72KvNlHAMwB7oyMnvd0GIUZGyf
    jpjY8hIqltsss5JMMymwipI0A1tEDchWLHtoev/d8+4QUmSvB5zT+8i5dN0BzbdR
    biaB3bV74vrXpg+jjepCOgWUI4yXUR60rCBktZQmbYsmBujd4mM8H1uK0bQ11B6u
    QnTWLaCuw07usIbt3MJkSv5HPdK2KVohtIE7biBAz1Ee0SIDdqRLo10rrNc7MBcf
    sAIgyfw7VFz0so04S0sme0cwoqaZakzDQcbLdbTZ62Z/swzYGtS9WHS1RDIq1dlJ
    xfJJUPUIn73YLcAh8mXEKT+Lq3Ol/xJOlfHJjEY8jXalR7MvLKTItTZvilpAW/f9
    qV4HiKXBDwmshfZNuMC/AY9M
    =DVZy
    -----END PGP SIGNATURE-----
    

    pinheadmz's public key is on openpgp.org

    </details>

  17. winterrdog commented at 9:48 PM on September 24, 2026: contributor

    tACK fa2c62036b1d1a1f5858e7ea96cbc719503a942d

    successfully built and tested on this toolchain: FreeBSD 15.0/clang++-19/x86_64. the fixup looks great to me

  18. davidgumberg commented at 12:11 AM on September 25, 2026: contributor
  19. willcl-ark approved
  20. willcl-ark commented at 10:14 AM on September 25, 2026: member

    ACK fa2c62036b1d1a1f5858e7ea96cbc719503a942d

  21. sedited merged this on Sep 25, 2026
  22. sedited closed this on Sep 25, 2026

  23. maflcko deleted the branch on Sep 25, 2026
  24. fanquake removed the label Needs Backport (32.x) on Sep 25, 2026
  25. fanquake commented at 3:58 PM on September 25, 2026: member

    Backported to 32.x in #36300.

  26. fanquake referenced this in commit 782ca5a16f on Sep 25, 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-09-28 10:51 UTC

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