memgraph/tests/unit/distributed_plan_pretty_print.cpp
Teon Banek e128a9f80f Move distributed query stuff to new folder
Summary:
The new distributed directory is inside the query, and mirrors the query
structure. This groups all of the distributed (query) source code
together, which should make the potential directory extraction easier.

Reviewers: mferencevic, llugovic, mtomic

Reviewed By: mferencevic

Subscribers: pullbot

Differential Revision: https://phabricator.memgraph.io/D1923
2019-04-24 09:34:53 +02:00

290 lines
9.6 KiB
C++

#include <gtest/gtest.h>
#include "database/distributed/graph_db.hpp"
#include "query/frontend/semantic/symbol_table.hpp"
#include "query/distributed/plan/ops.hpp"
#include "query/distributed/plan/pretty_print.hpp"
#include "distributed_common.hpp"
#include "query_common.hpp"
using namespace query;
using namespace query::plan;
// The JSON formatted plan is consumed (or will be) by Memgraph Lab, and
// therefore should not be changed before synchronizing with whoever is
// maintaining Memgraph Lab. Hopefully, one day integration tests will exist and
// there will be no need to be super careful.
// This is a hack to prevent Googletest from crashing when outputing JSONs.
namespace nlohmann {
void PrintTo(const json &json, std::ostream *os) {
*os << std::endl << json.dump(1);
}
} // namespace nlohmann
using namespace nlohmann;
class PrintToJsonTest : public ::testing::Test {
public:
static void SetUpTestCase() {
cluster_ = std::make_unique<Cluster>(0, "distributed_plan_to_json");
}
static void TearDownTestCase() { cluster_ = nullptr; }
protected:
PrintToJsonTest() : dba_ptr(cluster_->master()->Access()), dba(*dba_ptr) {}
AstStorage storage;
SymbolTable symbol_table;
std::unique_ptr<database::GraphDbAccessor> dba_ptr;
database::GraphDbAccessor &dba;
Symbol GetSymbol(std::string name) {
return symbol_table.CreateSymbol(name, true);
}
void Check(LogicalOperator *root, std::string expected) {
EXPECT_EQ(DistributedPlanToJson(dba, root), json::parse(expected));
}
static std::unique_ptr<Cluster> cluster_;
};
std::unique_ptr<Cluster> PrintToJsonTest::cluster_{nullptr};
TEST_F(PrintToJsonTest, PullRemote) {
Symbol node_sym = GetSymbol("node");
std::shared_ptr<LogicalOperator> last_op;
last_op = std::make_shared<ScanAll>(nullptr, GetSymbol("node"));
last_op =
std::make_shared<PullRemote>(last_op, 1, std::vector<Symbol>{node_sym});
Check(last_op.get(), R"(
{
"name" : "PullRemote",
"symbols" : ["node"],
"input" : {
"name" : "ScanAll",
"output_symbol" : "node",
"input" : { "name" : "Once" }
}
})");
}
TEST_F(PrintToJsonTest, Synchronize) {
storage::Property prop = dba.Property("prop");
auto node_sym = GetSymbol("node");
std::shared_ptr<LogicalOperator> last_op =
std::make_shared<ScanAll>(nullptr, node_sym);
last_op = std::make_shared<plan::SetProperty>(
last_op, prop, PROPERTY_LOOKUP("node", prop),
ADD(PROPERTY_LOOKUP("node", prop), LITERAL(1)));
auto pull_remote =
std::make_shared<PullRemote>(last_op, 1, std::vector<Symbol>{node_sym});
last_op = std::make_shared<Synchronize>(std::make_shared<Once>(), pull_remote,
true);
Check(last_op.get(), R"sep(
{
"name" : "Synchronize",
"advance_command" : true,
"input" : { "name" : "Once" },
"pull_remote" : {
"name" : "PullRemote",
"symbols" : ["node"],
"input" : {
"name" : "SetProperty",
"property" : "prop",
"lhs" : "(PropertyLookup (Identifier \"node\") \"prop\")",
"rhs" : "(+ (PropertyLookup (Identifier \"node\") \"prop\") 1)",
"input" : {
"name" : "ScanAll",
"output_symbol" : "node",
"input" : { "name" : "Once" }
}
}
}
})sep");
}
TEST_F(PrintToJsonTest, SynchronizeNoPullRemote) {
auto last_op =
std::make_shared<Synchronize>(std::make_shared<Once>(), nullptr, false);
Check(last_op.get(), R"sep(
{
"name" : "Synchronize",
"advance_command" : false,
"input" : { "name" : "Once" },
"pull_remote" : null
})sep");
}
TEST_F(PrintToJsonTest, PullRemoteOrderBy) {
Symbol node_sym = GetSymbol("node");
storage::Property value = dba.Property("value");
storage::Property color = dba.Property("color");
std::shared_ptr<LogicalOperator> last_op =
std::make_shared<ScanAll>(nullptr, node_sym);
last_op = std::make_shared<PullRemoteOrderBy>(
last_op, 1,
std::vector<SortItem>{{Ordering::ASC, PROPERTY_LOOKUP("node", value)},
{Ordering::DESC, PROPERTY_LOOKUP("node", color)}},
std::vector<Symbol>{node_sym});
Check(last_op.get(), R"sep(
{
"name" : "PullRemoteOrderBy",
"order_by" : [
{
"ordering" : "asc",
"expression" : "(PropertyLookup (Identifier \"node\") \"value\")"
},
{
"ordering" : "desc",
"expression" : "(PropertyLookup (Identifier \"node\") \"color\")"
}
],
"symbols" : ["node"],
"input" : {
"name" : "ScanAll",
"output_symbol" : "node",
"input" : { "name" : "Once" }
}
})sep");
}
TEST_F(PrintToJsonTest, Expand) {
auto node1_sym = GetSymbol("node1");
std::shared_ptr<LogicalOperator> last_op =
std::make_shared<ScanAll>(nullptr, node1_sym);
last_op = std::make_shared<DistributedExpand>(
last_op, node1_sym, GetSymbol("node2"), GetSymbol("edge"),
EdgeAtom::Direction::BOTH,
std::vector<storage::EdgeType>{dba.EdgeType("EdgeType1"),
dba.EdgeType("EdgeType2")},
false, GraphView::OLD);
Check(last_op.get(), R"(
{
"name" : "DistributedExpand",
"input_symbol" : "node1",
"node_symbol" : "node2",
"edge_symbol" : "edge",
"direction" : "both",
"edge_types" : ["EdgeType1", "EdgeType2"],
"existing_node" : false,
"input" : {
"name" : "ScanAll",
"output_symbol" : "node1",
"input" : { "name" : "Once" }
}
})");
}
TEST_F(PrintToJsonTest, DistributedExpandBfs) {
auto node1_sym = GetSymbol("node1");
std::shared_ptr<LogicalOperator> last_op =
std::make_shared<ScanAll>(nullptr, node1_sym);
last_op = std::make_shared<DistributedExpandBfs>(
last_op, node1_sym, GetSymbol("node2"), GetSymbol("edge"),
EdgeAtom::Direction::OUT,
std::vector<storage::EdgeType>{dba.EdgeType("EdgeType1"),
dba.EdgeType("EdgeType2")},
false, LITERAL(2), LITERAL(5),
ExpansionLambda{
GetSymbol("inner_node"), GetSymbol("inner_edge"),
PROPERTY_LOOKUP("inner_node", dba.Property("unblocked"))});
Check(last_op.get(), R"sep(
{
"name" : "DistributedExpandBfs",
"input_symbol" : "node1",
"node_symbol" : "node2",
"edge_symbol" : "edge",
"direction" : "out",
"edge_types" : ["EdgeType1", "EdgeType2"],
"existing_node" : false,
"lower_bound" : "2",
"upper_bound" : "5",
"input" : {
"name" : "ScanAll",
"output_symbol" : "node1",
"input" : { "name" : "Once" }
},
"filter_lambda" : "(PropertyLookup (Identifier \"inner_node\") \"unblocked\")"
})sep");
}
TEST_F(PrintToJsonTest, DistributedCreateNode) {
std::shared_ptr<LogicalOperator> last_op;
last_op = std::make_shared<DistributedCreateNode>(
std::make_shared<Once>(),
NodeCreationInfo{GetSymbol("node"),
{dba.Label("Label1"), dba.Label("Label2")},
{{dba.Property("prop1"), LITERAL(5)},
{dba.Property("prop2"), LITERAL("some cool stuff")}}},
true);
Check(last_op.get(), R"(
{
"name" : "DistributedCreateNode",
"on_random_worker" : true,
"node_info" : {
"symbol" : "node",
"labels" : ["Label1", "Label2"],
"properties" : {
"prop1" : "5",
"prop2" : "\"some cool stuff\""
}
},
"input" : { "name" : "Once" }
})");
}
TEST_F(PrintToJsonTest, DistributedCreateExpand) {
Symbol node1_sym = GetSymbol("node1");
std::shared_ptr<LogicalOperator> last_op =
std::make_shared<ScanAll>(nullptr, GetSymbol("node1"));
last_op = std::make_shared<DistributedCreateExpand>(
NodeCreationInfo{GetSymbol("node2"),
{dba.Label("Label1"), dba.Label("Label2")},
{{dba.Property("prop1"), LITERAL(5)},
{dba.Property("prop2"), LITERAL("some cool stuff")}}},
EdgeCreationInfo{GetSymbol("edge"),
{{dba.Property("weight"), LITERAL(5.32)}},
dba.EdgeType("edge_type"),
EdgeAtom::Direction::OUT},
last_op, node1_sym, false);
Check(last_op.get(), R"(
{
"name" : "DistributedCreateExpand",
"node_info" : {
"symbol" : "node2",
"labels" : ["Label1", "Label2"],
"properties" : {
"prop1" : "5",
"prop2" : "\"some cool stuff\""
}
},
"edge_info" : {
"symbol" : "edge",
"properties" : {
"weight" : "5.32"
},
"edge_type" : "edge_type",
"direction" : "out"
},
"input" : {
"name" : "ScanAll",
"output_symbol" : "node1",
"input" : { "name" : "Once" }
},
"input_symbol" : "node1",
"existing_node" : false
})");
}