summaryrefslogtreecommitdiff
path: root/protocols/Telegram/tdlib/td/test/db.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/Telegram/tdlib/td/test/db.cpp')
-rw-r--r--protocols/Telegram/tdlib/td/test/db.cpp112
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;