aboutsummaryrefslogtreecommitdiff
path: root/src/test/util/setup_common.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/util/setup_common.h')
-rw-r--r--src/test/util/setup_common.h100
1 files changed, 72 insertions, 28 deletions
diff --git a/src/test/util/setup_common.h b/src/test/util/setup_common.h
index dbd66e3585..f9cf5d9157 100644
--- a/src/test/util/setup_common.h
+++ b/src/test/util/setup_common.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2015-2022 The Bitcoin Core developers
+// Copyright (c) 2015-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -10,9 +10,12 @@
#include <key.h>
#include <node/caches.h>
#include <node/context.h> // IWYU pragma: export
+#include <optional>
+#include <ostream>
#include <primitives/transaction.h>
#include <pubkey.h>
#include <stdexcept>
+#include <test/util/random.h>
#include <util/chaintype.h> // IWYU pragma: export
#include <util/check.h>
#include <util/fs.h>
@@ -24,9 +27,12 @@
#include <type_traits>
#include <vector>
+class arith_uint256;
class CFeeRate;
class Chainstate;
class FastRandomContext;
+class uint160;
+class uint256;
/** This is connected to the logger. Can be used to redirect logs to any other log */
extern const std::function<void(const std::string&)> G_TEST_LOG_FUN;
@@ -37,17 +43,17 @@ extern const std::function<std::vector<const char*>()> G_TEST_COMMAND_LINE_ARGUM
/** Retrieve the unit test name. */
extern const std::function<std::string()> G_TEST_GET_FULL_NAME;
-// Enable BOOST_CHECK_EQUAL for enum class types
-namespace std {
-template <typename T>
-std::ostream& operator<<(typename std::enable_if<std::is_enum<T>::value, std::ostream>::type& stream, const T& e)
-{
- return stream << static_cast<typename std::underlying_type<T>::type>(e);
-}
-} // namespace std
-
static constexpr CAmount CENT{1000000};
+struct TestOpts {
+ std::vector<const char*> extra_args{};
+ bool coins_db_in_memory{true};
+ bool block_tree_db_in_memory{true};
+ bool setup_net{true};
+ bool setup_validation_interface{true};
+ bool min_validation_cache{false}; // Equivalent of -maxsigcachebytes=0
+};
+
/** Basic testing setup.
* This just configures logging, data dir and chain parameters.
*/
@@ -55,12 +61,37 @@ struct BasicTestingSetup {
util::SignalInterrupt m_interrupt;
node::NodeContext m_node; // keep as first member to be destructed last
- explicit BasicTestingSetup(const ChainType chainType = ChainType::MAIN, const std::vector<const char*>& extra_args = {});
+ FastRandomContext m_rng;
+ /** Seed the global RNG state and m_rng for testing and log the seed value. This affects all randomness, except GetStrongRandBytes(). */
+ void SeedRandomForTest(SeedRand seed)
+ {
+ SeedRandomStateForTest(seed);
+ m_rng.Reseed(GetRandHash());
+ }
+
+ explicit BasicTestingSetup(const ChainType chainType = ChainType::MAIN, TestOpts = {});
~BasicTestingSetup();
fs::path m_path_root;
fs::path m_path_lock;
bool m_has_custom_datadir{false};
+ /** @brief Test-specific arguments and settings.
+ *
+ * This member is intended to be the primary source of settings for code
+ * being tested by unit tests. It exists to make tests more self-contained
+ * and reduce reliance on global state.
+ *
+ * Usage guidelines:
+ * 1. Prefer using m_args where possible in test code.
+ * 2. If m_args is not accessible, use m_node.args as a fallback.
+ * 3. Avoid direct references to gArgs in test code.
+ *
+ * Note: Currently, m_node.args points to gArgs for backwards
+ * compatibility. In the future, it will point to m_args to further isolate
+ * test environments.
+ *
+ * @see https://github.com/bitcoin/bitcoin/issues/25055 for additional context.
+ */
ArgsManager m_args;
};
@@ -72,8 +103,9 @@ struct ChainTestingSetup : public BasicTestingSetup {
node::CacheSizes m_cache_sizes{};
bool m_coins_db_in_memory{true};
bool m_block_tree_db_in_memory{true};
+ std::function<void()> m_make_chainman{};
- explicit ChainTestingSetup(const ChainType chainType = ChainType::MAIN, const std::vector<const char*>& extra_args = {});
+ explicit ChainTestingSetup(const ChainType chainType = ChainType::MAIN, TestOpts = {});
~ChainTestingSetup();
// Supplies a chainstate, if one is needed
@@ -85,9 +117,7 @@ struct ChainTestingSetup : public BasicTestingSetup {
struct TestingSetup : public ChainTestingSetup {
explicit TestingSetup(
const ChainType chainType = ChainType::MAIN,
- const std::vector<const char*>& extra_args = {},
- const bool coins_db_in_memory = true,
- const bool block_tree_db_in_memory = true);
+ TestOpts = {});
};
/** Identical to TestingSetup, but chain set to regtest */
@@ -106,9 +136,7 @@ class CScript;
struct TestChain100Setup : public TestingSetup {
TestChain100Setup(
const ChainType chain_type = ChainType::REGTEST,
- const std::vector<const char*>& extra_args = {},
- const bool coins_db_in_memory = true,
- const bool block_tree_db_in_memory = true);
+ TestOpts = {});
/**
* Create a new block with just given transactions, coinbase paying to
@@ -220,22 +248,40 @@ struct TestChain100Setup : public TestingSetup {
* be used in "hot loops", for example fuzzing or benchmarking.
*/
template <class T = const BasicTestingSetup>
-std::unique_ptr<T> MakeNoLogFileContext(const ChainType chain_type = ChainType::REGTEST, const std::vector<const char*>& extra_args = {})
+std::unique_ptr<T> MakeNoLogFileContext(const ChainType chain_type = ChainType::REGTEST, TestOpts opts = {})
{
- const std::vector<const char*> arguments = Cat(
+ opts.extra_args = Cat(
{
"-nodebuglogfile",
"-nodebug",
},
- extra_args);
+ opts.extra_args);
- return std::make_unique<T>(chain_type, arguments);
+ return std::make_unique<T>(chain_type, opts);
}
CBlock getBlock13b8a();
-// define an implicit conversion here so that uint256 may be used directly in BOOST_CHECK_*
+// Make types usable in BOOST_CHECK_* @{
+namespace std {
+template <typename T> requires std::is_enum_v<T>
+inline std::ostream& operator<<(std::ostream& os, const T& e)
+{
+ return os << static_cast<std::underlying_type_t<T>>(e);
+}
+
+template <typename T>
+inline std::ostream& operator<<(std::ostream& os, const std::optional<T>& v)
+{
+ return v ? os << *v
+ : os << "std::nullopt";
+}
+} // namespace std
+
+std::ostream& operator<<(std::ostream& os, const arith_uint256& num);
+std::ostream& operator<<(std::ostream& os, const uint160& num);
std::ostream& operator<<(std::ostream& os, const uint256& num);
+// @}
/**
* BOOST_CHECK_EXCEPTION predicates to check the specific validation error.
@@ -245,11 +291,9 @@ std::ostream& operator<<(std::ostream& os, const uint256& num);
class HasReason
{
public:
- explicit HasReason(const std::string& reason) : m_reason(reason) {}
- bool operator()(const std::exception& e) const
- {
- return std::string(e.what()).find(m_reason) != std::string::npos;
- };
+ explicit HasReason(std::string_view reason) : m_reason(reason) {}
+ bool operator()(std::string_view s) const { return s.find(m_reason) != std::string_view::npos; }
+ bool operator()(const std::exception& e) const { return (*this)(e.what()); }
private:
const std::string m_reason;