054-updates_streamer.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. // SPDX-License-Identifier: GPL-3.0-or-later
  2. // SPDX-FileCopyrightText: 2023-2024 Ivan Baidakou
  3. #include "test-utils.h"
  4. #include "model/misc/updates_streamer.h"
  5. #include "model/diff/modify/create_folder.h"
  6. #include "model/diff/modify/share_folder.h"
  7. using namespace syncspirit;
  8. using namespace syncspirit::test;
  9. using namespace syncspirit::utils;
  10. using namespace syncspirit::model;
  11. TEST_CASE("updates_streamer", "[model]") {
  12. utils::set_default("trace");
  13. auto my_id = device_id_t::from_string("KHQNO2S-5QSILRK-YX4JZZ4-7L77APM-QNVGZJT-EKU7IFI-PNEPBMY-4MXFMQD").value();
  14. auto my_device = device_t::create(my_id, "my-device").value();
  15. auto peer_id = device_id_t::from_string("VUV42CZ-IQD5A37-RPEBPM4-VVQK6E4-6WSKC7B-PVJQHHD-4PZD44V-ENC6WAZ").value();
  16. auto peer_device = device_t::create(peer_id, "peer-device").value();
  17. auto cluster = cluster_ptr_t(new cluster_t(my_device, 1, 1));
  18. cluster->get_devices().put(my_device);
  19. cluster->get_devices().put(peer_device);
  20. auto &folders = cluster->get_folders();
  21. db::Folder db_folder;
  22. db_folder.set_id("1234-5678");
  23. db_folder.set_label("my-label");
  24. db_folder.set_path("/my/path");
  25. auto diff = diff::cluster_diff_ptr_t(new diff::modify::create_folder_t(db_folder));
  26. REQUIRE(diff->apply(*cluster));
  27. auto folder = folders.by_id(db_folder.id());
  28. diff = diff::cluster_diff_ptr_t(new diff::modify::share_folder_t(peer_id.get_sha256(), db_folder.id()));
  29. REQUIRE(diff->apply(*cluster));
  30. auto add_remote = [&](std::uint64_t index, std::int64_t sequence) {
  31. auto remote_folder = remote_folder_info_t::create(index, sequence, *peer_device, *folder).value();
  32. peer_device->get_remote_folder_infos().put(remote_folder);
  33. };
  34. SECTION("trivial") {
  35. SECTION("no files") {
  36. auto streamer = model::updates_streamer_t(*cluster, *peer_device);
  37. REQUIRE(!streamer);
  38. }
  39. add_remote(0, 0);
  40. SECTION("no files (2)") {
  41. auto streamer = model::updates_streamer_t(*cluster, *peer_device);
  42. REQUIRE(!streamer);
  43. }
  44. }
  45. auto my_folder = folder->get_folder_infos().by_device(*my_device);
  46. auto &my_files = my_folder->get_file_infos();
  47. int seq = 1;
  48. auto add_file = [&](const char *name) {
  49. auto pr_file = proto::FileInfo();
  50. pr_file.set_name(name);
  51. pr_file.set_sequence(seq++);
  52. auto f = file_info_t::create(cluster->next_uuid(), pr_file, my_folder).value();
  53. my_files.put(f);
  54. my_folder->set_max_sequence(f->get_sequence());
  55. return f;
  56. };
  57. SECTION("2 files, index mismatch") {
  58. SECTION("zero sequence") { add_remote(0, 0); }
  59. SECTION("non-zero sequence") { add_remote(0, seq + 100); }
  60. auto f1 = add_file("a.txt");
  61. auto f2 = add_file("b.txt");
  62. auto streamer = model::updates_streamer_t(*cluster, *peer_device);
  63. REQUIRE(streamer);
  64. CHECK(streamer.next() == f1);
  65. REQUIRE(streamer);
  66. CHECK(streamer.next() == f2);
  67. REQUIRE(!streamer);
  68. }
  69. SECTION("2 files, index matches, sequence greater") {
  70. auto f1 = add_file("a.txt");
  71. auto f2 = add_file("b.txt");
  72. add_remote(my_folder->get_index(), f2->get_sequence());
  73. auto streamer = model::updates_streamer_t(*cluster, *peer_device);
  74. REQUIRE(!streamer);
  75. }
  76. SECTION("2 files, index matches, sequence greater") {
  77. auto f1 = add_file("a.txt");
  78. auto f2 = add_file("b.txt");
  79. add_remote(my_folder->get_index(), f1->get_sequence());
  80. auto streamer = model::updates_streamer_t(*cluster, *peer_device);
  81. REQUIRE(streamer);
  82. CHECK(streamer.next() == f2);
  83. REQUIRE(!streamer);
  84. }
  85. SECTION("1 file, streamer is updated lazily") {
  86. add_remote(0, seq);
  87. auto streamer = model::updates_streamer_t(*cluster, *peer_device);
  88. REQUIRE(!streamer);
  89. auto f1 = add_file("a.txt");
  90. streamer.on_update(*f1);
  91. CHECK(streamer.next() == f1);
  92. REQUIRE(!streamer);
  93. }
  94. SECTION("empty streamer ignores updates") {
  95. add_remote(0, seq);
  96. auto streamer = model::updates_streamer_t();
  97. REQUIRE(!streamer);
  98. auto f1 = add_file("a.txt");
  99. streamer.on_update(*f1);
  100. REQUIRE(!streamer);
  101. }
  102. SECTION("2 files, streamer is updated") {
  103. add_remote(0, seq + 100);
  104. auto f1 = add_file("a.txt");
  105. auto f2 = add_file("b.txt");
  106. auto streamer = model::updates_streamer_t(*cluster, *peer_device);
  107. REQUIRE(streamer);
  108. f1->set_sequence(++seq);
  109. my_folder->set_max_sequence(seq);
  110. streamer.on_update(*f1);
  111. REQUIRE(streamer.next() == f2);
  112. REQUIRE(streamer.next() == f1);
  113. REQUIRE(!streamer);
  114. }
  115. }