diff options
Diffstat (limited to 'protocols/Telegram/tdlib/td/test/db.cpp')
-rw-r--r-- | protocols/Telegram/tdlib/td/test/db.cpp | 112 |
1 files changed, 87 insertions, 25 deletions
diff --git a/protocols/Telegram/tdlib/td/test/db.cpp b/protocols/Telegram/tdlib/td/test/db.cpp index 61757e9893..9e56e331f4 100644 --- a/protocols/Telegram/tdlib/td/test/db.cpp +++ b/protocols/Telegram/tdlib/td/test/db.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -30,6 +30,7 @@ #include "td/utils/Random.h" #include "td/utils/Slice.h" #include "td/utils/Status.h" +#include "td/utils/StringBuilder.h" #include "td/utils/tests.h" #include <limits> @@ -62,6 +63,7 @@ TEST(DB, binlog_encryption_bug) { binlog_name.str(), [&](const td::BinlogEvent &x) {}, cucumber) .ensure(); } + td::Binlog::destroy(binlog_name).ignore(); } TEST(DB, binlog_encryption) { @@ -75,21 +77,22 @@ TEST(DB, binlog_encryption) { { td::Binlog binlog; binlog.init(binlog_name.str(), [](const td::BinlogEvent &x) {}).ensure(); - binlog.add_raw_event(td::BinlogEvent::create_raw(binlog.next_id(), 1, 0, td::create_storer("AAAA")), + binlog.add_raw_event(td::BinlogEvent::create_raw(binlog.next_event_id(), 1, 0, td::create_storer("AAAA")), td::BinlogDebugInfo{__FILE__, __LINE__}); - binlog.add_raw_event(td::BinlogEvent::create_raw(binlog.next_id(), 1, 0, td::create_storer("BBBB")), + binlog.add_raw_event(td::BinlogEvent::create_raw(binlog.next_event_id(), 1, 0, td::create_storer("BBBB")), td::BinlogDebugInfo{__FILE__, __LINE__}); - binlog.add_raw_event(td::BinlogEvent::create_raw(binlog.next_id(), 1, 0, td::create_storer(long_data)), + binlog.add_raw_event(td::BinlogEvent::create_raw(binlog.next_event_id(), 1, 0, td::create_storer(long_data)), td::BinlogDebugInfo{__FILE__, __LINE__}); LOG(INFO) << "SET PASSWORD"; binlog.change_key(cucumber); binlog.change_key(hello); LOG(INFO) << "OK"; - binlog.add_raw_event(td::BinlogEvent::create_raw(binlog.next_id(), 1, 0, td::create_storer("CCCC")), + binlog.add_raw_event(td::BinlogEvent::create_raw(binlog.next_event_id(), 1, 0, td::create_storer("CCCC")), td::BinlogDebugInfo{__FILE__, __LINE__}); binlog.close().ensure(); } + td::Binlog::destroy(binlog_name).ignore(); return; auto add_suffix = [&] { @@ -105,7 +108,7 @@ TEST(DB, binlog_encryption) { td::Binlog binlog; binlog .init( - binlog_name.str(), [&](const td::BinlogEvent &x) { v.push_back(x.data_.str()); }, hello) + binlog_name.str(), [&](const td::BinlogEvent &x) { v.push_back(x.get_data().str()); }, hello) .ensure(); CHECK(v == td::vector<td::string>({"AAAA", "BBBB", long_data, "CCCC"})); } @@ -117,7 +120,7 @@ TEST(DB, binlog_encryption) { LOG(INFO) << "RESTART"; td::Binlog binlog; auto status = binlog.init( - binlog_name.str(), [&](const td::BinlogEvent &x) { v.push_back(x.data_.str()); }, cucumber); + binlog_name.str(), [&](const td::BinlogEvent &x) { v.push_back(x.get_data().str()); }, cucumber); CHECK(status.is_error()); } @@ -128,9 +131,11 @@ TEST(DB, binlog_encryption) { LOG(INFO) << "RESTART"; td::Binlog binlog; auto status = binlog.init( - binlog_name.str(), [&](const td::BinlogEvent &x) { v.push_back(x.data_.str()); }, cucumber, hello); + binlog_name.str(), [&](const td::BinlogEvent &x) { v.push_back(x.get_data().str()); }, cucumber, hello); CHECK(v == td::vector<td::string>({"AAAA", "BBBB", long_data, "CCCC"})); } + + td::Binlog::destroy(binlog_name).ignore(); } TEST(DB, sqlite_lfs) { @@ -264,13 +269,32 @@ TEST(DB, sqlite_encryption_migrate_v4) { using SeqNo = td::uint64; struct DbQuery { - enum class Type { Get, Set, Erase } type = Type::Get; + enum class Type { Get, Set, Erase, EraseBatch } type = Type::Get; SeqNo tid = 0; - td::int32 id = 0; td::string key; td::string value; + + // for EraseBatch + td::vector<td::string> erased_keys; }; +static td::StringBuilder &operator<<(td::StringBuilder &string_builder, const DbQuery &query) { + string_builder << "seq_no = " << query.tid << ": "; + switch (query.type) { + case DbQuery::Type::Get: + return string_builder << "Get " << query.key << " = " << query.value; + case DbQuery::Type::Set: + return string_builder << "Set " << query.key << " = " << query.value; + case DbQuery::Type::Erase: + return string_builder << "Del " << query.key; + case DbQuery::Type::EraseBatch: + return string_builder << "Del " << query.erased_keys; + default: + UNREACHABLE(); + return string_builder; + } +} + template <class ImplT> class QueryHandler { public: @@ -290,6 +314,10 @@ class QueryHandler { impl_.erase(query.key); query.tid = 1; return; + case DbQuery::Type::EraseBatch: + impl_.erase_batch(query.erased_keys); + query.tid = 1; + return; } } @@ -314,6 +342,9 @@ class SeqQueryHandler { case DbQuery::Type::Erase: query.tid = impl_.erase(query.key); return; + case DbQuery::Type::EraseBatch: + query.tid = impl_.erase_batch(query.erased_keys); + return; } } @@ -334,6 +365,12 @@ class SqliteKV { kv_->get().erase(key); return 0; } + SeqNo erase_batch(td::vector<td::string> keys) { + for (auto &key : keys) { + kv_->get().erase(key); + } + return 0; + } td::Status init(const td::string &name) { auto sql_connection = std::make_shared<td::SqliteConnectionSafe>(name, td::DbKey::empty()); kv_ = std::make_shared<td::SqliteKeyValueSafe>("kv", sql_connection); @@ -360,6 +397,14 @@ class BaselineKV { map_.erase(key); return ++current_tid_; } + SeqNo erase_batch(td::vector<td::string> keys) { + for (auto &key : keys) { + map_.erase(key); + } + SeqNo result = current_tid_ + 1; + current_tid_ += map_.size(); + return result; + } private: std::map<td::string, td::string> map_; @@ -380,9 +425,8 @@ TEST(DB, key_value) { int queries_n = 1000; td::vector<DbQuery> queries(queries_n); for (auto &q : queries) { - int op = td::Random::fast(0, 2); + int op = td::Random::fast(0, 3); const auto &key = rand_elem(keys); - const auto &value = rand_elem(values); if (op == 0) { q.type = DbQuery::Type::Get; q.key = key; @@ -392,7 +436,13 @@ TEST(DB, key_value) { } else if (op == 2) { q.type = DbQuery::Type::Set; q.key = key; - q.value = value; + q.value = rand_elem(values); + } else if (op == 3) { + q.type = DbQuery::Type::EraseBatch; + q.erased_keys.resize(td::Random::fast(0, 3)); + for (auto &erased_key : q.erased_keys) { + erased_key = rand_elem(keys); + } } } @@ -494,17 +544,22 @@ TEST(DB, thread_key_value) { for (auto &q : qs) { int op = td::Random::fast(0, 10); const auto &key = rand_elem(keys); - const auto &value = rand_elem(values); - if (op > 1) { - q.type = DbQuery::Type::Get; - q.key = key; - } else if (op == 0) { + if (op == 0) { q.type = DbQuery::Type::Erase; q.key = key; } else if (op == 1) { + q.type = DbQuery::Type::EraseBatch; + q.erased_keys.resize(td::Random::fast(0, 3)); + for (auto &erased_key : q.erased_keys) { + erased_key = rand_elem(keys); + } + } else if (op <= 6) { q.type = DbQuery::Type::Set; q.key = key; - q.value = value; + q.value = rand_elem(values); + } else { + q.type = DbQuery::Type::Get; + q.key = key; } } } @@ -606,17 +661,22 @@ TEST(DB, persistent_key_value) { for (auto &q : qs) { int op = td::Random::fast(0, 10); const auto &key = rand_elem(keys); - const auto &value = rand_elem(values); - if (op > 1) { - q.type = DbQuery::Type::Get; - q.key = key; - } else if (op == 0) { + if (op == 0) { q.type = DbQuery::Type::Erase; q.key = key; } else if (op == 1) { + q.type = DbQuery::Type::EraseBatch; + q.erased_keys.resize(td::Random::fast(0, 3)); + for (auto &erased_key : q.erased_keys) { + erased_key = rand_elem(keys); + } + } else if (op <= 6) { q.type = DbQuery::Type::Set; q.key = key; - q.value = value; + q.value = rand_elem(values); + } else { + q.type = DbQuery::Type::Get; + q.key = key; } } } @@ -718,6 +778,7 @@ TEST(DB, persistent_key_value) { if (was) { continue; } + LOG(DEBUG) << pos; int best = -1; SeqNo best_tid = 0; @@ -728,6 +789,7 @@ TEST(DB, persistent_key_value) { } was = true; auto &q = res[i][p]; + LOG(DEBUG) << i << ' ' << p << ' ' << q; if (q.tid != 0) { if (best == -1 || q.tid < best_tid) { best = i; |