070-db.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615
  1. // SPDX-License-Identifier: GPL-3.0-or-later
  2. // SPDX-FileCopyrightText: 2019-2023 Ivan Baidakou
  3. #include <catch2/catch_all.hpp>
  4. #include "test-utils.h"
  5. #include "diff-builder.h"
  6. #include "model/diff/peer/cluster_remove.h"
  7. #include "model/diff/modify/unshare_folder.h"
  8. #include "test_supervisor.h"
  9. #include "access.h"
  10. #include "model/cluster.h"
  11. #include "db/utils.h"
  12. #include "net/db_actor.h"
  13. #include "access.h"
  14. #include <boost/filesystem.hpp>
  15. using namespace syncspirit;
  16. using namespace syncspirit::db;
  17. using namespace syncspirit::test;
  18. using namespace syncspirit::model;
  19. using namespace syncspirit::net;
  20. namespace fs = boost::filesystem;
  21. namespace {
  22. struct env {};
  23. } // namespace
  24. namespace syncspirit::net {
  25. template <> inline auto &db_actor_t::access<env>() noexcept { return env; }
  26. } // namespace syncspirit::net
  27. namespace {
  28. struct fixture_t {
  29. using msg_t = net::message::load_cluster_response_t;
  30. using msg_ptr_t = r::intrusive_ptr_t<msg_t>;
  31. fixture_t() noexcept : root_path{bfs::unique_path()}, path_quard{root_path} { utils::set_default("trace"); }
  32. virtual supervisor_t::configure_callback_t configure() noexcept {
  33. return [&](r::plugin::plugin_base_t &plugin) {
  34. plugin.template with_casted<r::plugin::starter_plugin_t>(
  35. [&](auto &p) { p.subscribe_actor(r::lambda<msg_t>([&](msg_t &msg) { reply = &msg; })); });
  36. };
  37. }
  38. cluster_ptr_t make_cluster() noexcept {
  39. auto my_id =
  40. device_id_t::from_string("KHQNO2S-5QSILRK-YX4JZZ4-7L77APM-QNVGZJT-EKU7IFI-PNEPBMY-4MXFMQD").value();
  41. my_device = device_t::create(my_id, "my-device").value();
  42. return cluster_ptr_t(new cluster_t(my_device, 1, 1));
  43. }
  44. virtual void run() noexcept {
  45. auto peer_id =
  46. device_id_t::from_string("VUV42CZ-IQD5A37-RPEBPM4-VVQK6E4-6WSKC7B-PVJQHHD-4PZD44V-ENC6WAZ").value();
  47. peer_device = device_t::create(peer_id, "peer-device").value();
  48. cluster = make_cluster();
  49. auto root_path = bfs::unique_path();
  50. bfs::create_directory(root_path);
  51. auto root_path_guard = path_guard_t(root_path);
  52. r::system_context_t ctx;
  53. sup = ctx.create_supervisor<supervisor_t>().timeout(timeout).create_registry().finish();
  54. sup->cluster = cluster;
  55. sup->configure_callback = configure();
  56. sup->start();
  57. sup->do_process();
  58. CHECK(static_cast<r::actor_base_t *>(sup.get())->access<to::state>() == r::state_t::OPERATIONAL);
  59. auto db_config = config::db_config_t{1024 * 1024, 0};
  60. db_actor = sup->create_actor<db_actor_t>()
  61. .cluster(cluster)
  62. .db_dir(root_path.string())
  63. .db_config(db_config)
  64. .timeout(timeout)
  65. .finish();
  66. sup->do_process();
  67. CHECK(static_cast<r::actor_base_t *>(db_actor.get())->access<to::state>() == r::state_t::OPERATIONAL);
  68. db_addr = db_actor->get_address();
  69. main();
  70. reply.reset();
  71. sup->shutdown();
  72. sup->do_process();
  73. CHECK(static_cast<r::actor_base_t *>(sup.get())->access<to::state>() == r::state_t::SHUT_DOWN);
  74. }
  75. virtual void main() noexcept {}
  76. r::address_ptr_t db_addr;
  77. r::pt::time_duration timeout = r::pt::millisec{10};
  78. cluster_ptr_t cluster;
  79. device_ptr_t peer_device;
  80. device_ptr_t my_device;
  81. r::intrusive_ptr_t<supervisor_t> sup;
  82. r::intrusive_ptr_t<net::db_actor_t> db_actor;
  83. bfs::path root_path;
  84. path_guard_t path_quard;
  85. r::system_context_t ctx;
  86. msg_ptr_t reply;
  87. };
  88. } // namespace
  89. void test_db_migration() {
  90. struct F : fixture_t {
  91. void main() noexcept override {
  92. auto &db_env = db_actor->access<env>();
  93. auto txn_opt = db::make_transaction(db::transaction_type_t::RW, db_env);
  94. REQUIRE(txn_opt);
  95. auto &txn = txn_opt.value();
  96. auto load_opt = db::load(db::prefix::device, txn);
  97. REQUIRE(load_opt);
  98. auto &values = load_opt.value();
  99. REQUIRE(values.size() == 1);
  100. }
  101. };
  102. F().run();
  103. }
  104. void test_loading_empty_db() {
  105. struct F : fixture_t {
  106. void main() noexcept override {
  107. sup->request<net::payload::load_cluster_request_t>(db_addr).send(timeout);
  108. sup->do_process();
  109. REQUIRE(reply);
  110. auto diff = reply->payload.res.diff;
  111. REQUIRE(diff->apply(*cluster));
  112. auto devices = cluster->get_devices();
  113. REQUIRE(devices.size() == 1);
  114. REQUIRE(devices.by_sha256(cluster->get_device()->device_id().get_sha256()));
  115. }
  116. };
  117. F().run();
  118. }
  119. void test_folder_creation() {
  120. struct F : fixture_t {
  121. void main() noexcept override {
  122. auto folder_id = "1234-5678";
  123. auto builder = diff_builder_t(*cluster);
  124. builder.create_folder(folder_id, "/my/path", "my-label").apply(*sup);
  125. auto folder = cluster->get_folders().by_id(folder_id);
  126. REQUIRE(folder);
  127. REQUIRE(folder->get_folder_infos().by_device(*cluster->get_device()));
  128. sup->request<net::payload::load_cluster_request_t>(db_addr).send(timeout);
  129. sup->do_process();
  130. REQUIRE(reply);
  131. auto cluster_clone = make_cluster();
  132. REQUIRE(reply->payload.res.diff->apply(*cluster_clone));
  133. auto folder_clone = cluster_clone->get_folders().by_id(folder->get_id());
  134. REQUIRE(folder_clone);
  135. REQUIRE(folder.get() != folder_clone.get());
  136. REQUIRE(folder_clone->get_label() == "my-label");
  137. REQUIRE(folder_clone->get_path().string() == "/my/path");
  138. REQUIRE(folder_clone->get_folder_infos().size() == 1);
  139. REQUIRE(folder_clone->get_folder_infos().by_device(*cluster->get_device()));
  140. }
  141. };
  142. F().run();
  143. }
  144. void test_peer_updating() {
  145. struct F : fixture_t {
  146. void main() noexcept override {
  147. auto sha256 = peer_device->device_id().get_sha256();
  148. auto builder = diff_builder_t(*cluster);
  149. builder.update_peer(sha256, "some_name", "some-cn", true).apply(*sup);
  150. auto device = cluster->get_devices().by_sha256(sha256);
  151. REQUIRE(device);
  152. CHECK(device->get_name() == "some_name");
  153. CHECK(device->get_cert_name() == "some-cn");
  154. sup->request<net::payload::load_cluster_request_t>(db_addr).send(timeout);
  155. sup->do_process();
  156. REQUIRE(reply);
  157. auto cluster_clone = make_cluster();
  158. REQUIRE(reply->payload.res.diff->apply(*cluster_clone));
  159. REQUIRE(cluster_clone->get_devices().size() == 2);
  160. auto device_clone = cluster_clone->get_devices().by_sha256(sha256);
  161. REQUIRE(device_clone);
  162. REQUIRE(device.get() != device_clone.get());
  163. CHECK(device_clone->get_name() == "some_name");
  164. CHECK(device_clone->get_cert_name() == "some-cn");
  165. }
  166. };
  167. F().run();
  168. }
  169. void test_folder_sharing() {
  170. struct F : fixture_t {
  171. void main() noexcept override {
  172. auto sha256 = peer_device->device_id().get_sha256();
  173. auto folder_id = "1234-5678";
  174. auto builder = diff_builder_t(*cluster);
  175. builder.update_peer(sha256)
  176. .apply(*sup)
  177. .create_folder(folder_id, "/my/path")
  178. .configure_cluster(sha256)
  179. .add(sha256, folder_id, 5, 4)
  180. .finish()
  181. .share_folder(sha256, folder_id)
  182. .apply(*sup);
  183. CHECK(static_cast<r::actor_base_t *>(db_actor.get())->access<to::state>() == r::state_t::OPERATIONAL);
  184. sup->request<net::payload::load_cluster_request_t>(db_addr).send(timeout);
  185. sup->do_process();
  186. REQUIRE(reply);
  187. auto cluster_clone = make_cluster();
  188. REQUIRE(reply->payload.res.diff->apply(*cluster_clone));
  189. auto peer_device = cluster_clone->get_devices().by_sha256(sha256);
  190. REQUIRE(peer_device);
  191. auto folder = cluster_clone->get_folders().by_id(folder_id);
  192. REQUIRE(folder);
  193. REQUIRE(folder->get_folder_infos().size() == 2);
  194. auto fi = folder->get_folder_infos().by_device(*peer_device);
  195. REQUIRE(fi);
  196. CHECK(fi->get_index() == 5);
  197. CHECK(fi->get_max_sequence() == 4);
  198. }
  199. };
  200. F().run();
  201. }
  202. void test_cluster_update_and_remove() {
  203. struct F : fixture_t {
  204. void main() noexcept override {
  205. auto sha256 = peer_device->device_id().get_sha256();
  206. auto folder_id = "1234-5678";
  207. auto unknown_folder_id = "5678-999";
  208. auto file = proto::FileInfo();
  209. file.set_name("a.txt");
  210. file.set_size(5ul);
  211. file.set_block_size(5ul);
  212. file.set_sequence(6ul);
  213. auto b = file.add_blocks();
  214. b->set_size(5ul);
  215. b->set_hash(utils::sha256_digest("12345").value());
  216. auto builder = diff_builder_t(*cluster);
  217. builder.update_peer(sha256)
  218. .apply(*sup)
  219. .create_folder(folder_id, "/my/path")
  220. .configure_cluster(sha256)
  221. .add(sha256, folder_id, 5, file.sequence())
  222. .add(sha256, unknown_folder_id, 5, 5)
  223. .finish()
  224. .share_folder(sha256, folder_id)
  225. .apply(*sup)
  226. .make_index(sha256, folder_id)
  227. .add(file)
  228. .finish()
  229. .apply(*sup);
  230. REQUIRE(cluster->get_blocks().size() == 1);
  231. auto block = cluster->get_blocks().get(b->hash());
  232. REQUIRE(block);
  233. auto folder = cluster->get_folders().by_id(folder_id);
  234. auto peer_folder_info = folder->get_folder_infos().by_device(*peer_device);
  235. REQUIRE(peer_folder_info);
  236. CHECK(peer_folder_info->get_max_sequence() == 6ul);
  237. REQUIRE(peer_folder_info->get_file_infos().size() == 1);
  238. auto peer_file = peer_folder_info->get_file_infos().by_name("a.txt");
  239. REQUIRE(peer_file);
  240. auto &unknown_folders = cluster->get_unknown_folders();
  241. CHECK(std::distance(unknown_folders.begin(), unknown_folders.end()) == 1);
  242. sup->request<net::payload::load_cluster_request_t>(db_addr).send(timeout);
  243. sup->do_process();
  244. REQUIRE(reply);
  245. REQUIRE(!reply->payload.ee);
  246. auto cluster_clone = make_cluster();
  247. {
  248. REQUIRE(reply->payload.res.diff->apply(*cluster_clone));
  249. REQUIRE(cluster_clone->get_blocks().size() == 1);
  250. CHECK(cluster_clone->get_blocks().get(b->hash()));
  251. auto folder = cluster_clone->get_folders().by_id(folder_id);
  252. auto peer_folder_info = folder->get_folder_infos().by_device(*peer_device);
  253. REQUIRE(peer_folder_info);
  254. REQUIRE(peer_folder_info->get_file_infos().size() == 1);
  255. REQUIRE(peer_folder_info->get_file_infos().by_name("a.txt"));
  256. REQUIRE(!cluster_clone->get_unknown_folders().empty());
  257. }
  258. auto &uf = *cluster->get_unknown_folders().front();
  259. using keys_t = diff::peer::cluster_remove_t::keys_t;
  260. keys_t updated_folders{std::string(folder_id)};
  261. keys_t removed_folder_infos{std::string(peer_folder_info->get_key())};
  262. keys_t removed_files{std::string(peer_file->get_key())};
  263. keys_t removed_blocks{std::string(block->get_key())};
  264. keys_t removed_unknown_folders{std::string(uf.get_key())};
  265. auto diff = model::diff::cluster_diff_ptr_t{};
  266. diff = new diff::peer::cluster_remove_t(sha256, updated_folders, removed_folder_infos, removed_files,
  267. removed_blocks, removed_unknown_folders);
  268. sup->send<model::payload::model_update_t>(sup->get_address(), diff, nullptr);
  269. sup->do_process();
  270. sup->request<net::payload::load_cluster_request_t>(db_addr).send(timeout);
  271. sup->do_process();
  272. REQUIRE(reply);
  273. REQUIRE(!reply->payload.ee);
  274. cluster_clone = make_cluster();
  275. {
  276. REQUIRE(reply->payload.res.diff->apply(*cluster_clone));
  277. REQUIRE(cluster_clone->get_blocks().size() == 0);
  278. auto &fis = cluster_clone->get_folders().by_id(folder_id)->get_folder_infos();
  279. REQUIRE(fis.size() == 1);
  280. REQUIRE(!fis.by_device(*peer_device));
  281. REQUIRE(fis.by_device(*cluster->get_device()));
  282. REQUIRE(cluster_clone->get_unknown_folders().empty());
  283. }
  284. }
  285. };
  286. F().run();
  287. }
  288. void test_unsharing_folder() {
  289. struct F : fixture_t {
  290. void main() noexcept override {
  291. auto sha256 = peer_device->device_id().get_sha256();
  292. auto folder_id = "1234-5678";
  293. auto file = proto::FileInfo();
  294. file.set_name("a.txt");
  295. file.set_size(5ul);
  296. file.set_block_size(5ul);
  297. file.set_sequence(6ul);
  298. auto b = file.add_blocks();
  299. b->set_size(5ul);
  300. b->set_hash(utils::sha256_digest("12345").value());
  301. auto builder = diff_builder_t(*cluster);
  302. builder.update_peer(sha256)
  303. .apply(*sup)
  304. .create_folder(folder_id, "/my/path")
  305. .configure_cluster(sha256)
  306. .add(sha256, folder_id, 5, file.sequence())
  307. .finish()
  308. .share_folder(sha256, folder_id)
  309. .apply(*sup)
  310. .make_index(sha256, folder_id)
  311. .add(file)
  312. .finish()
  313. .apply(*sup);
  314. REQUIRE(cluster->get_blocks().size() == 1);
  315. auto block = cluster->get_blocks().get(b->hash());
  316. REQUIRE(block);
  317. auto folder = cluster->get_folders().by_id(folder_id);
  318. auto peer_folder_info = folder->get_folder_infos().by_device(*peer_device);
  319. REQUIRE(peer_folder_info);
  320. CHECK(peer_folder_info->get_max_sequence() == 6ul);
  321. REQUIRE(peer_folder_info->get_file_infos().size() == 1);
  322. auto peer_file = peer_folder_info->get_file_infos().by_name("a.txt");
  323. REQUIRE(peer_file);
  324. builder.unshare_folder(sha256, folder_id).apply(*sup);
  325. sup->request<net::payload::load_cluster_request_t>(db_addr).send(timeout);
  326. sup->do_process();
  327. REQUIRE(reply);
  328. REQUIRE(!reply->payload.ee);
  329. auto cluster_clone = make_cluster();
  330. {
  331. REQUIRE(reply->payload.res.diff->apply(*cluster_clone));
  332. auto &fis = cluster_clone->get_folders().by_id(folder_id)->get_folder_infos();
  333. REQUIRE(fis.size() == 1);
  334. REQUIRE(!fis.by_device(*peer_device));
  335. REQUIRE(fis.by_device(*cluster->get_device()));
  336. REQUIRE(cluster_clone->get_blocks().size() == 0);
  337. }
  338. }
  339. };
  340. F().run();
  341. }
  342. void test_clone_file() {
  343. struct F : fixture_t {
  344. void main() noexcept override {
  345. auto sha256 = peer_device->device_id().get_sha256();
  346. auto folder_id = "1234-5678";
  347. auto file = proto::FileInfo();
  348. file.set_name("a.txt");
  349. file.set_sequence(6ul);
  350. auto version = file.mutable_version();
  351. auto counter = version->add_counters();
  352. counter->set_id(1);
  353. counter->set_value(peer_device->as_uint());
  354. auto builder = diff_builder_t(*cluster);
  355. builder.update_peer(sha256)
  356. .apply(*sup)
  357. .create_folder(folder_id, "/my/path")
  358. .configure_cluster(sha256)
  359. .add(sha256, folder_id, 5, file.sequence())
  360. .finish()
  361. .share_folder(sha256, folder_id)
  362. .apply(*sup);
  363. auto folder = cluster->get_folders().by_id(folder_id);
  364. auto folder_my = folder->get_folder_infos().by_device(*my_device);
  365. auto folder_peer = folder->get_folder_infos().by_device(*peer_device);
  366. SECTION("file without blocks") {
  367. builder.make_index(sha256, folder_id).add(file).finish().apply(*sup);
  368. auto file_peer = folder_peer->get_file_infos().by_name(file.name());
  369. REQUIRE(file_peer);
  370. builder.clone_file(*file_peer).apply(*sup);
  371. sup->request<net::payload::load_cluster_request_t>(db_addr).send(timeout);
  372. sup->do_process();
  373. REQUIRE(reply);
  374. REQUIRE(!reply->payload.ee);
  375. auto cluster_clone = make_cluster();
  376. {
  377. REQUIRE(reply->payload.res.diff->apply(*cluster_clone));
  378. REQUIRE(cluster_clone->get_blocks().size() == 0);
  379. auto &fis = cluster_clone->get_folders().by_id(folder_id)->get_folder_infos();
  380. REQUIRE(fis.size() == 2);
  381. auto folder_info_clone = fis.by_device(*cluster_clone->get_device());
  382. auto file_clone = folder_info_clone->get_file_infos().by_name(file.name());
  383. REQUIRE(file_clone);
  384. REQUIRE(file_clone->get_name() == file.name());
  385. REQUIRE(file_clone->get_blocks().size() == 0);
  386. REQUIRE(file_clone->get_sequence() == 1);
  387. REQUIRE(!file_clone->get_source());
  388. REQUIRE(folder_info_clone->get_max_sequence() == 1);
  389. }
  390. }
  391. SECTION("file with blocks") {
  392. file.set_size(5ul);
  393. file.set_block_size(5ul);
  394. auto b = file.add_blocks();
  395. b->set_size(5ul);
  396. b->set_hash(utils::sha256_digest("12345").value());
  397. builder.make_index(sha256, folder_id).add(file).finish().apply(*sup);
  398. auto folder = cluster->get_folders().by_id(folder_id);
  399. auto folder_my = folder->get_folder_infos().by_device(*my_device);
  400. auto folder_peer = folder->get_folder_infos().by_device(*peer_device);
  401. auto file_peer = folder_peer->get_file_infos().by_name(file.name());
  402. REQUIRE(file_peer);
  403. builder.clone_file(*file_peer).apply(*sup);
  404. REQUIRE(folder_my->get_max_sequence() == 0);
  405. {
  406. sup->request<net::payload::load_cluster_request_t>(db_addr).send(timeout);
  407. sup->do_process();
  408. REQUIRE(reply);
  409. REQUIRE(!reply->payload.ee);
  410. auto cluster_clone = make_cluster();
  411. REQUIRE(reply->payload.res.diff->apply(*cluster_clone));
  412. REQUIRE(cluster_clone->get_blocks().size() == 1);
  413. auto &fis = cluster_clone->get_folders().by_id(folder_id)->get_folder_infos();
  414. REQUIRE(fis.size() == 2);
  415. auto folder_info_clone = fis.by_device(*cluster_clone->get_device());
  416. auto file_clone = folder_info_clone->get_file_infos().by_name(file.name());
  417. REQUIRE(file_clone);
  418. REQUIRE(file_clone->get_name() == file.name());
  419. REQUIRE(file_clone->get_blocks().size() == 1);
  420. REQUIRE(file_clone->get_sequence() == 0);
  421. REQUIRE(folder_info_clone->get_max_sequence() == 0);
  422. }
  423. file_peer = folder_peer->get_file_infos().by_name(file.name());
  424. file_peer->mark_local_available(0);
  425. REQUIRE(file_peer->is_locally_available());
  426. auto file_my = folder_my->get_file_infos().by_name(file.name());
  427. builder.finish_file_ack(*file_my).apply(*sup);
  428. {
  429. sup->request<net::payload::load_cluster_request_t>(db_addr).send(timeout);
  430. sup->do_process();
  431. REQUIRE(reply);
  432. REQUIRE(!reply->payload.ee);
  433. auto cluster_clone = make_cluster();
  434. REQUIRE(reply->payload.res.diff->apply(*cluster_clone));
  435. REQUIRE(cluster_clone->get_blocks().size() == 1);
  436. auto &fis = cluster_clone->get_folders().by_id(folder_id)->get_folder_infos();
  437. REQUIRE(fis.size() == 2);
  438. auto folder_info_clone = fis.by_device(*cluster_clone->get_device());
  439. auto file_clone = folder_info_clone->get_file_infos().by_name(file.name());
  440. REQUIRE(file_clone);
  441. REQUIRE(file_clone->get_name() == file.name());
  442. REQUIRE(file_clone->get_blocks().size() == 1);
  443. REQUIRE(file_clone->get_blocks().at(0));
  444. REQUIRE(file_clone->get_sequence() == 1);
  445. REQUIRE(folder_info_clone->get_max_sequence() == 1);
  446. }
  447. }
  448. }
  449. };
  450. F().run();
  451. }
  452. void test_local_update() {
  453. struct F : fixture_t {
  454. void main() noexcept override {
  455. auto folder_id = "1234-5678";
  456. auto pr_file = proto::FileInfo();
  457. pr_file.set_name("a.txt");
  458. pr_file.set_size(5ul);
  459. auto hash = utils::sha256_digest("12345").value();
  460. auto pr_block = pr_file.add_blocks();
  461. pr_block->set_weak_hash(12);
  462. pr_block->set_size(5);
  463. pr_block->set_hash(hash);
  464. auto builder = diff_builder_t(*cluster);
  465. builder.create_folder(folder_id, "/my/path").apply(*sup).local_update(folder_id, pr_file).apply(*sup);
  466. SECTION("check saved file with new blocks") {
  467. sup->request<net::payload::load_cluster_request_t>(db_addr).send(timeout);
  468. sup->do_process();
  469. REQUIRE(reply);
  470. REQUIRE(!reply->payload.ee);
  471. auto cluster_clone = make_cluster();
  472. REQUIRE(reply->payload.res.diff->apply(*cluster_clone));
  473. auto folder = cluster_clone->get_folders().by_id(folder_id);
  474. auto folder_my = folder->get_folder_infos().by_device(*my_device);
  475. auto file = folder_my->get_file_infos().by_name("a.txt");
  476. REQUIRE(file);
  477. CHECK(cluster_clone->get_blocks().size() == 1);
  478. CHECK(file->get_blocks().size() == 1);
  479. }
  480. pr_file.set_deleted(true);
  481. pr_file.set_size(0);
  482. pr_file.clear_blocks();
  483. builder.local_update(folder_id, pr_file).apply(*sup);
  484. SECTION("check deleted blocks") {
  485. sup->request<net::payload::load_cluster_request_t>(db_addr).send(timeout);
  486. sup->do_process();
  487. REQUIRE(reply);
  488. REQUIRE(!reply->payload.ee);
  489. auto cluster_clone = make_cluster();
  490. REQUIRE(reply->payload.res.diff->apply(*cluster_clone));
  491. auto folder = cluster_clone->get_folders().by_id(folder_id);
  492. auto folder_my = folder->get_folder_infos().by_device(*my_device);
  493. auto file = folder_my->get_file_infos().by_name("a.txt");
  494. REQUIRE(file);
  495. CHECK(file->is_deleted());
  496. CHECK(cluster_clone->get_blocks().size() == 0);
  497. CHECK(file->get_blocks().size() == 0);
  498. }
  499. }
  500. };
  501. F().run();
  502. };
  503. int _init() {
  504. REGISTER_TEST_CASE(test_loading_empty_db, "test_loading_empty_db", "[db]");
  505. REGISTER_TEST_CASE(test_folder_creation, "test_folder_creation", "[db]");
  506. REGISTER_TEST_CASE(test_peer_updating, "test_peer_updating", "[db]");
  507. REGISTER_TEST_CASE(test_folder_sharing, "test_folder_sharing", "[db]");
  508. REGISTER_TEST_CASE(test_cluster_update_and_remove, "test_cluster_update_and_remove", "[db]");
  509. REGISTER_TEST_CASE(test_clone_file, "test_clone_file", "[db]");
  510. REGISTER_TEST_CASE(test_local_update, "test_local_update", "[db]");
  511. REGISTER_TEST_CASE(test_unsharing_folder, "test_unsharing_folder", "[db]");
  512. return 1;
  513. }
  514. static int v = _init();