070-db.cpp 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. #include "catch.hpp"
  2. #include "test-utils.h"
  3. #include "access.h"
  4. #include "db/utils.h"
  5. #include <boost/filesystem.hpp>
  6. using namespace syncspirit;
  7. using namespace syncspirit::db;
  8. namespace fs = boost::filesystem;
  9. struct env_t {
  10. MDBX_env *env;
  11. fs::path path;
  12. ~env_t() {
  13. if (env) {
  14. mdbx_env_close(env);
  15. }
  16. // std::cout << path.c_str() << "\n";
  17. fs::remove_all(path);
  18. }
  19. };
  20. static env_t mk_env() {
  21. auto path = fs::unique_path();
  22. MDBX_env *env;
  23. auto r = mdbx_env_create(&env);
  24. assert(r == MDBX_SUCCESS);
  25. MDBX_env_flags_t flags =
  26. MDBX_EXCLUSIVE | MDBX_SAFE_NOSYNC | MDBX_WRITEMAP | MDBX_NOTLS | MDBX_COALESCE | MDBX_LIFORECLAIM;
  27. r = mdbx_env_open(env, path.c_str(), flags, 0664);
  28. assert(r == MDBX_SUCCESS);
  29. // std::cout << path.c_str() << "\n";
  30. return env_t{env, std::move(path)};
  31. }
  32. static transaction_t mk_txn(env_t &env, transaction_type_t type) {
  33. auto r = db::make_transaction(type, env.env);
  34. assert((bool)r);
  35. return std::move(r.value());
  36. }
  37. TEST_CASE("get db version & migrate 0 -> 1", "[db]") {
  38. auto env = mk_env();
  39. auto txn = mk_txn(env, transaction_type_t::RW);
  40. auto version = db::get_version(txn);
  41. REQUIRE(version.value() == 0);
  42. db::Device db_d0;
  43. db_d0.set_id(test::device_id2sha256("VUV42CZ-IQD5A37-RPEBPM4-VVQK6E4-6WSKC7B-PVJQHHD-4PZD44V-ENC6WAZ"));
  44. db_d0.set_name("d1");
  45. auto d0 = model::device_ptr_t(new model::local_device_t(db_d0));
  46. CHECK(db::migrate(version.value(), d0, txn));
  47. txn = mk_txn(env, transaction_type_t::RO);
  48. version = db::get_version(txn);
  49. CHECK(version.value() == 1);
  50. SECTION("save & load device") {
  51. db::Device db_d1;
  52. db_d1.set_id(test::device_id2sha256("KHQNO2S-5QSILRK-YX4JZZ4-7L77APM-QNVGZJT-EKU7IFI-PNEPBMY-4MXFMQD"));
  53. db_d1.set_name("d1");
  54. auto d1 = model::device_ptr_t(new model::device_t(db_d1));
  55. db::Device db_d2;
  56. db_d2.set_id(test::device_id2sha256("KUEQE66-JJ7P6AD-BEHD4ZW-GPBNW6Q-Y4C3K4Y-X44WJWZ-DVPIDXS-UDRJMA7"));
  57. db_d2.set_name("d2");
  58. auto d2 = model::device_ptr_t(new model::device_t(db_d2));
  59. model::devices_map_t devices;
  60. devices.put(d1);
  61. devices.put(d2);
  62. auto txn = mk_txn(env, transaction_type_t::RW);
  63. auto r = db::store_device(d1, txn);
  64. REQUIRE(r);
  65. CHECK(d1->get_db_key() > 0);
  66. r = db::store_device(d2, txn);
  67. REQUIRE(txn.commit());
  68. CHECK(d2->get_db_key() > 0);
  69. txn = mk_txn(env, transaction_type_t::RO);
  70. auto devices_opt = db::load_devices(txn);
  71. REQUIRE(devices_opt);
  72. auto &devices2 = devices_opt.value();
  73. REQUIRE(devices2.size() == devices.size() + 1);
  74. REQUIRE(devices2.by_id(d1->device_id.get_sha256()));
  75. REQUIRE(devices2.by_id(d2->device_id.get_sha256()));
  76. REQUIRE(*devices2.by_id(d1->device_id.get_sha256()) == *d1);
  77. REQUIRE(*devices2.by_id(d2->device_id.get_sha256()) == *d2);
  78. auto &ld1 = *devices2.by_id(d1->device_id.get_sha256());
  79. auto &ld2 = *devices2.by_id(d2->device_id.get_sha256());
  80. CHECK(ld1.get_db_key() != 0);
  81. CHECK(ld2.get_db_key() != 0);
  82. }
  83. SECTION("save & load ignored device") {
  84. auto d1 = model::device_id_t::from_sha256(
  85. test::device_id2sha256("KHQNO2S-5QSILRK-YX4JZZ4-7L77APM-QNVGZJT-EKU7IFI-PNEPBMY-4MXFMQD"))
  86. .value();
  87. auto ignored_device = model::ignored_device_ptr_t(new model::device_id_t(d1));
  88. auto txn = mk_txn(env, transaction_type_t::RW);
  89. auto r = db::store_ignored_device(ignored_device, txn);
  90. REQUIRE(r);
  91. REQUIRE(txn.commit());
  92. txn = mk_txn(env, transaction_type_t::RO);
  93. auto ignored_devices_opt = db::load_ignored_devices(txn);
  94. CHECK(ignored_devices_opt);
  95. auto &ignored_devices = ignored_devices_opt.value();
  96. REQUIRE(ignored_devices.size() == 1);
  97. CHECK(*ignored_devices.by_key(ignored_device->get_sha256()) == *ignored_device);
  98. }
  99. SECTION("save & load ignored folder") {
  100. auto db_f = db::IgnoredFolder{};
  101. db_f.set_id("123");
  102. db_f.set_label("my-label");
  103. auto ignored_folder = model::ignored_folder_ptr_t(new model::ignored_folder_t(db_f));
  104. auto txn = mk_txn(env, transaction_type_t::RW);
  105. auto r = db::store_ignored_folder(ignored_folder, txn);
  106. REQUIRE(r);
  107. REQUIRE(txn.commit());
  108. txn = mk_txn(env, transaction_type_t::RO);
  109. auto ignored_folders_opt = db::load_ignored_folders(txn);
  110. CHECK(ignored_folders_opt);
  111. auto &ignored_folders = ignored_folders_opt.value();
  112. REQUIRE(ignored_folders.size() == 1);
  113. CHECK(*ignored_folders.by_key(ignored_folder->id) == *ignored_folder);
  114. }
  115. SECTION("save & load folders") {
  116. db::Folder db_f1;
  117. db_f1.set_id("1111");
  118. db_f1.set_label("1111-l");
  119. auto f1 = model::folder_ptr_t(new model::folder_t(db_f1));
  120. db::Folder db_f2;
  121. db_f2.set_id("2222");
  122. db_f2.set_label("2222-l");
  123. auto f2 = model::folder_ptr_t(new model::folder_t(db_f2));
  124. model::folders_map_t folders;
  125. folders.put(f1);
  126. folders.put(f2);
  127. auto txn = mk_txn(env, transaction_type_t::RW);
  128. auto r = db::store_folder(f1, txn);
  129. REQUIRE(r);
  130. CHECK(f1->get_db_key() > 0);
  131. r = db::store_folder(f2, txn);
  132. REQUIRE(txn.commit());
  133. CHECK(f2->get_db_key() > 0);
  134. txn = mk_txn(env, transaction_type_t::RO);
  135. auto folders_opt = db::load_folders(txn);
  136. REQUIRE(folders_opt);
  137. auto &folders2 = folders_opt.value();
  138. REQUIRE(folders2.size() == folders.size());
  139. REQUIRE(folders2.by_id(f1->id()));
  140. REQUIRE(folders2.by_id(f2->id()));
  141. REQUIRE(*folders2.by_id(f1->id()) == *f1);
  142. REQUIRE(*folders2.by_id(f2->id()) == *f2);
  143. }
  144. SECTION("save & load folder_infos") {
  145. db::Device db_d1;
  146. db_d1.set_id(test::device_id2sha256("KHQNO2S-5QSILRK-YX4JZZ4-7L77APM-QNVGZJT-EKU7IFI-PNEPBMY-4MXFMQD"));
  147. db_d1.set_name("d1");
  148. auto d1 = model::device_ptr_t(new model::device_t(db_d1));
  149. auto devices = model::devices_map_t();
  150. devices.put(d1);
  151. db::Folder db_f1;
  152. db_f1.set_id("1111");
  153. db_f1.set_label("1111-l");
  154. auto f1 = model::folder_ptr_t(new model::folder_t(db_f1));
  155. auto folders = model::folders_map_t();
  156. folders.put(f1);
  157. auto txn = mk_txn(env, transaction_type_t::RW);
  158. db::FolderInfo db_fi;
  159. db_fi.set_index_id(1234);
  160. // db_fi.set_max_sequence(1235);
  161. auto fi = model::folder_info_ptr_t(new model::folder_info_t(db_fi, d1.get(), f1.get(), 12345));
  162. auto r = db::store_folder_info(fi, txn);
  163. REQUIRE(r);
  164. REQUIRE(txn.commit());
  165. CHECK(fi->get_db_key());
  166. txn = mk_txn(env, transaction_type_t::RO);
  167. auto infos = db::load_folder_infos(devices, folders, txn);
  168. REQUIRE(infos);
  169. auto fi_x = infos.value().by_key(fi->get_db_key());
  170. CHECK(*fi_x == *fi);
  171. CHECK(fi_x->get_device() == fi->get_device());
  172. CHECK(fi_x->get_folder() == fi->get_folder());
  173. SECTION("save & load file_infos") {
  174. db::FileInfo db_fi1;
  175. db_fi1.set_name("a/b/c.txt");
  176. auto fi1 = model::file_info_ptr_t(new model::file_info_t(db_fi1, f1.get()));
  177. auto txn = mk_txn(env, transaction_type_t::RW);
  178. auto r = db::store_file_info(fi1, txn);
  179. REQUIRE(r);
  180. REQUIRE(txn.commit());
  181. txn = mk_txn(env, transaction_type_t::RO);
  182. auto fi_infos = db::load_file_infos(folders, txn);
  183. REQUIRE(fi_infos);
  184. auto fi1_x = fi_infos.value().by_key(fi1->get_db_key());
  185. CHECK(*fi1_x == *fi1);
  186. CHECK(fi1_x->get_folder() == f1.get());
  187. }
  188. }
  189. }