2018-04-03 22:51:23 +08:00
|
|
|
#include <gtest/gtest.h>
|
|
|
|
|
|
|
|
#include "distributed_common.hpp"
|
|
|
|
|
2018-07-05 16:55:00 +08:00
|
|
|
class DistributedGcTest : public DistributedGraphDbTest {
|
|
|
|
public:
|
|
|
|
DistributedGcTest() : DistributedGraphDbTest("gc") {}
|
|
|
|
};
|
|
|
|
|
|
|
|
TEST_F(DistributedGcTest, GarbageCollect) {
|
2018-07-26 15:08:21 +08:00
|
|
|
auto dba = master().Access();
|
|
|
|
auto tx = dba->transaction_id();
|
|
|
|
dba->Commit();
|
2018-04-03 22:51:23 +08:00
|
|
|
|
|
|
|
// Create multiple transactions so that the commit log can be cleared
|
|
|
|
for (int i = 0; i < tx::CommitLog::kBitsetBlockSize; ++i) {
|
2018-07-26 15:08:21 +08:00
|
|
|
auto dba = master().Access();
|
2018-04-03 22:51:23 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
master().CollectGarbage();
|
|
|
|
worker(1).CollectGarbage();
|
|
|
|
worker(2).CollectGarbage();
|
|
|
|
EXPECT_EQ(master().tx_engine().Info(tx).is_committed(), true);
|
|
|
|
|
2018-07-26 15:08:21 +08:00
|
|
|
auto dba2 = master().Access();
|
|
|
|
auto tx_last = dba2->transaction_id();
|
|
|
|
dba2->Commit();
|
2018-04-03 22:51:23 +08:00
|
|
|
|
|
|
|
worker(1).CollectGarbage();
|
|
|
|
worker(2).CollectGarbage();
|
|
|
|
master().CollectGarbage();
|
|
|
|
|
|
|
|
EXPECT_DEATH(master().tx_engine().Info(tx), "chunk is nullptr");
|
|
|
|
EXPECT_DEATH(worker(1).tx_engine().Info(tx), "chunk is nullptr");
|
|
|
|
EXPECT_DEATH(worker(2).tx_engine().Info(tx), "chunk is nullptr");
|
|
|
|
EXPECT_EQ(master().tx_engine().Info(tx_last).is_committed(), true);
|
|
|
|
EXPECT_EQ(worker(1).tx_engine().Info(tx_last).is_committed(), true);
|
|
|
|
EXPECT_EQ(worker(2).tx_engine().Info(tx_last).is_committed(), true);
|
|
|
|
}
|
|
|
|
|
2018-07-05 16:55:00 +08:00
|
|
|
TEST_F(DistributedGcTest, GarbageCollectBlocked) {
|
2018-07-26 15:08:21 +08:00
|
|
|
auto dba = master().Access();
|
|
|
|
auto tx = dba->transaction_id();
|
|
|
|
dba->Commit();
|
2018-04-03 22:51:23 +08:00
|
|
|
|
|
|
|
// Block garbage collection because this is a still alive transaction on the
|
|
|
|
// worker
|
2018-07-26 15:08:21 +08:00
|
|
|
auto dba3 = worker(1).Access();
|
2018-04-03 22:51:23 +08:00
|
|
|
|
|
|
|
// Create multiple transactions so that the commit log can be cleared
|
|
|
|
for (int i = 0; i < tx::CommitLog::kBitsetBlockSize; ++i) {
|
2018-07-26 15:08:21 +08:00
|
|
|
auto dba = master().Access();
|
2018-04-03 22:51:23 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Query for a large id so that the commit log new block is created
|
|
|
|
master().tx_engine().Info(tx::CommitLog::kBitsetBlockSize);
|
|
|
|
|
|
|
|
master().CollectGarbage();
|
|
|
|
worker(1).CollectGarbage();
|
|
|
|
worker(2).CollectGarbage();
|
|
|
|
EXPECT_EQ(master().tx_engine().Info(tx).is_committed(), true);
|
|
|
|
|
2018-07-26 15:08:21 +08:00
|
|
|
auto dba2 = master().Access();
|
|
|
|
auto tx_last = dba2->transaction_id();
|
|
|
|
dba2->Commit();
|
2018-04-03 22:51:23 +08:00
|
|
|
|
|
|
|
worker(1).CollectGarbage();
|
|
|
|
worker(2).CollectGarbage();
|
|
|
|
master().CollectGarbage();
|
|
|
|
|
|
|
|
EXPECT_EQ(master().tx_engine().Info(tx).is_committed(), true);
|
|
|
|
EXPECT_EQ(worker(1).tx_engine().Info(tx).is_committed(), true);
|
|
|
|
EXPECT_EQ(worker(2).tx_engine().Info(tx).is_committed(), true);
|
|
|
|
EXPECT_EQ(master().tx_engine().Info(tx_last).is_committed(), true);
|
|
|
|
EXPECT_EQ(worker(1).tx_engine().Info(tx_last).is_committed(), true);
|
|
|
|
EXPECT_EQ(worker(2).tx_engine().Info(tx_last).is_committed(), true);
|
|
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, char **argv) {
|
|
|
|
::testing::FLAGS_gtest_death_test_style = "threadsafe";
|
|
|
|
::testing::InitGoogleTest(&argc, argv);
|
|
|
|
return RUN_ALL_TESTS();
|
|
|
|
}
|