b90375c3ae
Summary: This diff removes the need for a database when parsing a query and creating an Ast. Instead of storing storage::{Label,Property,EdgeType} in Ast nodes, we store the name and an index into all of the names. This allows for easy creation of a map from {Label,Property,EdgeType} index into the concrete storage type. Obviously, this comes with a performance penalty during execution, but it should be minor. The upside is that the query/frontend minimally depends on storage (PropertyValue), which makes writing tests easier as well as running them a lot faster (there is no database setup). This is most noticeable in the ast_serialization test which took a long time due to start up of a distributed database. Reviewers: mtomic, llugovic Reviewed By: mtomic Subscribers: mferencevic, pullbot Differential Revision: https://phabricator.memgraph.io/D1774
135 lines
4.7 KiB
C++
135 lines
4.7 KiB
C++
#include <gmock/gmock.h>
|
|
#include <gtest/gtest.h>
|
|
|
|
#include "query/frontend/semantic/required_privileges.hpp"
|
|
#include "storage/common/types/types.hpp"
|
|
|
|
#include "query_common.hpp"
|
|
|
|
using namespace query;
|
|
|
|
class FakeDbAccessor {};
|
|
|
|
const std::string EDGE_TYPE = "0";
|
|
const std::string LABEL_0 = "label0";
|
|
const std::string LABEL_1 = "label1";
|
|
const std::string PROP_0 = "prop0";
|
|
|
|
using ::testing::UnorderedElementsAre;
|
|
|
|
class TestPrivilegeExtractor : public ::testing::Test {
|
|
protected:
|
|
AstStorage storage;
|
|
FakeDbAccessor dba;
|
|
};
|
|
|
|
TEST_F(TestPrivilegeExtractor, CreateNode) {
|
|
auto *query = QUERY(SINGLE_QUERY(CREATE(PATTERN(NODE("n")))));
|
|
EXPECT_THAT(GetRequiredPrivileges(query),
|
|
UnorderedElementsAre(AuthQuery::Privilege::CREATE));
|
|
}
|
|
|
|
TEST_F(TestPrivilegeExtractor, MatchNodeDelete) {
|
|
auto *query =
|
|
QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("n"))), DELETE(IDENT("n"))));
|
|
EXPECT_THAT(GetRequiredPrivileges(query),
|
|
UnorderedElementsAre(AuthQuery::Privilege::MATCH,
|
|
AuthQuery::Privilege::DELETE));
|
|
}
|
|
|
|
TEST_F(TestPrivilegeExtractor, MatchNodeReturn) {
|
|
auto *query = QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("n"))), RETURN("n")));
|
|
EXPECT_THAT(GetRequiredPrivileges(query),
|
|
UnorderedElementsAre(AuthQuery::Privilege::MATCH));
|
|
}
|
|
|
|
TEST_F(TestPrivilegeExtractor, MatchCreateExpand) {
|
|
auto *query = QUERY(SINGLE_QUERY(
|
|
MATCH(PATTERN(NODE("n"))),
|
|
CREATE(PATTERN(NODE("n"),
|
|
EDGE("r", EdgeAtom::Direction::OUT, {EDGE_TYPE}),
|
|
NODE("m")))));
|
|
EXPECT_THAT(GetRequiredPrivileges(query),
|
|
UnorderedElementsAre(AuthQuery::Privilege::MATCH,
|
|
AuthQuery::Privilege::CREATE));
|
|
}
|
|
|
|
TEST_F(TestPrivilegeExtractor, MatchNodeSetLabels) {
|
|
auto *query = QUERY(
|
|
SINGLE_QUERY(MATCH(PATTERN(NODE("n"))), SET("n", {LABEL_0, LABEL_1})));
|
|
EXPECT_THAT(GetRequiredPrivileges(query),
|
|
UnorderedElementsAre(AuthQuery::Privilege::MATCH,
|
|
AuthQuery::Privilege::SET));
|
|
}
|
|
|
|
TEST_F(TestPrivilegeExtractor, MatchNodeSetProperty) {
|
|
auto *query = QUERY(
|
|
SINGLE_QUERY(MATCH(PATTERN(NODE("n"))),
|
|
SET(PROPERTY_LOOKUP(storage.Create<Identifier>("n"), PROP_0),
|
|
LITERAL(42))));
|
|
EXPECT_THAT(GetRequiredPrivileges(query),
|
|
UnorderedElementsAre(AuthQuery::Privilege::MATCH,
|
|
AuthQuery::Privilege::SET));
|
|
}
|
|
|
|
TEST_F(TestPrivilegeExtractor, MatchNodeSetProperties) {
|
|
auto *query =
|
|
QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("n"))), SET("n", LIST())));
|
|
EXPECT_THAT(GetRequiredPrivileges(query),
|
|
UnorderedElementsAre(AuthQuery::Privilege::MATCH,
|
|
AuthQuery::Privilege::SET));
|
|
}
|
|
|
|
TEST_F(TestPrivilegeExtractor, MatchNodeRemoveLabels) {
|
|
auto *query = QUERY(
|
|
SINGLE_QUERY(MATCH(PATTERN(NODE("n"))), REMOVE("n", {LABEL_0, LABEL_1})));
|
|
EXPECT_THAT(GetRequiredPrivileges(query),
|
|
UnorderedElementsAre(AuthQuery::Privilege::MATCH,
|
|
AuthQuery::Privilege::REMOVE));
|
|
}
|
|
|
|
TEST_F(TestPrivilegeExtractor, MatchNodeRemoveProperty) {
|
|
auto *query = QUERY(SINGLE_QUERY(
|
|
MATCH(PATTERN(NODE("n"))),
|
|
REMOVE(PROPERTY_LOOKUP(storage.Create<Identifier>("n"), PROP_0))));
|
|
EXPECT_THAT(GetRequiredPrivileges(query),
|
|
UnorderedElementsAre(AuthQuery::Privilege::MATCH,
|
|
AuthQuery::Privilege::REMOVE));
|
|
}
|
|
|
|
TEST_F(TestPrivilegeExtractor, CreateIndex) {
|
|
auto *query = CREATE_INDEX_ON(storage.GetLabelIx(LABEL_0),
|
|
storage.GetPropertyIx(PROP_0));
|
|
EXPECT_THAT(GetRequiredPrivileges(query),
|
|
UnorderedElementsAre(AuthQuery::Privilege::INDEX));
|
|
}
|
|
|
|
TEST_F(TestPrivilegeExtractor, AuthQuery) {
|
|
auto *query = AUTH_QUERY(AuthQuery::Action::CREATE_ROLE, "", "role", "",
|
|
nullptr, std::vector<AuthQuery::Privilege>{});
|
|
EXPECT_THAT(GetRequiredPrivileges(query),
|
|
UnorderedElementsAre(AuthQuery::Privilege::AUTH));
|
|
}
|
|
|
|
TEST_F(TestPrivilegeExtractor, StreamQuery) {
|
|
std::string stream_name("kafka");
|
|
std::string stream_uri("localhost:1234");
|
|
std::string stream_topic("tropik");
|
|
std::string transform_uri("localhost:1234/file.py");
|
|
|
|
std::vector<StreamQuery *> stream_queries = {
|
|
CREATE_STREAM(stream_name, stream_uri, stream_topic, transform_uri,
|
|
nullptr, nullptr),
|
|
DROP_STREAM(stream_name),
|
|
SHOW_STREAMS,
|
|
START_STREAM(stream_name, nullptr),
|
|
STOP_STREAM(stream_name),
|
|
START_ALL_STREAMS,
|
|
STOP_ALL_STREAMS};
|
|
|
|
for (auto *query : stream_queries) {
|
|
EXPECT_THAT(GetRequiredPrivileges(query),
|
|
UnorderedElementsAre(AuthQuery::Privilege::STREAM));
|
|
}
|
|
}
|