From fa0dc4bdffb06b6f0c192fe1aa02b4dfdcdc6e15 Mon Sep 17 00:00:00 2001 From: MarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz> Date: Fri, 23 May 2025 08:47:35 +0200 Subject: [PATCH] test: Allow testing of check failures This allows specific tests to mock the check behavior to consistently use exceptions instead of aborts for intentionally failing checks in all build configurations. --- src/test/CMakeLists.txt | 1 + src/test/util_check_tests.cpp | 33 +++++++++++++++++++++++++++++++++ src/util/check.cpp | 5 +++++ src/util/check.h | 6 ++++++ 4 files changed, 45 insertions(+) create mode 100644 src/test/util_check_tests.cpp diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index 93db34d5a21..fa0e8791180 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -114,6 +114,7 @@ add_executable(test_bitcoin txvalidation_tests.cpp txvalidationcache_tests.cpp uint256_tests.cpp + util_check_tests.cpp util_string_tests.cpp util_tests.cpp util_threadnames_tests.cpp diff --git a/src/test/util_check_tests.cpp b/src/test/util_check_tests.cpp new file mode 100644 index 00000000000..93ac9194604 --- /dev/null +++ b/src/test/util_check_tests.cpp @@ -0,0 +1,33 @@ +// Copyright (c) The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include + +#include +#include + +BOOST_AUTO_TEST_SUITE(util_check_tests) + +BOOST_AUTO_TEST_CASE(check_pass) +{ + Assume(true); + Assert(true); + CHECK_NONFATAL(true); +} + +BOOST_AUTO_TEST_CASE(check_fail) +{ + // Disable aborts for easier testing here + test_only_CheckFailuresAreExceptionsNotAborts mock_checks{}; + + if constexpr (G_ABORT_ON_FAILED_ASSUME) { + BOOST_CHECK_EXCEPTION(Assume(false), NonFatalCheckError, HasReason{"Internal bug detected: false"}); + } else { + BOOST_CHECK_NO_THROW(Assume(false)); + } + BOOST_CHECK_EXCEPTION(Assert(false), NonFatalCheckError, HasReason{"Internal bug detected: false"}); + BOOST_CHECK_EXCEPTION(CHECK_NONFATAL(false), NonFatalCheckError, HasReason{"Internal bug detected: false"}); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/util/check.cpp b/src/util/check.cpp index 9f07fbe4780..77783c843d7 100644 --- a/src/util/check.cpp +++ b/src/util/check.cpp @@ -27,8 +27,13 @@ NonFatalCheckError::NonFatalCheckError(std::string_view msg, std::string_view fi { } +bool g_detail_test_only_CheckFailuresAreExceptionsNotAborts{false}; + void assertion_fail(std::string_view file, int line, std::string_view func, std::string_view assertion) { + if (g_detail_test_only_CheckFailuresAreExceptionsNotAborts) { + throw NonFatalCheckError{assertion, file, line, func}; + } auto str = strprintf("%s:%s %s: Assertion `%s' failed.\n", file, line, func, assertion); fwrite(str.data(), 1, str.size(), stderr); std::abort(); diff --git a/src/util/check.h b/src/util/check.h index 198e9e078b2..6b4ec11f1c8 100644 --- a/src/util/check.h +++ b/src/util/check.h @@ -46,6 +46,12 @@ inline bool EnableFuzzDeterminism() } } +extern bool g_detail_test_only_CheckFailuresAreExceptionsNotAborts; +struct test_only_CheckFailuresAreExceptionsNotAborts { + test_only_CheckFailuresAreExceptionsNotAborts() { g_detail_test_only_CheckFailuresAreExceptionsNotAborts = true; }; + ~test_only_CheckFailuresAreExceptionsNotAborts() { g_detail_test_only_CheckFailuresAreExceptionsNotAborts = false; }; +}; + std::string StrFormatInternalBug(std::string_view msg, std::string_view file, int line, std::string_view func); class NonFatalCheckError : public std::runtime_error