#include "gtest/gtest.h" // #include "leveldb/env.h" // #include "leveldb/db.h" #include "fielddb/field_db.h" #include "test/helper.cc" #include #include #include using namespace fielddb; TEST(TestNormalRecover, Recover) { fielddb::DestroyDB("testdb3.1",Options()); FieldDB *db = new FieldDB(); if(OpenDB("testdb3.1", &db).ok() == false) { std::cerr << "open db failed" << std::endl; abort(); } db->CreateIndexOnField("address", op); db->CreateIndexOnField("age", op); InsertFieldData(db); bool allowNotFound = false; GetFieldData(db, allowNotFound); findKeysByCityIndex(db, true); findKeysByAgeIndex(db, true); delete db; db = new FieldDB(); if(OpenDB("testdb3.1", &db).ok() == false) { std::cerr << "open db failed" << std::endl; abort(); } //仍然能读到之前写入的数据和索引 GetFieldData(db, allowNotFound); findKeysByCityIndex(db, true); findKeysByAgeIndex(db, true); } TEST(TestParalRecover, Recover) { //第一次运行 fielddb::DestroyDB("testdb3.2",Options()); FieldDB *db = new FieldDB(); if(OpenDB("testdb3.2", &db).ok() == false) { std::cerr << "open db failed" << std::endl; abort(); } db->CreateIndexOnField("address", op); db->CreateIndexOnField("age", op); int thread_num_ = 4; std::vector threads(thread_num_); threads[0] = std::thread([db](){ InsertFieldData(db); }); threads[1] = std::thread([db](){ WriteFieldData(db); }); threads[2] = std::thread([db](){ DeleteFieldData(db); }); threads[3] = std::thread([db](){ InsertOneField(db); delete db; }); for (auto& t : threads) { if (t.joinable()) { t.join(); } } //线程3导致了其他线程错误,测试会终止(模拟数据库崩溃) //这会导致各线程在各种奇怪的时间点崩溃 //第二次运行注释掉上面的代码,运行下面的代码测试恢复 //第二次运行 // FieldDB *db = new FieldDB(); // if(OpenDB("testdb3.2", &db).ok() == false) { // std::cerr << "open db failed" << std::endl; // abort(); // } // GetOneField(db); // checkDataInKVAndIndex(db); //这里会出现两个数字,如果>1说明除了线程3插入的一条数据,其他线程也有数据在崩溃前被正确恢复了 } int main(int argc, char** argv) { // All tests currently run with the same read-only file limits. testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }