From b538fb041c3481492b5ffc754bff806f4ad4c4c5 Mon Sep 17 00:00:00 2001 From: Marko Budiselic Date: Thu, 7 Jul 2016 01:58:26 +0100 Subject: [PATCH] first integration test (basic set of queries is tested) --- CMakeLists.txt | 41 +++-- .../{prepare => hardcode}/main.cpp | 0 src/query_engine/hardcode/queries.hpp | 148 ++++++++++++++++ src/query_engine/main_queries.cpp | 159 +----------------- tests/CMakeLists.txt | 37 ++-- tests/integration/queries.cpp | 40 +++++ 6 files changed, 235 insertions(+), 190 deletions(-) rename src/query_engine/{prepare => hardcode}/main.cpp (100%) create mode 100644 src/query_engine/hardcode/queries.hpp create mode 100644 tests/integration/queries.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 277dc9e04..f0175ae6a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -183,29 +183,28 @@ EXECUTE_PROCESS( # add_executable(query_hasher src/query_engine/main_query_hasher.cpp) # target_link_libraries(query_hasher ${fmt_static_lib}) +set(memgraph_src_files + ${src_dir}/mvcc/id.cpp + ${src_dir}/storage/vertices.cpp + ${src_dir}/storage/label/label.cpp + ${src_dir}/storage/label/label_collection.cpp + ${src_dir}/storage/label/label_store.cpp + ${src_dir}/storage/edge_type/edge_type.cpp + ${src_dir}/storage/edge_type/edge_type_store.cpp + ${src_dir}/storage/model/properties/property.cpp + ${src_dir}/storage/model/properties/null.cpp + ${src_dir}/storage/model/properties/bool.cpp + ${src_dir}/storage/model/properties/string.cpp + ${src_dir}/storage/model/properties/properties.cpp + ${src_dir}/storage/locking/record_lock.cpp + ${src_dir}/storage/vertex_accessor.cpp + ${src_dir}/transactions/transaction.cpp +) # hard coded implementation of queries -add_executable( - queries - src/query_engine/main_queries.cpp - src/mvcc/id.cpp - src/storage/vertices.cpp - src/storage/label/label.cpp - src/storage/label/label_collection.cpp - src/storage/label/label_store.cpp - src/storage/edge_type/edge_type.cpp - src/storage/edge_type/edge_type_store.cpp - src/storage/model/properties/property.cpp - src/storage/model/properties/null.cpp - src/storage/model/properties/bool.cpp - src/storage/model/properties/string.cpp - src/storage/model/properties/properties.cpp - src/storage/locking/record_lock.cpp - src/storage/vertex_accessor.cpp - src/transactions/transaction.cpp -) +add_executable(queries src/query_engine/main_queries.cpp ${memgraph_src_files}) target_link_libraries(queries ${fmt_static_lib}) # tests -# enable_testing() -# add_subdirectory(tests) +enable_testing() +add_subdirectory(tests) diff --git a/src/query_engine/prepare/main.cpp b/src/query_engine/hardcode/main.cpp similarity index 100% rename from src/query_engine/prepare/main.cpp rename to src/query_engine/hardcode/main.cpp diff --git a/src/query_engine/hardcode/queries.hpp b/src/query_engine/hardcode/queries.hpp new file mode 100644 index 000000000..49cd34e9f --- /dev/null +++ b/src/query_engine/hardcode/queries.hpp @@ -0,0 +1,148 @@ +#pragma once + +#include "database/db.hpp" +#include "query_engine/query_stripper.hpp" +#include "storage/model/properties/property.hpp" +#include "storage/model/properties/traversers/consolewriter.hpp" +#include "utils/command_line/arguments.hpp" + +void cout_properties(const Properties &properties) +{ + ConsoleWriter writer; + properties.accept(writer); +} + +auto load_queries(Db& db) +{ + std::map> queries; + + auto create_labeled_and_named_node = [&db](const properties_t &args) { + auto &t = db.tx_engine.begin(); + auto vertex_accessor = db.graph.vertices.insert(t); + vertex_accessor.property("name", args[0]); + auto &label = db.graph.label_store.find_or_create("LABEL"); + vertex_accessor.add_label(label); + cout_properties(vertex_accessor.properties()); + t.commit(); + return true; + }; + + auto create_account = [&db](const properties_t &args) { + auto &t = db.tx_engine.begin(); + auto vertex_accessor = db.graph.vertices.insert(t); + vertex_accessor.property("id", args[0]); + vertex_accessor.property("name", args[1]); + vertex_accessor.property("country", args[2]); + vertex_accessor.property("created_at", args[3]); + auto &label = db.graph.label_store.find_or_create("ACCOUNT"); + vertex_accessor.add_label(label); + cout_properties(vertex_accessor.properties()); + t.commit(); + return true; + }; + + auto find_node_by_internal_id = [&db](const properties_t &args) { + auto &t = db.tx_engine.begin(); + auto id = static_cast(*args[0]); + auto vertex_accessor = db.graph.vertices.find(t, Id(id.value)); + if (!vertex_accessor) { + cout << "vertex doesn't exist" << endl; + t.commit(); + return false; + } + cout_properties(vertex_accessor.properties()); + cout << "LABELS:" << endl; + for (auto label_ref : vertex_accessor.labels()) { + cout << label_ref.get() << endl; + } + t.commit(); + return true; + }; + + auto create_edge = [&db](const properties_t &args) { + auto &t = db.tx_engine.begin(); + + auto v1 = db.graph.vertices.find(t, args[0]->as().value); + if (!v1) return t.commit(), false; + + auto v2 = db.graph.vertices.find(t, args[1]->as().value); + if (!v2) return t.commit(), false; + + auto e = db.graph.edges.insert(t); + + v1.vlist->update(t)->data.out.add(e.vlist); + v2.vlist->update(t)->data.in.add(e.vlist); + + e.from(v1.vlist); + e.to(v2.vlist); + + auto &edge_type = db.graph.edge_type_store.find_or_create("IS"); + e.edge_type(edge_type); + + t.commit(); + + cout << e.edge_type() << endl; + cout_properties(e.properties()); + + return true; + }; + + auto find_edge_by_internal_id = [&db](const properties_t &args) { + auto &t = db.tx_engine.begin(); + auto e = db.graph.edges.find(t, args[0]->as().value); + if (!e) return t.commit(), false; + + // print edge type and properties + cout << "EDGE_TYPE: " << e.edge_type() << endl; + + auto from = e.from(); + cout << "FROM:" << endl; + cout_properties(from->find(t)->data.props); + + auto to = e.to(); + cout << "TO:" << endl; + cout_properties(to->find(t)->data.props); + + t.commit(); + + return true; + }; + + auto update_node = [&db](const properties_t &args) { + auto &t = db.tx_engine.begin(); + + auto v = db.graph.vertices.find(t, args[0]->as().value); + if (!v) return t.commit(), false; + + v.property("name", args[1]); + cout_properties(v.properties()); + + t.commit(); + + return true; + }; + + auto find_by_label = [&db](const properties_t &args) + { + auto &t = db.tx_engine.begin(); + auto &label = db.graph.label_store.find_or_create("LABEL"); + auto &index_record_collection = + db.graph.vertices.find_label_index(label); + auto accessor = index_record_collection.access(); + cout << "VERTICES" << endl; + for (auto& v : accessor) { + cout << v.record->data.props.at("name").as().value << endl; + } + return true; + }; + + queries[10597108978382323595u] = create_account; + queries[5397556489557792025u] = create_labeled_and_named_node; + queries[7939106225150551899u] = create_edge; + queries[11198568396549106428u] = find_node_by_internal_id; + queries[8320600413058284114u] = find_edge_by_internal_id; + queries[6813335159006269041u] = update_node; + queries[4857652843629217005u] = find_by_label; + + return queries; +} diff --git a/src/query_engine/main_queries.cpp b/src/query_engine/main_queries.cpp index c71e7bdb7..bcd4ba6bc 100644 --- a/src/query_engine/main_queries.cpp +++ b/src/query_engine/main_queries.cpp @@ -1,12 +1,6 @@ #include -#include "cypher/common.hpp" -#include "database/db.hpp" -#include "query_stripper.hpp" -#include "storage/model/properties/property.hpp" -#include "storage/model/properties/traversers/consolewriter.hpp" -#include "utils/command_line/arguments.hpp" -#include "utils/time/timer.hpp" +#include "query_engine/hardcode/queries.hpp" using namespace std; @@ -97,158 +91,21 @@ using namespace std; // FULL: MATCH (n:LABEL) RETURN n // STRIPPPED: MATCH(n:LABEL)RETURNn // HASH: 4857652843629217005 -// STATUS: TODO +// STATUS: DONE // -- // TODO: Labels and Types have to be extracted from a query during the // query compile time -void cout_properties(const Properties &properties) -{ - ConsoleWriter writer; - properties.accept(writer); -} +// void cout_properties(const Properties &properties) +// { +// ConsoleWriter writer; +// properties.accept(writer); +// } int main(int argc, char **argv) { Db db; - std::map> queries; - - auto create_labeled_and_named_node = [&db](const properties_t &args) { - auto &t = db.tx_engine.begin(); - auto vertex_accessor = db.graph.vertices.insert(t); - vertex_accessor.property("name", args[0]); - auto &label = db.graph.label_store.find_or_create("LABEL"); - vertex_accessor.add_label(label); - cout_properties(vertex_accessor.properties()); - t.commit(); - - return true; - }; - - auto create_account = [&db](const properties_t &args) { - auto &t = db.tx_engine.begin(); - auto vertex_accessor = db.graph.vertices.insert(t); - // this can be a loop - vertex_accessor.property("id", args[0]); - vertex_accessor.property("name", args[1]); - vertex_accessor.property("country", args[2]); - vertex_accessor.property("created_at", args[3]); - // here is the problem because LABEL can't be stripped out - auto &label = db.graph.label_store.find_or_create("ACCOUNT"); - vertex_accessor.add_label(label); - cout_properties(vertex_accessor.properties()); - t.commit(); - - return true; - }; - - auto find_node_by_internal_id = [&db](const properties_t &args) { - auto &t = db.tx_engine.begin(); - auto id = static_cast(*args[0]); - auto vertex_accessor = db.graph.vertices.find(t, Id(id.value)); - - if (!vertex_accessor) { - cout << "vertex doesn't exist" << endl; - t.commit(); - return false; - } - - cout_properties(vertex_accessor.properties()); - - cout << "LABELS:" << endl; - for (auto label_ref : vertex_accessor.labels()) { - cout << label_ref.get() << endl; - } - - t.commit(); - - return true; - }; - - auto create_edge = [&db](const properties_t &args) { - auto &t = db.tx_engine.begin(); - - auto v1 = db.graph.vertices.find(t, args[0]->as().value); - if (!v1) return t.commit(), false; - - auto v2 = db.graph.vertices.find(t, args[1]->as().value); - if (!v2) return t.commit(), false; - - auto e = db.graph.edges.insert(t); - - v1.vlist->update(t)->data.out.add(e.vlist); - v2.vlist->update(t)->data.in.add(e.vlist); - - e.from(v1.vlist); - e.to(v2.vlist); - - auto &edge_type = db.graph.edge_type_store.find_or_create("IS"); - e.edge_type(edge_type); - - t.commit(); - - cout << e.edge_type() << endl; - cout_properties(e.properties()); - - return true; - }; - - auto find_edge_by_internal_id = [&db](const properties_t &args) { - auto &t = db.tx_engine.begin(); - auto e = db.graph.edges.find(t, args[0]->as().value); - if (!e) return t.commit(), false; - - // print edge type and properties - cout << "EDGE_TYPE: " << e.edge_type() << endl; - - auto from = e.from(); - cout << "FROM:" << endl; - cout_properties(from->find(t)->data.props); - - auto to = e.to(); - cout << "TO:" << endl; - cout_properties(to->find(t)->data.props); - - t.commit(); - - return true; - }; - - auto update_node = [&db](const properties_t &args) { - auto &t = db.tx_engine.begin(); - - auto v = db.graph.vertices.find(t, args[0]->as().value); - if (!v) return t.commit(), false; - - v.property("name", args[1]); - cout_properties(v.properties()); - - t.commit(); - - return true; - }; - - auto find_by_label = [&db](const properties_t &args) - { - auto &t = db.tx_engine.begin(); - auto &label = db.graph.label_store.find_or_create("LABEL"); - auto &index_record_collection = - db.graph.vertices.find_label_index(label); - auto accessor = index_record_collection.access(); - cout << "VERTICES" << endl; - for (auto& v : accessor) { - cout << v.record->data.props.at("name").as().value << endl; - } - return true; - }; - - queries[10597108978382323595u] = create_account; - queries[5397556489557792025u] = create_labeled_and_named_node; - queries[7939106225150551899u] = create_edge; - queries[11198568396549106428u] = find_node_by_internal_id; - queries[8320600413058284114u] = find_edge_by_internal_id; - queries[6813335159006269041u] = update_node; - queries[4857652843629217005u] = find_by_label; + auto queries = load_queries(db); // auto arguments = all_arguments(argc, argv); // auto input_query = extract_query(arguments); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 4a3d0086e..116857a3a 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -18,21 +18,17 @@ message(STATUS "Available unit tests are: ${unit_test_names}") file(COPY ${CMAKE_SOURCE_DIR}/tests/data DESTINATION ${CMAKE_BINARY_DIR}/tests) - # set(chosen_test "concurrent_skiplist") - # build unit tests foreach(test ${unit_test_names}) set(test_name unit_${test}) - # if (${chosen_test} STREQUAL ${test_name}) - add_executable(${test_name} unit/${test}.cpp ${src_dir}/template_engine/engine.cpp) - # TODO: separate dependencies - target_link_libraries(${test_name} stdc++fs) - target_link_libraries(${test_name} cypher_lib) - target_link_libraries(${test_name} Threads::Threads) - target_link_libraries(${test_name} ${fmt_static_lib}) - add_test(NAME ${test_name} COMMAND ${test_name}) - set_property(TARGET ${test_name} PROPERTY CXX_STANDARD 14) - # endif(${chosen_test} STREQUAL ${test_name}) + add_executable(${test_name} unit/${test}.cpp ${src_dir}/template_engine/engine.cpp) + # TODO: separate dependencies + target_link_libraries(${test_name} stdc++fs) + target_link_libraries(${test_name} cypher_lib) + target_link_libraries(${test_name} Threads::Threads) + target_link_libraries(${test_name} ${fmt_static_lib}) + add_test(NAME ${test_name} COMMAND ${test_name}) + set_property(TARGET ${test_name} PROPERTY CXX_STANDARD 14) endforeach() ## CONCURRENCY TESTS @@ -47,10 +43,15 @@ message(STATUS "Available concurrency tests are: ${concurrency_test_names}") # build concurrency tests foreach(test ${concurrency_test_names}) set(test_name concurrent_${test}) - # if (${chosen_test} STREQUAL ${test_name}) - add_executable(${test_name} concurrent/${test}.cpp) - target_link_libraries(${test_name} Threads::Threads) - add_test(NAME ${test_name} COMMAND ${test_name}) - set_property(TARGET ${test_name} PROPERTY CXX_STANDARD 14) - # endif(${chosen_test} STREQUAL ${test_name}) + add_executable(${test_name} concurrent/${test}.cpp) + target_link_libraries(${test_name} Threads::Threads) + add_test(NAME ${test_name} COMMAND ${test_name}) + set_property(TARGET ${test_name} PROPERTY CXX_STANDARD 14) endforeach() + +# build integration tests +message(STATUS ${memgraph_src_files}) +add_executable(integration_queries integration/queries.cpp ${memgraph_src_files}) +target_link_libraries(integration_queries ${fmt_static_lib}) +add_test(NAME integration_queries COMMAND integration_queries) +set_property(TARGET integration_queries PROPERTY CXX_STANDARD 14) diff --git a/tests/integration/queries.cpp b/tests/integration/queries.cpp new file mode 100644 index 000000000..a11d75c95 --- /dev/null +++ b/tests/integration/queries.cpp @@ -0,0 +1,40 @@ +#include "query_engine/hardcode/queries.hpp" +#include "utils/assert.hpp" + +int main(void) +{ + Db db; + + auto query_functions = load_queries(db); + + auto stripper = make_query_stripper(TK_INT, TK_FLOAT, TK_STR, TK_BOOL); + + // TODO: put all queries into a file + std::vector queries = { + "CREATE (n:LABEL {name: \"TEST1\"}) RETURN n", + "CREATE (n:LABEL {name: \"TEST2\"}) RETURN n", + "CREATE (n:LABEL {name: \"TEST3\"}) RETURN n", + "CREATE (n:ACCOUNT {id: 2322, name: \"TEST\", country: \"Croatia\", created_at: 2352352}) RETURN n" , + "MATCH (n {id: 0}) RETURN n", + "MATCH (n {id: 1}) RETURN n", + "MATCH (n {id: 2}) RETURN n", + "MATCH (n {id: 3}) RETURN n", + "MATCH (a {id:0}), (p {id: 1}) CREATE (a)-[r:IS]->(p) RETURN r", + "MATCH (a {id:1}), (p {id: 2}) CREATE (a)-[r:IS]->(p) RETURN r", + "MATCH ()-[r]-() WHERE ID(r)=0 RETURN r", + "MATCH ()-[r]-() WHERE ID(r)=1 RETURN r", + "MATCH (n: {id: 0}) SET n.name = \"TEST100\" RETURN n", + "MATCH (n: {id: 1}) SET n.name = \"TEST101\" RETURN n", + "MATCH (n: {id: 0}) SET n.name = \"TEST102\" RETURN n", + "MATCH (n:LABEL) RETURN n" + }; + + for (auto &query : queries) { + auto stripped = stripper.strip(query); + auto result = query_functions[stripped.hash](stripped.arguments); + permanent_assert(result == true, + "Result retured from query function is not true"); + } + + return 0; +}