#include #include #include #include #include #include #include #include #include #include #include "dataguard/dataguard.h" #include "storage/disk_map.hpp" namespace SnapShotTest { template struct KeysContainerForGenerator { std::deque keys_list; std::set keys_set; bool IsIn(const Key &key) const { return keys_set.find(key) != keys_set.end(); } template Key GetRandomKey(random_generator_t &rnd) { return keys_list[rnd() % keys_list.size()]; } void AddKey(const Key &key) { if (IsIn(key)) return; keys_list.insert(std::lower_bound(keys_list.begin(), keys_list.end(), key), key); keys_set.insert(key); } void RemoveKey(const Key &key) { if (!IsIn(key)) return; keys_list.erase(std::lower_bound(keys_list.begin(), keys_list.end(), key)); keys_set.erase(key); } size_t Size() const { return keys_list.size(); } }; } // namespace SnapShotTest TEST(Hello, World) { return; } TEST(Basic, DiskMap) { using namespace SnapShotTest; const unsigned int RndSeed = testing::GTEST_FLAG(random_seed); std::mt19937 rnd(RndSeed); KeysContainerForGenerator keys_container; std::map std_map; remove("/tmp/index.db"); remove("/tmp/data.db"); const int total_opts = 1000000; { DiskMap disk_map("index", "/tmp/index.db", "data", "/tmp/data.db"); for (int i = 0; i < total_opts; i++) { int opt_id = rnd() % 100; if (opt_id <= 40) { if (keys_container.Size() > 0 && rnd() % 5 <= 2) { // overrite and existing key int key = keys_container.GetRandomKey(rnd); int val = rnd() % 1000000; std_map[key] = val; disk_map.Put(key, val); } else { // insert a new key int key = rnd() % 1000000; int val = rnd() % 1000000; keys_container.AddKey(key); std_map[key] = val; disk_map.Put(key, val); } } else if (opt_id <= 60) { if (keys_container.Size() > 0 && rnd() % 5 <= 2) { // delete an existing key int key = keys_container.GetRandomKey(rnd); keys_container.RemoveKey(key); std_map.erase(key); disk_map.Remove(key); } else { // delete a non-existing key int key = rnd() % 1000000; keys_container.RemoveKey(key); std_map.erase(key); disk_map.Remove(key); } } else { if (keys_container.Size() == 0) continue; int key = keys_container.GetRandomKey(rnd); int val = disk_map.Get(key); if (std_map.find(key) == std_map.end()) { ASSERT_EQ(val, -1); } else { ASSERT_EQ(val, std_map[key]); } } } } } TEST(Basic, T1) { remove("/tmp/1.dat"); remove("/tmp/2.dat"); remove("/tmp/diff.dat"); remove("/tmp/3.dat"); remove("/tmp/4.dat"); const unsigned int RndSeed = testing::GTEST_FLAG(random_seed); std::mt19937 rnd(RndSeed); const int str_len_s1 = 10000; const int str_len_s2 = 9900; char s1[str_len_s1], s2[str_len_s2]; for (int i = 0; i < str_len_s1 - 1; i++) { s1[i] = 'a' + rnd() % 26; } s1[str_len_s1 - 1] = '\0'; memcpy(s2, s1, str_len_s2); for (int i = 0; i < str_len_s2 - 1; i++) { if (i >= str_len_s1) { s2[i] = 'a' + rnd() % 26; continue; } if (rnd() % 3 == 0) { s2[i] = 'a' + rnd() % 26; } } s2[str_len_s2 - 1] = '\0'; // write to file FILE *fp = fopen("/tmp/1.dat", "wb"); fwrite(s1, 1, str_len_s1, fp); fclose(fp); fp = fopen("/tmp/2.dat", "wb"); fwrite(s2, 1, str_len_s2, fp); fclose(fp); GenerateDiff("/tmp/1.dat", "/tmp/2.dat", "/tmp/diff.dat"); ApplyPatch("/tmp/1.dat", "/tmp/diff.dat", "/tmp/3.dat", false); ApplyPatch("/tmp/2.dat", "/tmp/diff.dat", "/tmp/4.dat", true); } TEST(Basic, T2) { std::shared_ptr logger_ptr = spdlog::stderr_color_mt("stderr_logger"); mkdir("/tmp/T2", 0700); remove("/tmp/T2/index.db"); remove("/tmp/T2/data.db"); remove("/tmp/T2/meta.dat"); { DiskMap disk_map("index", "/tmp/T2/index.db", "data", "/tmp/T2/data.db"); SnapShotManager snap_shot_manager; sjtu::vector drivers; drivers.push_back(&disk_map); snap_shot_manager.Connect(drivers); snap_shot_manager.SetLogger(logger_ptr); snap_shot_manager.SetMetaFile("/tmp/T2/meta.dat"); for (int i = 0; i < 100000; i++) disk_map.Put(i, i); snap_shot_manager.CreateSnapShot("snap1"); } { DiskMap disk_map("index", "/tmp/T2/index.db", "data", "/tmp/T2/data.db"); SnapShotManager snap_shot_manager; sjtu::vector drivers; drivers.push_back(&disk_map); snap_shot_manager.Connect(drivers); snap_shot_manager.SetLogger(logger_ptr); snap_shot_manager.SetMetaFile("/tmp/T2/meta.dat"); for (int i = 0; i < 100; i += 10) { int tmp = i + 3; disk_map.Put(i, tmp); } snap_shot_manager.CreateSnapShot("snap2"); snap_shot_manager.SwitchToSnapShot("INIT"); snap_shot_manager.CheckOutFrontier(); } { DiskMap disk_map("index", "/tmp/T2/index.db", "data", "/tmp/T2/data.db"); SnapShotManager snap_shot_manager; sjtu::vector drivers; drivers.push_back(&disk_map); snap_shot_manager.Connect(drivers); snap_shot_manager.SetLogger(logger_ptr); snap_shot_manager.SetMetaFile("/tmp/T2/meta.dat"); snap_shot_manager.SwitchToSnapShot("snap1"); snap_shot_manager.CheckOutFrontier(); } { DiskMap disk_map("index", "/tmp/T2/index.db", "data", "/tmp/T2/data.db"); SnapShotManager snap_shot_manager; sjtu::vector drivers; drivers.push_back(&disk_map); snap_shot_manager.Connect(drivers); snap_shot_manager.SetLogger(logger_ptr); snap_shot_manager.SetMetaFile("/tmp/T2/meta.dat"); for (int i = 0; i < 100000; i++) EXPECT_EQ(disk_map.Get(i), i); snap_shot_manager.SwitchToSnapShot("snap2"); snap_shot_manager.CheckOutFrontier(); } { DiskMap disk_map("index", "/tmp/T2/index.db", "data", "/tmp/T2/data.db"); SnapShotManager snap_shot_manager; sjtu::vector drivers; drivers.push_back(&disk_map); snap_shot_manager.Connect(drivers); snap_shot_manager.SetLogger(logger_ptr); snap_shot_manager.SetMetaFile("/tmp/T2/meta.dat"); for (int i = 0; i < 100; i += 10) EXPECT_EQ(disk_map.Get(i), i + 3); snap_shot_manager.SwitchToSnapShot("snap1"); snap_shot_manager.CheckOutFrontier(); } { DiskMap disk_map("index", "/tmp/T2/index.db", "data", "/tmp/T2/data.db"); SnapShotManager snap_shot_manager; sjtu::vector drivers; drivers.push_back(&disk_map); snap_shot_manager.Connect(drivers); snap_shot_manager.SetLogger(logger_ptr); snap_shot_manager.SetMetaFile("/tmp/T2/meta.dat"); for (int i = 0; i < 100; i += 10) { int tmp = i + 4; disk_map.Put(i, tmp); } snap_shot_manager.CreateSnapShot("snap3"); snap_shot_manager.RemoveSnapShot("snap1"); snap_shot_manager.SwitchToSnapShot("snap2"); snap_shot_manager.CheckOutFrontier(); } { DiskMap disk_map("index", "/tmp/T2/index.db", "data", "/tmp/T2/data.db"); SnapShotManager snap_shot_manager; sjtu::vector drivers; drivers.push_back(&disk_map); snap_shot_manager.Connect(drivers); snap_shot_manager.SetLogger(logger_ptr); snap_shot_manager.SetMetaFile("/tmp/T2/meta.dat"); for (int i = 0; i < 100; i += 10) EXPECT_EQ(disk_map.Get(i), i + 3); snap_shot_manager.SwitchToSnapShot("snap3"); snap_shot_manager.CheckOutFrontier(); } { DiskMap disk_map("index", "/tmp/T2/index.db", "data", "/tmp/T2/data.db"); SnapShotManager snap_shot_manager; sjtu::vector drivers; drivers.push_back(&disk_map); snap_shot_manager.Connect(drivers); snap_shot_manager.SetLogger(logger_ptr); snap_shot_manager.SetMetaFile("/tmp/T2/meta.dat"); for (int i = 0; i < 100; i += 10) EXPECT_EQ(disk_map.Get(i), i + 4); snap_shot_manager.SwitchToSnapShot("INIT"); snap_shot_manager.CheckOutFrontier(); snap_shot_manager.RemoveSnapShot("snap2"); snap_shot_manager.SwitchToSnapShot("snap3"); snap_shot_manager.CheckOutFrontier(); } { DiskMap disk_map("index", "/tmp/T2/index.db", "data", "/tmp/T2/data.db"); SnapShotManager snap_shot_manager; sjtu::vector drivers; drivers.push_back(&disk_map); snap_shot_manager.Connect(drivers); snap_shot_manager.SetLogger(logger_ptr); snap_shot_manager.SetMetaFile("/tmp/T2/meta.dat"); for (int i = 0; i < 100; i += 10) EXPECT_EQ(disk_map.Get(i), i + 4); } }