130-controller-cluster.cpp 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. #include "catch.hpp"
  2. #include "fixture.h"
  3. #include "ui/messages.hpp"
  4. #include "utils/error_code.h"
  5. #include "test-utils.h"
  6. using namespace syncspirit;
  7. using namespace syncspirit::test;
  8. using namespace syncspirit::utils;
  9. void test_start_reading() {
  10. struct F : Fixture {
  11. void setup() override { peer_cluster_config = payload::cluster_config_ptr_t(new proto::ClusterConfig()); }
  12. void main() override { CHECK(peer->start_reading == 1); }
  13. };
  14. F().run();
  15. }
  16. void test_new_folder() {
  17. using notify_t = ui::message::new_folder_notify_t;
  18. using notify_ptr_t = r::intrusive_ptr_t<notify_t>;
  19. using cluster_msg_t = r::intrusive_ptr_t<message::cluster_config_t>;
  20. struct F : Fixture {
  21. notify_ptr_t notify;
  22. proto::Folder p_folder;
  23. cluster_msg_t cluster_msg;
  24. void setup() override {
  25. auto config = proto::ClusterConfig();
  26. auto folder = proto::Folder();
  27. folder.set_label("my-folder");
  28. folder.set_id("123");
  29. auto d_my = proto::Device();
  30. d_my.set_id(device_my->device_id.get_sha256());
  31. d_my.set_index_id(21);
  32. d_my.set_max_sequence(0);
  33. auto d_peer = proto::Device();
  34. d_my.set_id(device_peer->device_id.get_sha256());
  35. d_my.set_index_id(22);
  36. d_my.set_max_sequence(1);
  37. *folder.add_devices() = d_my;
  38. *folder.add_devices() = d_peer;
  39. *config.add_folders() = folder;
  40. peer_cluster_config = payload::cluster_config_ptr_t(new proto::ClusterConfig(config));
  41. p_folder = folder;
  42. }
  43. void pre_run() override {
  44. peer->configure_callback = [&](auto &plugin) {
  45. plugin.template with_casted<r::plugin::starter_plugin_t>([&](auto &p) {
  46. p.subscribe_actor(r::lambda<notify_t>([&](notify_t &msg) { notify = &msg; }), sup->get_address());
  47. p.subscribe_actor(r::lambda<message::cluster_config_t>(
  48. [&](message::cluster_config_t &msg) { cluster_msg = &msg; }));
  49. });
  50. };
  51. }
  52. void main() override {
  53. CHECK(peer->start_reading == 1);
  54. REQUIRE(notify);
  55. CHECK(notify->payload.folder.label() == "my-folder");
  56. CHECK(notify->payload.folder.id() == "123");
  57. CHECK(notify->payload.source == device_peer);
  58. CHECK(notify->payload.source_index == 22);
  59. auto dir = root_path / "my-folder";
  60. auto db_folder = db::Folder();
  61. db_folder.set_id(p_folder.id());
  62. db_folder.set_label(p_folder.label());
  63. db_folder.set_path(dir.string());
  64. auto folder = model::folder_ptr_t(new model::folder_t(db_folder));
  65. cluster->get_folders().put(folder);
  66. folder->assign_device(device_my);
  67. folder->assign_cluster(cluster.get());
  68. auto db_fi_local = db::FolderInfo();
  69. db_fi_local.set_index_id(234);
  70. auto fi_local =
  71. model::folder_info_ptr_t(new model::folder_info_t(db_fi_local, device_my.get(), folder.get(), 2));
  72. auto db_fi_source = db::FolderInfo();
  73. db_fi_source.set_index_id(345);
  74. db_fi_source.set_max_sequence(5);
  75. auto fi_source =
  76. model::folder_info_ptr_t(new model::folder_info_t(db_fi_source, device_peer.get(), folder.get(), 3));
  77. folder->add(fi_local);
  78. folder->add(fi_source);
  79. peer->send<payload::store_new_folder_notify_t>(controller->get_address(), folder);
  80. sup->do_process();
  81. REQUIRE(cluster_msg);
  82. proto::Index index;
  83. index.set_folder(folder->id());
  84. SECTION("file with content (1 and 0 blocks)") {
  85. auto block_info = proto::BlockInfo();
  86. block_info.set_size(5);
  87. block_info.set_hash(utils::sha256_digest("12345").value());
  88. auto fi = proto::FileInfo();
  89. fi.set_name("a.txt");
  90. fi.set_type(proto::FileInfoType::FILE);
  91. fi.set_sequence(5);
  92. fi.set_block_size(5);
  93. auto path = dir / "a.txt";
  94. SECTION("non-empty") {
  95. fi.set_size(5);
  96. *fi.add_blocks() = block_info;
  97. *index.add_files() = fi;
  98. auto index_ptr = proto::message::Index(std::make_unique<proto::Index>(std::move(index)));
  99. peer->send<payload::forwarded_message_t>(controller->get_address(), std::move(index_ptr));
  100. SECTION("correct small block") {
  101. peer->push_response("12345");
  102. sup->do_process();
  103. CHECK(read_file(path) == "12345");
  104. }
  105. SECTION("block hash mismatches") {
  106. peer->push_response("1234");
  107. sup->do_process();
  108. CHECK(!bfs::exists(path));
  109. auto ec = controller->get_shutdown_reason()->next->ec;
  110. CHECK(ec.value() == (int)utils::protocol_error_code_t::digest_mismatch);
  111. }
  112. }
  113. SECTION("empty") {
  114. *index.add_files() = fi;
  115. auto index_ptr = proto::message::Index(std::make_unique<proto::Index>(std::move(index)));
  116. peer->send<payload::forwarded_message_t>(controller->get_address(), std::move(index_ptr));
  117. sup->do_process();
  118. REQUIRE(bfs::exists(path));
  119. CHECK(bfs::file_size(path) == 0);
  120. }
  121. }
  122. SECTION("file with content (2 blocks)") {
  123. auto bi1 = proto::BlockInfo();
  124. bi1.set_size(5);
  125. bi1.set_hash(utils::sha256_digest("12345").value());
  126. auto bi2 = proto::BlockInfo();
  127. bi2.set_size(5);
  128. bi2.set_hash(utils::sha256_digest("67890").value());
  129. auto fi = proto::FileInfo();
  130. fi.set_name("a.txt");
  131. fi.set_type(proto::FileInfoType::FILE);
  132. fi.set_sequence(5);
  133. fi.set_block_size(5);
  134. auto path = dir / "a.txt";
  135. fi.set_size(5);
  136. *fi.add_blocks() = bi1;
  137. *fi.add_blocks() = bi2;
  138. *index.add_files() = fi;
  139. auto index_ptr = proto::message::Index(std::make_unique<proto::Index>(std::move(index)));
  140. peer->send<payload::forwarded_message_t>(controller->get_address(), std::move(index_ptr));
  141. SECTION("direct order") {
  142. peer->push_response("12345");
  143. peer->push_response("67890");
  144. sup->do_process();
  145. CHECK(read_file(path) == "1234567890");
  146. }
  147. SECTION("indirect order") {
  148. peer->push_response("67890", 1);
  149. peer->push_response("12345", 0);
  150. sup->do_process();
  151. CHECK(read_file(path) == "1234567890");
  152. }
  153. }
  154. SECTION("sync deleted file") {
  155. auto fi = proto::FileInfo();
  156. fi.set_name("b.txt");
  157. fi.set_type(proto::FileInfoType::FILE);
  158. fi.set_sequence(4);
  159. fi.set_deleted(true);
  160. *index.add_files() = fi;
  161. SECTION("file does not exist") {
  162. auto index_ptr = proto::message::Index(std::make_unique<proto::Index>(std::move(index)));
  163. peer->send<payload::forwarded_message_t>(controller->get_address(), std::move(index_ptr));
  164. sup->do_process();
  165. CHECK(!controller->get_shutdown_reason());
  166. }
  167. SECTION("file does exist, and then it is deleted") {
  168. auto index_ptr = proto::message::Index(std::make_unique<proto::Index>(std::move(index)));
  169. peer->send<payload::forwarded_message_t>(controller->get_address(), std::move(index_ptr));
  170. auto p = dir / "b.txt";
  171. write_file(p, "");
  172. sup->do_process();
  173. CHECK(!controller->get_shutdown_reason());
  174. CHECK(!bfs::exists(p));
  175. }
  176. }
  177. };
  178. };
  179. F().run();
  180. }
  181. REGISTER_TEST_CASE(test_start_reading, "test_start_reading", "[controller]");
  182. REGISTER_TEST_CASE(test_new_folder, "test_new_folder", "[controller]");