1#include <test/jtx/CheckMessageLogs.h>
2#include <test/jtx/Env.h>
3#include <test/jtx/envconfig.h>
4#include <test/nodestore/TestBase.h>
5#include <test/unit_test/SuiteJournal.h>
7#include <xrpld/core/Config.h>
9#include <xrpl/basics/ByteUtilities.h>
10#include <xrpl/beast/unit_test/suite.h>
11#include <xrpl/beast/utility/Journal.h>
12#include <xrpl/beast/utility/temp_dir.h>
13#include <xrpl/beast/xor_shift_engine.h>
14#include <xrpl/config/BasicConfig.h>
15#include <xrpl/config/Constants.h>
16#include <xrpl/nodestore/Database.h>
17#include <xrpl/nodestore/DummyScheduler.h>
18#include <xrpl/nodestore/Manager.h>
19#include <xrpl/nodestore/Types.h>
20#include <xrpl/protocol/SystemParameters.h>
21#include <xrpl/rdb/DatabaseCon.h>
50 auto const integrityWarning =
51 "reducing the data integrity guarantees from the "
52 "default [sqlite] behavior is not recommended for "
53 "nodes storing large amounts of history, because of the "
54 "difficulty inherent in rebuilding corrupted data.";
61 if (BEAST_EXPECT(s.globalPragma->size() == 3))
63 BEAST_EXPECT(s.globalPragma->at(0) ==
"PRAGMA journal_mode=wal;");
64 BEAST_EXPECT(s.globalPragma->at(1) ==
"PRAGMA synchronous=normal;");
65 BEAST_EXPECT(s.globalPragma->at(2) ==
"PRAGMA temp_store=file;");
79 p->ledgerHistory = 100'000'000;
90 if (BEAST_EXPECT(s.globalPragma->size() == 3))
92 BEAST_EXPECT(s.globalPragma->at(0) ==
"PRAGMA journal_mode=wal;");
93 BEAST_EXPECT(s.globalPragma->at(1) ==
"PRAGMA synchronous=normal;");
94 BEAST_EXPECT(s.globalPragma->at(2) ==
"PRAGMA temp_store=file;");
108 p->ledgerHistory = 100'000'000;
119 if (BEAST_EXPECT(s.globalPragma->size() == 3))
121 BEAST_EXPECT(s.globalPragma->at(0) ==
"PRAGMA journal_mode=memory;");
122 BEAST_EXPECT(s.globalPragma->at(1) ==
"PRAGMA synchronous=off;");
123 BEAST_EXPECT(s.globalPragma->at(2) ==
"PRAGMA temp_store=memory;");
149 BEAST_EXPECT(!found);
151 if (BEAST_EXPECT(s.globalPragma->size() == 3))
153 BEAST_EXPECT(s.globalPragma->at(0) ==
"PRAGMA journal_mode=off;");
154 BEAST_EXPECT(s.globalPragma->at(1) ==
"PRAGMA synchronous=extra;");
155 BEAST_EXPECT(s.globalPragma->at(2) ==
"PRAGMA temp_store=default;");
171 p->ledgerHistory = 50'000'000;
184 if (BEAST_EXPECT(s.globalPragma->size() == 3))
186 BEAST_EXPECT(s.globalPragma->at(0) ==
"PRAGMA journal_mode=off;");
187 BEAST_EXPECT(s.globalPragma->at(1) ==
"PRAGMA synchronous=extra;");
188 BEAST_EXPECT(s.globalPragma->at(2) ==
"PRAGMA temp_store=default;");
194 auto const expected =
195 "Failed to initialize SQL databases: "
196 "Configuration file may not define both \"safety_level\" and "
226 auto const expected =
227 "Failed to initialize SQL databases: Configuration file may "
228 "not define both \"safety_level\" and \"journal_mode\"";
255 auto const expected =
256 "Failed to initialize SQL databases: Configuration file may "
257 "not define both \"safety_level\" and \"synchronous\"";
284 auto const expected =
285 "Failed to initialize SQL databases: Configuration file may "
286 "not define both \"safety_level\" and \"temp_store\"";
313 auto const expected =
314 "Failed to initialize SQL databases: Invalid safety_level "
341 auto const expected =
342 "Failed to initialize SQL databases: Invalid journal_mode "
369 auto const expected =
370 "Failed to initialize SQL databases: Invalid synchronous "
397 auto const expected =
398 "Failed to initialize SQL databases: Invalid temp_store "
426 if (BEAST_EXPECT(s.txPragma.size() == 4))
428 BEAST_EXPECT(s.txPragma.at(0) ==
"PRAGMA page_size=4096;");
429 BEAST_EXPECT(s.txPragma.at(1) ==
"PRAGMA journal_size_limit=1582080;");
430 BEAST_EXPECT(s.txPragma.at(2) ==
"PRAGMA max_page_count=4294967294;");
431 BEAST_EXPECT(s.txPragma.at(3) ==
"PRAGMA mmap_size=17179869184;");
443 return Env(*
this, std::move(p));
446 if (BEAST_EXPECT(s.txPragma.size() == 4))
448 BEAST_EXPECT(s.txPragma.at(0) ==
"PRAGMA page_size=512;");
449 BEAST_EXPECT(s.txPragma.at(1) ==
"PRAGMA journal_size_limit=2582080;");
450 BEAST_EXPECT(s.txPragma.at(2) ==
"PRAGMA max_page_count=4294967294;");
451 BEAST_EXPECT(s.txPragma.at(3) ==
"PRAGMA mmap_size=17179869184;");
456 auto const expected =
"Invalid page_size. Must be between 512 and 65536.";
479 auto const expected =
"Invalid page_size. Must be between 512 and 65536.";
502 auto const expected =
"Invalid page_size. Must be a power of 2.";
566 testcase(
"import into '" + destBackendType +
"' from '" + srcBackendType +
"'");
569 dest->importDatabase(*src);
586 bool const testPersistence,
588 int numObjsToTest = 2000)
592 std::string const s =
"NodeStore backend '" + type +
"'";
646 if (type ==
"memory")
674 BEAST_EXPECT(db->earliestLedgerSeq() == 1);
687 BEAST_EXPECT(
std::strcmp(e.
what(),
"earliest_seq set more than once") == 0);
707#if XRPL_ROCKSDB_AVAILABLE
716#if XRPL_ROCKSDB_AVAILABLE
720#if XRPL_ENABLE_SQLITE_BACKEND_TESTS
RAII temporary directory.
std::string path() const
Get the native path for the temporary directory.
void fail(String const &reason, char const *file, int line)
Record a failure.
TestcaseT testcase
Memberspace for declaring test cases.
virtual Config & config()=0
void run() override
Runs the suite.
void testImport(std::string const &destBackendType, std::string const &srcBackendType, std::int64_t seedValue)
void testNodeStore(std::string const &type, bool const testPersistence, std::int64_t const seedValue, int numObjsToTest=2000)
test::SuiteJournal journal_
Persistency layer for NodeObject.
Simple NodeStore Scheduler that just performs the tasks synchronously.
static Manager & instance()
Returns the instance of the manager singleton.
virtual std::unique_ptr< Database > makeDatabase(std::size_t burstSize, Scheduler &scheduler, int readThreads, Section const &backendParameters, beast::Journal journal)=0
Construct a NodeStore database.
static bool areBatchesEqual(Batch const &lhs, Batch const &rhs)
void fetchCopyOfBatch(Backend &backend, Batch *pCopy, Batch const &batch)
static void storeBatch(Backend &backend, Batch const &batch)
static Batch createPredictableBatch(int numObjects, std::uint64_t seed)
static int const kNumObjectsToTest
Holds a collection of configuration values.
void set(std::string const &key, std::string const &value)
Set a key/value pair.
A transaction testing environment.
detail::XorShiftEngine<> xor_shift_engine
XOR-shift Generator.
BEAST_DEFINE_TESTSUITE(Backend, nodestore, xrpl)
std::vector< std::shared_ptr< NodeObject > > Batch
A batch of NodeObjects to write at once.
Helpers for constructing Batch test transactions.
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
constexpr auto megabytes(T value) noexcept
DatabaseCon::Setup setupDatabaseCon(Config const &c, std::optional< beast::Journal > j=std::nullopt)
static constexpr std::uint32_t kXrpLedgerEarliestSeq
The XRP ledger network's earliest allowed sequence.
static std::unique_ptr< std::vector< std::string > const > globalPragma
static constexpr auto kPageSize
static constexpr auto kSafetyLevel
static constexpr auto kTempStore
static constexpr auto kJournalMode
static constexpr auto kSynchronous
static constexpr auto kJournalSizeLimit
static constexpr auto kType
static constexpr auto kPath
static constexpr auto kEarliestSeq
Binary function that satisfies the strict-weak-ordering requirement.
static constexpr auto kSqlite