17#include <boost/test/unit_test.hpp>
26 for (
const bool obfuscate : {
false,
true}) {
27 constexpr size_t CACHE_SIZE{1_MiB};
28 const fs::path path{m_args.GetDataDirBase() /
"dbwrapper"};
31 std::vector<std::pair<uint8_t, uint256>> key_values{};
35 CDBWrapper dbw{{.path = path, .cache_bytes = CACHE_SIZE, .wipe_data =
true, .obfuscate = obfuscate}};
42 for (uint8_t
k{0};
k < 10; ++
k) {
45 dbw.Write(key, value);
46 key_values.emplace_back(key, value);
52 CDBWrapper dbw{{.path = path, .cache_bytes = CACHE_SIZE, .obfuscate =
false}};
58 CDBWrapper dbw{{.path = path, .cache_bytes = CACHE_SIZE, .obfuscate = obfuscate}};
65 for (
const auto& [key, expected_value] : key_values) {
77 for (
bool obfuscate : {
false,
true}) {
78 fs::path ph = m_args.GetDataDirBase() / (obfuscate ?
"dbwrapper_1_obfuscate_true" :
"dbwrapper_1_obfuscate_false");
79 CDBWrapper dbw({.path = ph, .cache_bytes = 1_MiB, .memory_only =
false, .wipe_data =
true, .obfuscate = obfuscate});
89 std::string key_block =
"b" + m_rng.rand256().ToString();
91 uint256 in_block = m_rng.rand256();
92 dbw.Write(key_block, in_block);
97 std::string key_file =
strprintf(
"f%04x", m_rng.rand32());
99 uint256 in_file_info = m_rng.rand256();
100 dbw.Write(key_file, in_file_info);
105 std::string key_transaction =
"t" + m_rng.rand256().ToString();
107 uint256 in_transaction = m_rng.rand256();
108 dbw.Write(key_transaction, in_transaction);
113 std::string key_utxo =
"c" + m_rng.rand256().ToString();
115 uint256 in_utxo = m_rng.rand256();
116 dbw.Write(key_utxo, in_utxo);
121 uint8_t key_last_blockfile_number{
'l'};
122 uint32_t lastblockfilenumber = m_rng.rand32();
123 dbw.Write(key_last_blockfile_number, lastblockfilenumber);
124 BOOST_CHECK(dbw.Read(key_last_blockfile_number, res_uint_32));
128 uint8_t key_IsReindexing{
'R'};
129 bool isInReindexing = m_rng.randbool();
130 dbw.Write(key_IsReindexing, isInReindexing);
135 uint8_t key_lastblockhash_uxto{
'B'};
136 uint256 lastblock_hash = m_rng.rand256();
137 dbw.Write(key_lastblockhash_uxto, lastblock_hash);
138 BOOST_CHECK(dbw.Read(key_lastblockhash_uxto, res));
142 std::string file_option_tag =
"F";
143 uint8_t filename_length = m_rng.randbits(8);
144 std::string filename =
"randomfilename";
145 std::string key_file_option =
strprintf(
"%s%01x%s", file_option_tag, filename_length, filename);
147 bool in_file_bool = m_rng.randbool();
148 dbw.Write(key_file_option, in_file_bool);
158 for (
const bool obfuscate : {
false,
true}) {
159 fs::path ph = m_args.GetDataDirBase() / (obfuscate ?
"dbwrapper_batch_obfuscate_true" :
"dbwrapper_batch_obfuscate_false");
160 CDBWrapper dbw({.path = ph, .cache_bytes = 1_MiB, .memory_only =
true, .wipe_data =
false, .obfuscate = obfuscate});
172 batch.
Write(key, in);
173 batch.
Write(key2, in2);
174 batch.
Write(key3, in3);
179 dbw.WriteBatch(batch);
190 batch.
Write(key3, in3);
191 dbw.WriteBatch(batch);
202 for (
const bool obfuscate : {
false,
true}) {
203 const fs::path path{m_args.GetDataDirBase() / (obfuscate ?
"dbwrapper_deser_obf" :
"dbwrapper_deser_noobf")};
204 CDBWrapper dbw({.path = path, .cache_bytes = 1 << 20, .wipe_data =
true, .obfuscate = obfuscate});
206 constexpr uint8_t key{
'X'};
210 dbw.
Write(key, uint8_t{0xFF});
223 const fs::path path{m_args.GetDataDirBase() /
"dbwrapper_db_error"};
224 constexpr uint8_t key{
'Y'};
226 const auto make_db = [] (
const fs::path& path,
const bool force_compact) {
227 return CDBWrapper({.path = path, .cache_bytes = 1 << 20, .obfuscate =
false,
228 .options = {.force_compact = force_compact}});
232 make_db(path,
false).
Write(key, m_rng.rand256());
236 (void)make_db(path,
true);
239 for (
const auto& entry : fs::directory_iterator(path)) {
240 if (entry.path().extension() ==
".ldb") {
241 std::ofstream{entry.path(), std::ios::binary | std::ios::trunc}
247 const auto db{make_db(path,
false)};
253 BOOST_REQUIRE(!status);
255 BOOST_CHECK(status.
error().err_msg.find(
"Fatal LevelDB error") != std::string::npos);
262 for (
const bool obfuscate : {
false,
true}) {
263 const fs::path path{m_args.GetDataDirBase() / (obfuscate ?
"dbwrapper_tryread_obf" :
"dbwrapper_tryread_noobf")};
264 CDBWrapper dbw({.path = path, .cache_bytes = 1 << 20, .wipe_data =
true, .obfuscate = obfuscate});
266 constexpr uint8_t key_ok{
'A'};
267 constexpr uint8_t key_missing{
'B'};
268 constexpr uint8_t key_bad{
'C'};
270 uint256 written_value{m_rng.rand256()};
271 dbw.Write(key_ok, written_value);
272 dbw.Write(key_bad, uint8_t{0xFF});
278 BOOST_REQUIRE(status);
287 BOOST_REQUIRE(status);
295 BOOST_REQUIRE(!status);
305 for (
const bool obfuscate : {
false,
true}) {
306 fs::path ph = m_args.GetDataDirBase() / (obfuscate ?
"dbwrapper_iterator_obfuscate_true" :
"dbwrapper_iterator_obfuscate_false");
307 CDBWrapper dbw({.path = ph, .cache_bytes = 1_MiB, .memory_only =
true, .wipe_data =
false, .obfuscate = obfuscate});
315 dbw.Write(key2, in2);
317 std::unique_ptr<CDBIterator> it(dbw.NewIterator());
323 uint16_t key_too_large{0};
328 BOOST_REQUIRE(it->GetKey(key_res));
331 std::pair<uint256, uint8_t> value_too_large;
335 BOOST_REQUIRE(it->GetValue(val_res));
340 BOOST_REQUIRE(it->GetKey(key_res));
342 BOOST_REQUIRE(it->GetValue(val_res));
347 BOOST_REQUIRE(it->GetKey(key_res));
349 BOOST_REQUIRE(it->GetValue(val_res));
354 BOOST_REQUIRE(it->GetKey(key_res));
356 BOOST_REQUIRE(it->GetValue(val_res));
368 fs::path ph = m_args.GetDataDirBase() /
"existing_data_no_obfuscate";
369 fs::create_directories(ph);
372 std::unique_ptr<CDBWrapper> dbw = std::make_unique<CDBWrapper>(
DBParams{.
path = ph, .cache_bytes = 1 << 10, .memory_only =
false, .wipe_data =
false, .obfuscate =
false});
385 CDBWrapper odbw({.path = ph, .cache_bytes = 1 << 10, .memory_only =
false, .wipe_data =
false, .obfuscate =
true});
400 odbw.Write(key, in2);
409 fs::path ph = m_args.GetDataDirBase() /
"existing_data_reindex";
410 fs::create_directories(ph);
413 std::unique_ptr<CDBWrapper> dbw = std::make_unique<CDBWrapper>(
DBParams{.
path = ph, .cache_bytes = 1 << 10, .memory_only =
false, .wipe_data =
false, .obfuscate =
false});
426 CDBWrapper odbw({.path = ph, .cache_bytes = 1 << 10, .memory_only =
false, .wipe_data =
true, .obfuscate =
true});
437 odbw.Write(key, in2);
444 fs::path ph = m_args.GetDataDirBase() /
"iterator_ordering";
445 CDBWrapper dbw({.path = ph, .cache_bytes = 1_MiB, .memory_only =
true, .wipe_data =
false, .obfuscate =
false});
446 for (
int x=0x00; x<256; ++x) {
448 uint32_t value = x*x;
449 if (!(x & 1)) dbw.
Write(key, value);
453 std::unique_ptr<CDBIterator> it(
const_cast<CDBWrapper&
>(dbw).NewIterator());
455 for (
unsigned int x=0x00; x<256; ++x) {
457 uint32_t value = x*x;
458 if (x & 1) dbw.Write(key, value);
461 for (
const int seek_start : {0x00, 0x80}) {
462 it->Seek((uint8_t)seek_start);
463 for (
unsigned int x=seek_start; x<255; ++x) {
490 template<
typename Stream>
493 for (
size_t i = 0; i <
str.size(); i++) {
494 s << uint8_t(
str[i]);
498 template<
typename Stream>
512 fs::path ph = m_args.GetDataDirBase() /
"iterator_string_ordering";
513 CDBWrapper dbw({.path = ph, .cache_bytes = 1_MiB, .memory_only =
true, .wipe_data =
false, .obfuscate =
false});
514 for (
int x = 0; x < 10; ++x) {
515 for (
int y = 0; y < 10; ++y) {
517 for (
int z = 0; z < y; ++z)
519 uint32_t value = x*x;
524 std::unique_ptr<CDBIterator> it(
const_cast<CDBWrapper&
>(dbw).NewIterator());
525 for (
const int seek_start : {0, 5}) {
527 for (
unsigned int x = seek_start; x < 10; ++x) {
528 for (
int y = 0; y < 10; ++y) {
530 for (
int z = 0; z < y; ++z)
554 fs::path ph = m_args.GetDataDirBase() /
"test_runner_₿_🏃_20191128_104644";
555 CDBWrapper dbw({.path = ph, .cache_bytes = 1_MiB});
557 fs::path lockPath = ph /
"LOCK";
Batch of changes queued to be written to a CDBWrapper.
void Write(const K &key, const V &value)
bool Read(const K &key, V &value) const
Wrapper around TryRead() that preserves the original Read() semantics: returns true on success,...
void Write(const K &key, const V &value, bool fSync=false)
ReadStatus TryRead(const K &key, V &value) const
Read and deserialize a value from the database, with explicit error discrimination.
BOOST_CHECK_EXCEPTION predicates to check the specific validation error.
std::string ToString() const
The util::Expected class provides a standard way for low-level functions to return either error value...
constexpr const T & value() const &LIFETIMEBOUND
constexpr const E & error() const &noexcept LIFETIMEBOUND
BOOST_FIXTURE_TEST_SUITE(cuckoocache_tests, BasicTestingSetup)
Test Suite for CuckooCache.
BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_CASE(dbwrapper)
static bool exists(const path &p)
BOOST_CHECK_EQUAL(headers.FindFirst("key"), "value")
BOOST_CHECK_EXCEPTION(HTTPHeaders{}.Read(reader), std::runtime_error, HasReason{"Empty HTTP header name"})
const Obfuscation & GetObfuscation(const CDBWrapper &w)
Work around circular dependency, as well as for testing in dbwrapper_tests.
std::string ToString(const T &t)
Locale-independent version of std::to_string.
#define BOOST_CHECK(expr)
@ DeserializationError
Key exists but value could not be deserialized.
@ DatabaseError
Unexpected internal DB error.
Application-specific storage settings.
fs::path path
Location in the filesystem where leveldb data will be stored.
StringContentsSerializer()=default
void Unserialize(Stream &s)
void Serialize(Stream &s) const
StringContentsSerializer(const std::string &inp)