// Copyright 2021 Memgraph Ltd. // // Use of this software is governed by the Business Source License // included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source // License, and you may not use this file except in compliance with the Business Source License. // // As of the Change Date specified in that file, in accordance with // the Business Source License, use of this software will be governed // by the Apache License, Version 2.0, included in the file // licenses/APL.txt. #include #include #include #include #include #include #include #include #include #include #include #include #include "io/network/utils.hpp" #include "utils/algorithm.hpp" #include "utils/logging.hpp" #include "utils/timer.hpp" #include "long_running_common.hpp" using communication::bolt::Edge; using communication::bolt::Value; using communication::bolt::Vertex; class BfsPokecClient : public TestClient { public: BfsPokecClient(int id, const std::string &db) : TestClient(), rg_(id), db_(db) { auto result = Execute("MATCH (n:User) RETURN count(1)", {}, "NumNodes"); MG_ASSERT(result, "Read-only query should not fail"); num_nodes_ = result->records[0][0].ValueInt(); } private: std::mt19937 rg_; std::string db_; int num_nodes_; int RandomId() { std::uniform_int_distribution dist(1, num_nodes_); auto id = dist(rg_); return id; } void BfsWithDestinationNode() { auto start = RandomId(); auto end = RandomId(); while (start == end) { end = RandomId(); } if (FLAGS_db == "memgraph") { auto result = Execute( "MATCH (n:User {id: $start}), (m:User {id: $end}), " "p = (n)-[*bfs..15]->(m) " "RETURN extract(n in nodes(p) | n.id) AS path", {{"start", start}, {"end", end}}, "Bfs"); MG_ASSERT(result, "Read-only query should not fail!"); } else if (FLAGS_db == "neo4j") { auto result = Execute( "MATCH p = shortestPath(" "(n:User {id: $start})-[*..15]->(m:User {id: $end}))" "RETURN [x in nodes(p) | x.id] AS path;", {{"start", start}, {"end", end}}, "Bfs"); MG_ASSERT(result, "Read-only query should not fail!"); } } void BfsWithoutDestinationNode() { auto start = RandomId(); if (FLAGS_db == "memgraph") { auto result = Execute( "MATCH p = (n:User {id: $start})-[*bfs..15]->(m:User) WHERE m != n " "RETURN extract(n in nodes(p) | n.id) AS path", {{"start", start}}, "Bfs"); MG_ASSERT(result, "Read-only query should not fail!"); } else { auto result = Execute( "MATCH p = shortestPath(" "(n:User {id: $start})-[*..15]->(m:User)) WHERE m <> n " "RETURN [x in nodes(p) | x.id] AS path;", {{"start", start}}, "Bfs"); MG_ASSERT(result, "Read-only query should not fail!"); } } public: virtual void Step() override { if (FLAGS_scenario == "with_destination_node") { BfsWithDestinationNode(); return; } if (FLAGS_scenario == "without_destination_node") { BfsWithoutDestinationNode(); return; } LOG_FATAL("Should not get here: unknown scenario!"); } }; int main(int argc, char **argv) { gflags::ParseCommandLineFlags(&argc, &argv, true); communication::SSLInit sslInit; Endpoint endpoint(FLAGS_address, FLAGS_port); ClientContext context(FLAGS_use_ssl); Client client(&context); client.Connect(endpoint, FLAGS_username, FLAGS_password); std::vector> clients; for (auto i = 0; i < FLAGS_num_workers; ++i) { clients.emplace_back(std::make_unique(i, "memgraph")); } RunMultithreadedTest(clients); return 0; }