memgraph/tools/tests/mg_recovery_check.cpp

70 lines
2.0 KiB
C++
Raw Normal View History

#include <string>
#include "gflags/gflags.h"
#include "gtest/gtest.h"
Write-ahead log Summary: My dear fellow Memgraphians. It's friday afternoon, and I am as ready to pop as WAL is to get reviewed... What's done: - Vertices and Edges have global IDs, stored in `VersionList`. Main storage is now a concurrent map ID->vlist_ptr. - WriteAheadLog class added. It's based around buffering WAL::Op objects (elementraly DB changes) and periodically serializing and flusing them to disk. - Snapshot recovery refactored, WAL recovery added. Snapshot format changed again to include necessary info. - Durability testing completely reworked. What's not done (and should be when we decide how): - Old WAL file purging. - Config refactor (naming and organization). Will do when we discuss what we want. - Changelog and new feature documentation (both depending on the point above). - Better error handling and recovery feedback. Currently it's all returning bools, which is not fine-grained enough (neither for errors nor partial successes, also EOF is reported as a failure at the moment). - Moving the implementation of WAL stuff to .cpp where possible. - Not sure if there are transactions being created outside of `GraphDbAccessor` and it's `BuildIndex`. Need to look into. - True write-ahead logic (flag controlled): not committing a DB transaction if the WAL has not flushed it's data. We can discuss the gain/effort ratio for this feature. Reviewers: buda, mislav.bradac, teon.banek, dgleich Reviewed By: dgleich Subscribers: mtomic, pullbot Differential Revision: https://phabricator.memgraph.io/D958
2017-11-13 16:50:49 +08:00
#include "database/graph_db_accessor.hpp"
#include "database/graph_db.hpp"
#include "durability/recovery.hpp"
#include "query/typed_value.hpp"
static const char *usage =
"--snapshot-dir SNAPSHOT_DIR\n"
"Check that Memgraph can recover that snapshot. This tool should be "
"invoked through 'test_mg_import' wrapper, so as to check that 'mg_import' "
"tools work correctly.\n";
DEFINE_string(snapshot_dir, "", "Path to where the snapshot is stored");
class RecoveryTest : public ::testing::Test {
protected:
void SetUp() override {
Write-ahead log Summary: My dear fellow Memgraphians. It's friday afternoon, and I am as ready to pop as WAL is to get reviewed... What's done: - Vertices and Edges have global IDs, stored in `VersionList`. Main storage is now a concurrent map ID->vlist_ptr. - WriteAheadLog class added. It's based around buffering WAL::Op objects (elementraly DB changes) and periodically serializing and flusing them to disk. - Snapshot recovery refactored, WAL recovery added. Snapshot format changed again to include necessary info. - Durability testing completely reworked. What's not done (and should be when we decide how): - Old WAL file purging. - Config refactor (naming and organization). Will do when we discuss what we want. - Changelog and new feature documentation (both depending on the point above). - Better error handling and recovery feedback. Currently it's all returning bools, which is not fine-grained enough (neither for errors nor partial successes, also EOF is reported as a failure at the moment). - Moving the implementation of WAL stuff to .cpp where possible. - Not sure if there are transactions being created outside of `GraphDbAccessor` and it's `BuildIndex`. Need to look into. - True write-ahead logic (flag controlled): not committing a DB transaction if the WAL has not flushed it's data. We can discuss the gain/effort ratio for this feature. Reviewers: buda, mislav.bradac, teon.banek, dgleich Reviewed By: dgleich Subscribers: mtomic, pullbot Differential Revision: https://phabricator.memgraph.io/D958
2017-11-13 16:50:49 +08:00
std::string snapshot(FLAGS_snapshot_dir);
durability::Recover(snapshot, db_);
}
GraphDb db_;
};
TEST_F(RecoveryTest, TestVerticesRecovered) {
GraphDbAccessor dba(db_);
EXPECT_EQ(dba.VerticesCount(), 10);
EXPECT_EQ(dba.VerticesCount(dba.Label("Comment")), 5);
for (const auto &vertex : dba.Vertices(dba.Label("Comment"), false)) {
EXPECT_TRUE(vertex.has_label(dba.Label("Message")));
}
EXPECT_EQ(dba.VerticesCount(dba.Label("Forum")), 5);
}
TEST_F(RecoveryTest, TestPropertyNull) {
GraphDbAccessor dba(db_);
bool found = false;
for (const auto &vertex : dba.Vertices(dba.Label("Comment"), false)) {
auto id_prop = query::TypedValue(vertex.PropsAt(dba.Property("id")));
auto browser = query::TypedValue(vertex.PropsAt(dba.Property("browser")));
if (id_prop.IsString() && id_prop.Value<std::string>() == "2") {
EXPECT_FALSE(found);
found = true;
EXPECT_TRUE(browser.IsNull());
} else {
EXPECT_FALSE(browser.IsNull());
}
}
ASSERT_TRUE(found);
}
TEST_F(RecoveryTest, TestEdgesRecovered) {
GraphDbAccessor dba(db_);
EXPECT_EQ(dba.EdgesCount(), 5);
for (const auto &edge : dba.Edges(false)) {
EXPECT_TRUE(edge.EdgeType() == dba.EdgeType("POSTED_ON"));
}
}
int main(int argc, char *argv[]) {
::testing::InitGoogleTest(&argc, argv);
gflags::SetUsageMessage(usage);
gflags::ParseCommandLineFlags(&argc, &argv, true);
return RUN_ALL_TESTS();
}