071-fs_actor.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626
  1. // SPDX-License-Identifier: GPL-3.0-or-later
  2. // SPDX-FileCopyrightText: 2019-2024 Ivan Baidakou
  3. #include "test-utils.h"
  4. #include "fs/file_actor.h"
  5. #include "fs/utils.h"
  6. #include "diff-builder.h"
  7. #include "net/messages.h"
  8. #include "test_supervisor.h"
  9. #include "access.h"
  10. #include "model/cluster.h"
  11. #include "access.h"
  12. #include <boost/filesystem.hpp>
  13. using namespace syncspirit;
  14. using namespace syncspirit::db;
  15. using namespace syncspirit::test;
  16. using namespace syncspirit::model;
  17. using namespace syncspirit::net;
  18. namespace bfs = boost::filesystem;
  19. namespace {
  20. struct fixture_t {
  21. using msg_t = net::message::load_cluster_response_t;
  22. using msg_ptr_t = r::intrusive_ptr_t<msg_t>;
  23. using blk_res_t = fs::message::block_response_t;
  24. using blk_res_ptr_t = r::intrusive_ptr_t<blk_res_t>;
  25. fixture_t() noexcept : root_path{bfs::unique_path()}, path_guard{root_path} {
  26. utils::set_default("trace");
  27. bfs::create_directory(root_path);
  28. }
  29. virtual supervisor_t::configure_callback_t configure() noexcept {
  30. return [&](r::plugin::plugin_base_t &plugin) {
  31. plugin.template with_casted<r::plugin::starter_plugin_t>([&](auto &p) {
  32. p.subscribe_actor(r::lambda<msg_t>([&](msg_t &msg) { reply = &msg; }));
  33. p.subscribe_actor(r::lambda<blk_res_t>([&](blk_res_t &msg) { block_reply = &msg; }));
  34. });
  35. };
  36. }
  37. virtual void run() noexcept {
  38. auto my_id =
  39. device_id_t::from_string("KHQNO2S-5QSILRK-YX4JZZ4-7L77APM-QNVGZJT-EKU7IFI-PNEPBMY-4MXFMQD").value();
  40. my_device = device_t::create(my_id, "my-device").value();
  41. cluster = new cluster_t(my_device, 1, 1);
  42. auto peer_id =
  43. device_id_t::from_string("VUV42CZ-IQD5A37-RPEBPM4-VVQK6E4-6WSKC7B-PVJQHHD-4PZD44V-ENC6WAZ").value();
  44. peer_device = device_t::create(peer_id, "peer-device").value();
  45. cluster->get_devices().put(my_device);
  46. cluster->get_devices().put(peer_device);
  47. r::system_context_t ctx;
  48. sup = ctx.create_supervisor<supervisor_t>().auto_finish(false).timeout(timeout).create_registry().finish();
  49. sup->cluster = cluster;
  50. sup->configure_callback = configure();
  51. sup->start();
  52. sup->do_process();
  53. CHECK(static_cast<r::actor_base_t *>(sup.get())->access<to::state>() == r::state_t::OPERATIONAL);
  54. auto sha256 = peer_device->device_id().get_sha256();
  55. file_actor = sup->create_actor<fs::file_actor_t>().mru_size(2).cluster(cluster).timeout(timeout).finish();
  56. sup->do_process();
  57. CHECK(static_cast<r::actor_base_t *>(file_actor.get())->access<to::state>() == r::state_t::OPERATIONAL);
  58. file_addr = file_actor->get_address();
  59. auto builder = diff_builder_t(*cluster);
  60. builder.create_folder(folder_id, root_path.string(), "my-label")
  61. .apply(*sup)
  62. .update_peer(sha256, "some_name", "some-cn", true)
  63. .apply(*sup)
  64. .share_folder(sha256, folder_id)
  65. .apply(*sup);
  66. folder = cluster->get_folders().by_id(folder_id);
  67. folder_my = folder->get_folder_infos().by_device(*my_device);
  68. folder_peer = folder->get_folder_infos().by_device(*peer_device);
  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 file_addr;
  77. r::pt::time_duration timeout = r::pt::millisec{10};
  78. cluster_ptr_t cluster;
  79. model::device_ptr_t peer_device;
  80. model::device_ptr_t my_device;
  81. model::folder_ptr_t folder;
  82. model::folder_info_ptr_t folder_my;
  83. model::folder_info_ptr_t folder_peer;
  84. r::intrusive_ptr_t<supervisor_t> sup;
  85. r::intrusive_ptr_t<fs::file_actor_t> file_actor;
  86. bfs::path root_path;
  87. path_guard_t path_guard;
  88. r::system_context_t ctx;
  89. msg_ptr_t reply;
  90. blk_res_ptr_t block_reply;
  91. std::string_view folder_id = "1234-5678";
  92. };
  93. } // namespace
  94. void test_clone_file() {
  95. struct F : fixture_t {
  96. void main() noexcept override {
  97. proto::FileInfo pr_fi;
  98. std::int64_t modified = 1641828421;
  99. pr_fi.set_name("q.txt");
  100. pr_fi.set_modified_s(modified);
  101. auto version = pr_fi.mutable_version();
  102. auto counter = version->add_counters();
  103. counter->set_id(1);
  104. counter->set_value(peer_device->as_uint());
  105. auto make_file = [&]() {
  106. auto file = file_info_t::create(cluster->next_uuid(), pr_fi, folder_peer).value();
  107. folder_peer->add(file, false);
  108. return file;
  109. };
  110. SECTION("empty regular file") {
  111. auto peer_file = make_file();
  112. diff_builder_t(*cluster).clone_file(*peer_file).apply(*sup);
  113. auto my_file = folder_my->get_file_infos().by_name(peer_file->get_name());
  114. auto &path = my_file->get_path();
  115. REQUIRE(bfs::exists(path));
  116. REQUIRE(bfs::file_size(path) == 0);
  117. REQUIRE(bfs::last_write_time(path) == 1641828421);
  118. }
  119. SECTION("empty regular file a subdir") {
  120. pr_fi.set_name("a/b/c/d/e.txt");
  121. auto peer_file = make_file();
  122. diff_builder_t(*cluster).clone_file(*peer_file).apply(*sup);
  123. auto file = folder_my->get_file_infos().by_name(pr_fi.name());
  124. auto &path = file->get_path();
  125. REQUIRE(bfs::exists(path));
  126. REQUIRE(bfs::file_size(path) == 0);
  127. }
  128. SECTION("non-empty regular file") {
  129. pr_fi.set_size(5);
  130. pr_fi.set_block_size(5);
  131. auto b = proto::BlockInfo();
  132. b.set_hash(utils::sha256_digest("12345").value());
  133. b.set_weak_hash(555);
  134. b.set_size(5ul);
  135. auto bi = block_info_t::create(b).value();
  136. auto &blocks_map = cluster->get_blocks();
  137. blocks_map.put(bi);
  138. auto peer_file = make_file();
  139. peer_file->assign_block(bi, 0);
  140. diff_builder_t(*cluster).clone_file(*peer_file).apply(*sup);
  141. auto file = folder_my->get_file_infos().by_name(pr_fi.name());
  142. auto filename = std::string(file->get_name()) + ".syncspirit-tmp";
  143. auto path = root_path / filename;
  144. REQUIRE(bfs::exists(path));
  145. REQUIRE(bfs::file_size(path) == 5);
  146. }
  147. SECTION("directory") {
  148. pr_fi.set_type(proto::FileInfoType::DIRECTORY);
  149. auto peer_file = make_file();
  150. diff_builder_t(*cluster).clone_file(*peer_file).apply(*sup);
  151. auto file = folder_my->get_file_infos().by_name(pr_fi.name());
  152. auto &path = file->get_path();
  153. REQUIRE(bfs::exists(path));
  154. REQUIRE(bfs::is_directory(path));
  155. }
  156. #ifndef SYNCSPIRIT_WIN
  157. SECTION("symlink") {
  158. bfs::path target = root_path / "some-existing-file";
  159. write_file(target, "zzz");
  160. pr_fi.set_type(proto::FileInfoType::SYMLINK);
  161. pr_fi.set_symlink_target(target.string());
  162. auto peer_file = make_file();
  163. diff_builder_t(*cluster).clone_file(*peer_file).apply(*sup);
  164. auto file = folder_my->get_file_infos().by_name(pr_fi.name());
  165. auto &path = file->get_path();
  166. CHECK(!bfs::exists(path));
  167. CHECK(bfs::is_symlink(path));
  168. CHECK(bfs::read_symlink(path) == target);
  169. }
  170. #endif
  171. SECTION("deleted file") {
  172. pr_fi.set_deleted(true);
  173. bfs::path target = root_path / pr_fi.name();
  174. write_file(target, "zzz");
  175. REQUIRE(bfs::exists(target));
  176. auto peer_file = make_file();
  177. diff_builder_t(*cluster).clone_file(*peer_file).apply(*sup);
  178. auto file = folder_my->get_file_infos().by_name(pr_fi.name());
  179. CHECK(file->is_deleted());
  180. REQUIRE(!bfs::exists(target));
  181. }
  182. }
  183. };
  184. F().run();
  185. }
  186. void test_append_block() {
  187. struct F : fixture_t {
  188. void main() noexcept override {
  189. std::int64_t modified = 1641828421;
  190. proto::FileInfo pr_source;
  191. pr_source.set_name("q.txt");
  192. pr_source.set_block_size(5ul);
  193. pr_source.set_modified_s(modified);
  194. auto version = pr_source.mutable_version();
  195. auto counter = version->add_counters();
  196. counter->set_id(1);
  197. counter->set_value(peer_device->as_uint());
  198. auto bi = proto::BlockInfo();
  199. bi.set_size(5);
  200. bi.set_weak_hash(12);
  201. bi.set_hash(utils::sha256_digest("12345").value());
  202. bi.set_offset(0);
  203. auto b = block_info_t::create(bi).value();
  204. auto bi2 = proto::BlockInfo();
  205. bi2.set_size(5);
  206. bi2.set_weak_hash(12);
  207. bi2.set_hash(utils::sha256_digest("67890").value());
  208. bi2.set_offset(0);
  209. auto b2 = block_info_t::create(bi2).value();
  210. cluster->get_blocks().put(b);
  211. cluster->get_blocks().put(b2);
  212. auto blocks = std::vector<block_info_ptr_t>{b, b2};
  213. auto make_file = [&](size_t count) {
  214. auto file = file_info_t::create(cluster->next_uuid(), pr_source, folder_peer).value();
  215. for (size_t i = 0; i < count; ++i) {
  216. file->assign_block(blocks[i], i);
  217. }
  218. folder_peer->add(file, false);
  219. return file;
  220. };
  221. auto builder = diff_builder_t(*cluster);
  222. auto callback = [&](diff::modify::block_transaction_t &diff) {
  223. REQUIRE(diff.errors.load() == 0);
  224. builder.ack_block(diff);
  225. };
  226. SECTION("file with 1 block") {
  227. pr_source.set_size(5ul);
  228. auto peer_file = make_file(1);
  229. builder.clone_file(*peer_file).apply(*sup);
  230. auto file = folder_my->get_file_infos().by_name(pr_source.name());
  231. builder.append_block(*peer_file, 0, "12345", callback)
  232. .apply(*sup)
  233. .finish_file(*peer_file->local_file())
  234. .apply(*sup);
  235. auto path = root_path / std::string(file->get_name());
  236. REQUIRE(bfs::exists(path));
  237. REQUIRE(bfs::file_size(path) == 5);
  238. auto data = read_file(path);
  239. CHECK(data == "12345");
  240. CHECK(bfs::last_write_time(path) == 1641828421);
  241. }
  242. SECTION("file with 2 different blocks") {
  243. pr_source.set_size(10ul);
  244. auto peer_file = make_file(2);
  245. builder.clone_file(*peer_file).apply(*sup);
  246. auto file = folder_my->get_file_infos().by_name(pr_source.name());
  247. builder.append_block(*peer_file, 0, "12345", callback).apply(*sup);
  248. auto filename = std::string(file->get_name()) + ".syncspirit-tmp";
  249. auto path = root_path / filename;
  250. #ifndef SYNCSPIRIT_WIN
  251. REQUIRE(bfs::exists(path));
  252. REQUIRE(bfs::file_size(path) == 10);
  253. auto data = read_file(path);
  254. CHECK(data.substr(0, 5) == "12345");
  255. #endif
  256. builder.append_block(*peer_file, 1, "67890", callback).apply(*sup);
  257. SECTION("add 2nd block") {
  258. builder.finish_file(*peer_file->local_file()).apply(*sup);
  259. filename = std::string(file->get_name());
  260. path = root_path / filename;
  261. REQUIRE(bfs::exists(path));
  262. REQUIRE(bfs::file_size(path) == 10);
  263. auto data = read_file(path);
  264. CHECK(data == "1234567890");
  265. CHECK(bfs::last_write_time(path) == 1641828421);
  266. }
  267. #ifndef SYNCSPIRIT_WIN
  268. SECTION("remove folder (simulate err)") {
  269. bfs::remove_all(root_path);
  270. diff_builder_t(*cluster).finish_file(*peer_file->local_file()).apply(*sup);
  271. CHECK(static_cast<r::actor_base_t *>(file_actor.get())->access<to::state>() ==
  272. r::state_t::SHUT_DOWN);
  273. }
  274. #endif
  275. }
  276. }
  277. };
  278. F().run();
  279. }
  280. void test_clone_block() {
  281. struct F : fixture_t {
  282. void main() noexcept override {
  283. auto bi = proto::BlockInfo();
  284. bi.set_size(5);
  285. bi.set_weak_hash(12);
  286. bi.set_hash(utils::sha256_digest("12345").value());
  287. bi.set_offset(0);
  288. auto b = block_info_t::create(bi).value();
  289. auto bi2 = proto::BlockInfo();
  290. bi2.set_size(5);
  291. bi2.set_weak_hash(12);
  292. bi2.set_hash(utils::sha256_digest("67890").value());
  293. bi2.set_offset(0);
  294. auto b2 = block_info_t::create(bi2).value();
  295. cluster->get_blocks().put(b);
  296. cluster->get_blocks().put(b2);
  297. auto blocks = std::vector<block_info_ptr_t>{b, b2};
  298. std::int64_t modified = 1641828421;
  299. proto::FileInfo pr_source;
  300. pr_source.set_name("a.txt");
  301. pr_source.set_block_size(5ul);
  302. pr_source.set_modified_s(modified);
  303. auto version = pr_source.mutable_version();
  304. auto counter = version->add_counters();
  305. counter->set_id(1);
  306. counter->set_value(peer_device->as_uint());
  307. auto make_file = [&](const proto::FileInfo &fi, size_t count) {
  308. auto file = file_info_t::create(cluster->next_uuid(), fi, folder_peer).value();
  309. for (size_t i = 0; i < count; ++i) {
  310. file->assign_block(blocks[i], i);
  311. }
  312. folder_peer->add(file, false);
  313. return file;
  314. };
  315. auto builder = diff_builder_t(*cluster);
  316. auto callback = [&](diff::modify::block_transaction_t &diff) {
  317. REQUIRE(diff.errors.load() == 0);
  318. builder.ack_block(diff);
  319. };
  320. SECTION("source & target are different files") {
  321. proto::FileInfo pr_target;
  322. pr_target.set_name("b.txt");
  323. pr_target.set_block_size(5ul);
  324. (*pr_target.mutable_version()) = *version;
  325. SECTION("single block target file") {
  326. pr_source.set_size(5ul);
  327. pr_target.set_size(5ul);
  328. pr_target.set_modified_s(modified);
  329. auto source = make_file(pr_source, 1);
  330. auto target = make_file(pr_target, 1);
  331. builder.clone_file(*source).clone_file(*target).apply(*sup);
  332. auto source_file = folder_peer->get_file_infos().by_name(pr_source.name());
  333. auto target_file = folder_peer->get_file_infos().by_name(pr_target.name());
  334. builder.append_block(*source_file, 0, "12345", callback)
  335. .apply(*sup)
  336. .finish_file(*source_file->local_file())
  337. .apply(*sup);
  338. auto block = source_file->get_blocks()[0];
  339. auto file_block = model::file_block_t(block.get(), target_file.get(), 0);
  340. builder.clone_block(file_block, callback)
  341. .apply(*sup)
  342. .finish_file(*target->local_file())
  343. .apply(*sup);
  344. auto path = root_path / std::string(target_file->get_name());
  345. REQUIRE(bfs::exists(path));
  346. REQUIRE(bfs::file_size(path) == 5);
  347. auto data = read_file(path);
  348. CHECK(data == "12345");
  349. CHECK(bfs::last_write_time(path) == 1641828421);
  350. }
  351. SECTION("multi block target file") {
  352. pr_source.set_size(10ul);
  353. pr_target.set_size(10ul);
  354. auto source = make_file(pr_source, 2);
  355. auto target = make_file(pr_target, 2);
  356. builder.clone_file(*source).clone_file(*target).apply(*sup);
  357. auto source_file = folder_peer->get_file_infos().by_name(pr_source.name());
  358. auto target_file = folder_peer->get_file_infos().by_name(pr_target.name());
  359. builder.append_block(*source_file, 0, "12345", callback)
  360. .append_block(*source_file, 1, "67890", callback)
  361. .apply(*sup);
  362. auto blocks = source_file->get_blocks();
  363. auto fb_1 = model::file_block_t(blocks[0].get(), target_file.get(), 0);
  364. auto fb_2 = model::file_block_t(blocks[1].get(), target_file.get(), 1);
  365. builder.clone_block(fb_1, callback)
  366. .clone_block(fb_2, callback)
  367. .apply(*sup)
  368. .finish_file(*target->local_file())
  369. .apply(*sup);
  370. auto filename = std::string(target_file->get_name());
  371. auto path = root_path / filename;
  372. REQUIRE(bfs::exists(path));
  373. REQUIRE(bfs::file_size(path) == 10);
  374. auto data = read_file(path);
  375. CHECK(data == "1234567890");
  376. }
  377. SECTION("source/target different sizes") {
  378. pr_source.set_size(5ul);
  379. pr_target.set_size(10ul);
  380. auto target = make_file(pr_target, 2);
  381. auto source = file_info_t::create(cluster->next_uuid(), pr_source, folder_peer).value();
  382. source->assign_block(blocks[1], 0);
  383. folder_peer->add(source, false);
  384. builder.clone_file(*source).clone_file(*target).apply(*sup);
  385. auto source_file = folder_peer->get_file_infos().by_name(pr_source.name());
  386. auto target_file = folder_peer->get_file_infos().by_name(pr_target.name());
  387. builder.append_block(*source_file, 0, "67890", callback)
  388. .append_block(*target_file, 0, "12345", callback)
  389. .apply(*sup);
  390. auto blocks = source_file->get_blocks();
  391. auto fb = model::file_block_t(blocks[0].get(), target_file.get(), 1);
  392. builder.clone_block(fb, callback).apply(*sup).finish_file(*target->local_file()).apply(*sup);
  393. auto filename = std::string(target_file->get_name());
  394. auto path = root_path / filename;
  395. REQUIRE(bfs::exists(path));
  396. REQUIRE(bfs::file_size(path) == 10);
  397. auto data = read_file(path);
  398. CHECK(data == "1234567890");
  399. }
  400. }
  401. SECTION("source & target are is the same file") {
  402. pr_source.set_size(10ul);
  403. auto source = file_info_t::create(cluster->next_uuid(), pr_source, folder_peer).value();
  404. source->assign_block(blocks[0], 0);
  405. source->assign_block(blocks[0], 1);
  406. folder_peer->add(source, false);
  407. builder.clone_file(*source).apply(*sup);
  408. auto source_file = folder_peer->get_file_infos().by_name(pr_source.name());
  409. auto target_file = source_file;
  410. builder.append_block(*source_file, 0, "12345", callback).apply(*sup);
  411. auto block = source_file->get_blocks()[0];
  412. auto file_block = model::file_block_t(block.get(), target_file.get(), 1);
  413. builder.clone_block(file_block, callback).apply(*sup).finish_file(*source->local_file()).apply(*sup);
  414. auto path = root_path / std::string(target_file->get_name());
  415. REQUIRE(bfs::exists(path));
  416. REQUIRE(bfs::file_size(path) == 10);
  417. auto data = read_file(path);
  418. CHECK(data == "1234512345");
  419. CHECK(bfs::last_write_time(path) == 1641828421);
  420. }
  421. }
  422. };
  423. F().run();
  424. }
  425. void test_requesting_block() {
  426. struct F : fixture_t {
  427. void main() noexcept override {
  428. auto bi = proto::BlockInfo();
  429. bi.set_size(5);
  430. bi.set_weak_hash(12);
  431. bi.set_hash(utils::sha256_digest("12345").value());
  432. bi.set_offset(0);
  433. auto b = block_info_t::create(bi).value();
  434. auto bi2 = proto::BlockInfo();
  435. bi2.set_size(5);
  436. bi2.set_weak_hash(12);
  437. bi2.set_hash(utils::sha256_digest("67890").value());
  438. bi2.set_offset(0);
  439. auto b2 = block_info_t::create(bi2).value();
  440. cluster->get_blocks().put(b);
  441. cluster->get_blocks().put(b2);
  442. bfs::path target = root_path / "a.txt";
  443. std::int64_t modified = 1641828421;
  444. proto::FileInfo pr_source;
  445. pr_source.set_name("a.txt");
  446. pr_source.set_block_size(5ul);
  447. pr_source.set_modified_s(modified);
  448. pr_source.set_size(10);
  449. auto version = pr_source.mutable_version();
  450. auto counter = version->add_counters();
  451. counter->set_id(1);
  452. counter->set_value(my_device->as_uint());
  453. *pr_source.add_blocks() = bi;
  454. *pr_source.add_blocks() = bi2;
  455. auto file = file_info_t::create(cluster->next_uuid(), pr_source, folder_my).value();
  456. file->assign_block(b, 0);
  457. file->assign_block(b2, 1);
  458. folder_my->add(file, false);
  459. auto req = proto::Request();
  460. req.set_folder(std::string(folder->get_id()));
  461. req.set_name("a.txt");
  462. req.set_offset(0);
  463. req.set_size(5);
  464. auto req_ptr = proto::message::Request(new proto::Request(req));
  465. auto msg = r::make_message<fs::payload::block_request_t>(file_actor->get_address(), std::move(req_ptr),
  466. sup->get_address());
  467. SECTION("error, no file") {
  468. sup->put(msg);
  469. sup->do_process();
  470. REQUIRE(block_reply);
  471. REQUIRE(block_reply->payload.remote_request);
  472. REQUIRE(block_reply->payload.ec);
  473. REQUIRE(block_reply->payload.data.empty());
  474. }
  475. SECTION("error, oversized request") {
  476. write_file(target, "1234");
  477. sup->put(msg);
  478. sup->do_process();
  479. REQUIRE(block_reply);
  480. REQUIRE(block_reply->payload.remote_request);
  481. REQUIRE(block_reply->payload.ec);
  482. REQUIRE(block_reply->payload.data.empty());
  483. }
  484. SECTION("successful file reading") {
  485. write_file(target, "1234567890");
  486. sup->put(msg);
  487. sup->do_process();
  488. REQUIRE(block_reply);
  489. REQUIRE(block_reply->payload.remote_request);
  490. REQUIRE(!block_reply->payload.ec);
  491. REQUIRE(block_reply->payload.data == "12345");
  492. req.set_offset(5);
  493. auto req_ptr = proto::message::Request(new proto::Request(req));
  494. auto msg = r::make_message<fs::payload::block_request_t>(file_actor->get_address(), std::move(req_ptr),
  495. sup->get_address());
  496. sup->put(msg);
  497. sup->do_process();
  498. REQUIRE(block_reply);
  499. REQUIRE(block_reply->payload.remote_request);
  500. REQUIRE(!block_reply->payload.ec);
  501. REQUIRE(block_reply->payload.data == "67890");
  502. }
  503. }
  504. };
  505. F().run();
  506. }
  507. int _init() {
  508. REGISTER_TEST_CASE(test_clone_file, "test_clone_file", "[fs]");
  509. REGISTER_TEST_CASE(test_append_block, "test_append_block", "[fs]");
  510. REGISTER_TEST_CASE(test_clone_block, "test_clone_block", "[fs]");
  511. REGISTER_TEST_CASE(test_requesting_block, "test_requesting_block", "[fs]");
  512. return 1;
  513. }
  514. static int v = _init();