From b014dbdf2ddca264f2494f3c85631a40fd9bbc35 Mon Sep 17 00:00:00 2001 From: Ivan Baidakou Date: Sat, 15 Jun 2024 23:05:05 +0300 Subject: [PATCH] core: db_actor, process remove_peer; add tests --- src/model/diff/modify/remove_peer.cpp | 10 ++-- src/model/diff/modify/remove_peer.h | 2 +- src/net/db_actor.cpp | 25 ++++++++++ src/net/db_actor.h | 1 + tests/039-diff-remove-peer.cpp | 4 +- tests/070-db.cpp | 66 +++++++++++++++++++++++++++ tests/diff-builder.cpp | 3 +- tests/diff-builder.h | 2 +- 8 files changed, 101 insertions(+), 12 deletions(-) diff --git a/src/model/diff/modify/remove_peer.cpp b/src/model/diff/modify/remove_peer.cpp index 42b73bb9..3417c4cc 100644 --- a/src/model/diff/modify/remove_peer.cpp +++ b/src/model/diff/modify/remove_peer.cpp @@ -29,7 +29,7 @@ static auto make_unshare(const cluster_t &cluster, const device_t &peer, blocks_ } remove_peer_t::remove_peer_t(const cluster_t &cluster, const device_t &peer) noexcept - : aggregate_t(), peer_id{peer.device_id().get_sha256()} { + : aggregate_t(), peer_key{peer.get_key()} { auto removed_blocks = blocks_t{}; @@ -52,7 +52,9 @@ remove_peer_t::remove_peer_t(const cluster_t &cluster, const device_t &peer) noe } auto remove_peer_t::apply_impl(cluster_t &cluster) const noexcept -> outcome::result { - auto peer = cluster.get_devices().by_sha256(peer_id); + auto sha256 = peer_key.substr(1); + assert(sha256.size() == device_id_t::digest_length); + auto peer = cluster.get_devices().by_sha256(sha256); if (!peer) { return make_error_code(error_code_t::device_does_not_exist); } @@ -73,9 +75,5 @@ auto remove_peer_t::apply_impl(cluster_t &cluster) const noexcept -> outcome::re auto remove_peer_t::visit(cluster_visitor_t &visitor, void *custom) const noexcept -> outcome::result { LOG_TRACE(log, "visiting remove_peer_t"); - auto r = aggregate_t::visit(visitor, custom); - if (!r) { - return r; - } return visitor(*this, custom); } diff --git a/src/model/diff/modify/remove_peer.h b/src/model/diff/modify/remove_peer.h index c160f781..77fd0f67 100644 --- a/src/model/diff/modify/remove_peer.h +++ b/src/model/diff/modify/remove_peer.h @@ -14,7 +14,7 @@ struct SYNCSPIRIT_API remove_peer_t final : aggregate_t { outcome::result apply_impl(cluster_t &) const noexcept override; outcome::result visit(cluster_visitor_t &, void *) const noexcept override; - std::string peer_id; + std::string peer_key; }; } // namespace syncspirit::model::diff::modify diff --git a/src/net/db_actor.cpp b/src/net/db_actor.cpp index ce7d4f13..b5664d6a 100644 --- a/src/net/db_actor.cpp +++ b/src/net/db_actor.cpp @@ -26,6 +26,7 @@ #include "model/diff/modify/remove_blocks.h" #include "model/diff/modify/remove_files.h" #include "model/diff/modify/remove_folder_infos.h" +#include "model/diff/modify/remove_peer.h" #include "model/diff/modify/remove_unknown_folders.h" #include "model/diff/modify/unshare_folder.h" #include "model/diff/modify/update_folder_info.h" @@ -470,6 +471,30 @@ auto db_actor_t::operator()(const model::diff::modify::unshare_folder_t &diff, v return commit(true); } +auto db_actor_t::operator()(const model::diff::modify::remove_peer_t &diff, void *custom) noexcept + -> outcome::result { + if (cluster->is_tainted()) { + return outcome::success(); + } + + auto txn_opt = get_txn(); + if (!txn_opt) { + return txn_opt.assume_error(); + } + auto &txn = *txn_opt.assume_value(); + + auto r = diff.model::diff::aggregate_t::visit(*this, custom); + if (r.has_error()) { + return r.assume_error(); + } + r = db::remove(diff.peer_key, txn); + if (!r) { + return r.assume_error(); + } + + return commit(true); +} + auto db_actor_t::operator()(const model::diff::modify::update_peer_t &diff, void *) noexcept -> outcome::result { if (cluster->is_tainted()) { return outcome::success(); diff --git a/src/net/db_actor.h b/src/net/db_actor.h index 5bcb0669..578b8f01 100644 --- a/src/net/db_actor.h +++ b/src/net/db_actor.h @@ -76,6 +76,7 @@ struct SYNCSPIRIT_API db_actor_t : public r::actor_base_t, private model::diff:: outcome::result operator()(const model::diff::modify::remove_files_t &, void *) noexcept override; outcome::result operator()(const model::diff::modify::remove_folder_infos_t &, void *) noexcept override; outcome::result operator()(const model::diff::modify::remove_unknown_folders_t &, void *) noexcept override; + outcome::result operator()(const model::diff::modify::remove_peer_t &, void *) noexcept override; outcome::result operator()(const model::diff::modify::unshare_folder_t &, void *) noexcept override; outcome::result operator()(const model::diff::modify::update_peer_t &, void *) noexcept override; outcome::result operator()(const model::diff::modify::update_folder_info_t &, void *) noexcept override; diff --git a/tests/039-diff-remove-peer.cpp b/tests/039-diff-remove-peer.cpp index c90c3c58..79ed3885 100644 --- a/tests/039-diff-remove-peer.cpp +++ b/tests/039-diff-remove-peer.cpp @@ -20,7 +20,7 @@ TEST_CASE("remove peer", "[model]") { auto peer_device = device_t::create(peer_id, "peer-device").value(); auto cluster = cluster_ptr_t(new cluster_t(my_device, 1, 1)); - auto& devices = cluster->get_devices(); + auto &devices = cluster->get_devices(); devices.put(my_device); devices.put(peer_device); @@ -162,7 +162,7 @@ TEST_CASE("remove peer", "[model]") { mfi->set_index_id(10); auto uf = unknown_folder_t::create(cluster->next_uuid(), db_uf, peer_device->device_id()).value(); - auto& unknown_folders = cluster->get_unknown_folders(); + auto &unknown_folders = cluster->get_unknown_folders(); unknown_folders.emplace_front(uf); REQUIRE(builder.remove_peer(*peer_device).apply()); CHECK(devices.size() == 1); diff --git a/tests/070-db.cpp b/tests/070-db.cpp index 566061f7..4bdc147b 100644 --- a/tests/070-db.cpp +++ b/tests/070-db.cpp @@ -633,6 +633,71 @@ void test_peer_going_offline() { F().run(); }; +void test_remove_peer() { + struct F : fixture_t { + void main() noexcept override { + auto sha256 = peer_device->device_id().get_sha256(); + auto folder_id = "1234-5678"; + auto unknown_folder_id = "5678-999"; + + auto file = proto::FileInfo(); + file.set_name("a.txt"); + file.set_size(5ul); + file.set_block_size(5ul); + file.set_sequence(6ul); + auto b = file.add_blocks(); + b->set_size(5ul); + b->set_hash(utils::sha256_digest("12345").value()); + + auto builder = diff_builder_t(*cluster); + builder.update_peer(sha256) + .apply(*sup) + .create_folder(folder_id, "/my/path") + .configure_cluster(sha256) + .add(sha256, folder_id, 5, file.sequence()) + .add(sha256, unknown_folder_id, 5, 5) + .finish() + .share_folder(sha256, folder_id) + .apply(*sup) + .make_index(sha256, folder_id) + .add(file) + .finish() + .apply(*sup); + + REQUIRE(!cluster->get_unknown_folders().empty()); + + REQUIRE(cluster->get_blocks().size() == 1); + auto block = cluster->get_blocks().get(b->hash()); + REQUIRE(block); + + auto folder = cluster->get_folders().by_id(folder_id); + auto peer_folder_info = folder->get_folder_infos().by_device(*peer_device); + + REQUIRE(peer_folder_info); + CHECK(peer_folder_info->get_max_sequence() == 6ul); + REQUIRE(peer_folder_info->get_file_infos().size() == 1); + auto peer_file = peer_folder_info->get_file_infos().by_name("a.txt"); + REQUIRE(peer_file); + + builder.remove_peer(*peer_device).apply(*sup); + + sup->request(db_addr).send(timeout); + sup->do_process(); + REQUIRE(reply); + REQUIRE(!reply->payload.ee); + + auto cluster_clone = make_cluster(); + { + REQUIRE(reply->payload.res.diff->apply(*cluster_clone)); + CHECK(cluster_clone->get_unknown_folders().empty()); + CHECK(cluster_clone->get_devices().size() == 1); + REQUIRE(cluster_clone->get_blocks().size() == 0); + } + } + }; + F().run(); +} + int _init() { REGISTER_TEST_CASE(test_loading_empty_db, "test_loading_empty_db", "[db]"); REGISTER_TEST_CASE(test_folder_creation, "test_folder_creation", "[db]"); @@ -643,6 +708,7 @@ int _init() { REGISTER_TEST_CASE(test_clone_file, "test_clone_file", "[db]"); REGISTER_TEST_CASE(test_local_update, "test_local_update", "[db]"); REGISTER_TEST_CASE(test_peer_going_offline, "test_peer_going_offline", "[db]"); + REGISTER_TEST_CASE(test_remove_peer, "test_remove_peer", "[db]"); return 1; } diff --git a/tests/diff-builder.cpp b/tests/diff-builder.cpp index d8ee93ad..1c67d825 100644 --- a/tests/diff-builder.cpp +++ b/tests/diff-builder.cpp @@ -172,12 +172,11 @@ diff_builder_t &diff_builder_t::local_update(std::string_view folder_id, const p return *this; } -diff_builder_t &diff_builder_t::remove_peer(const model::device_t& peer) noexcept { +diff_builder_t &diff_builder_t::remove_peer(const model::device_t &peer) noexcept { diffs.emplace_back(new diff::modify::remove_peer_t(cluster, peer)); return *this; } - diff_builder_t &diff_builder_t::append_block(const model::file_info_t &target, size_t block_index, std::string data, dispose_callback_t callback) noexcept { bdiffs.emplace_back(new diff::modify::append_block_t(target, block_index, std::move(data), std::move(callback))); diff --git a/tests/diff-builder.h b/tests/diff-builder.h index 602cd764..0ef3f210 100644 --- a/tests/diff-builder.h +++ b/tests/diff-builder.h @@ -69,7 +69,7 @@ struct SYNCSPIRIT_TEST_API diff_builder_t { dispose_callback_t) noexcept; diff_builder_t &clone_block(const model::file_block_t &, dispose_callback_t) noexcept; diff_builder_t &ack_block(const model::diff::modify::block_transaction_t &) noexcept; - diff_builder_t &remove_peer(const model::device_t& peer) noexcept; + diff_builder_t &remove_peer(const model::device_t &peer) noexcept; private: using bdiffs_t = std::deque;