Bug fixes: RELEASE MODE - asserts

This commit is contained in:
Marko Budiselic 2016-12-19 18:32:44 +01:00
parent 021da26ac9
commit 362bc3ba48
13 changed files with 338 additions and 274 deletions

View File

@ -118,7 +118,8 @@ FILE(COPY ${include_dir}/utils/char_str.hpp DESTINATION ${build_include_dir}/uti
FILE(COPY ${include_dir}/utils/void.hpp DESTINATION ${build_include_dir}/utils)
FILE(COPY ${include_dir}/utils/array_store.hpp DESTINATION ${build_include_dir}/utils)
FILE(COPY ${include_dir}/utils/bswap.hpp DESTINATION ${build_include_dir}/utils)
FILE(COPY ${include_dir}/utils/stacktrace.hpp DESTINATION ${build_include_dir}/utils)
FILE(COPY ${include_dir}/utils/stacktrace/stacktrace.hpp DESTINATION ${build_include_dir}/utils/stacktrace)
FILE(COPY ${include_dir}/utils/stacktrace/log.hpp DESTINATION ${build_include_dir}/utils/stacktrace)
FILE(COPY ${include_dir}/utils/auto_scope.hpp DESTINATION ${build_include_dir}/utils)
FILE(COPY ${include_dir}/utils/assert.hpp DESTINATION ${build_include_dir}/utils)
FILE(COPY ${include_dir}/utils/reference_wrapper.hpp DESTINATION ${build_include_dir}/utils)

View File

@ -25,9 +25,12 @@
// parmanant exception will always be executed
#define permanent_assert(condition, message) \
if (!(condition)) { \
if (!(condition)) \
{ \
std::ostringstream s; \
s << message; \
std::cout << s.str() << std::endl; \
std::exit(EXIT_FAILURE); \
}
// assert_error_handler_(__FILE__, __LINE__, s.str().c_str());

View File

@ -4,39 +4,25 @@
#include <stdexcept>
#include "utils/auto_scope.hpp"
#include "utils/stacktrace.hpp"
#include "utils/stacktrace/stacktrace.hpp"
class BasicException : public std::exception {
public:
BasicException(const std::string &message, uint64_t stacktrace_size) noexcept
: message_(message),
stacktrace_size_(stacktrace_size) {
generate_stacktrace();
}
BasicException(const std::string &message) noexcept : message_(message),
stacktrace_size_(10) {
generate_stacktrace();
}
template <class... Args>
BasicException(const std::string &format, Args &&... args) noexcept
: BasicException(fmt::format(format, std::forward<Args>(args)...)) {}
const char *what() const noexcept override { return message_.c_str(); }
private:
std::string message_;
uint64_t stacktrace_size_;
void generate_stacktrace() {
#ifndef NDEBUG
Stacktrace stacktrace;
int size = std::min(stacktrace_size_, stacktrace.size());
for (int i = 0; i < size; i++) {
message_.append(fmt::format("\n at {} ({})", stacktrace[i].function,
stacktrace[i].location));
class BasicException : public std::exception
{
public:
BasicException(const std::string &message) noexcept : message_(message)
{
Stacktrace stacktrace;
message_.append(stacktrace.dump());
}
#endif
}
template <class... Args>
BasicException(const std::string &format, Args &&... args) noexcept
: BasicException(fmt::format(format, std::forward<Args>(args)...))
{
}
const char *what() const noexcept override { return message_.c_str(); }
private:
std::string message_;
};

View File

@ -8,34 +8,40 @@
using Function = std::function<void()>;
enum class Signal : int {
Terminate = SIGTERM,
SegmentationFault = SIGSEGV,
Interupt = SIGINT,
Quit = SIGQUIT,
Abort = SIGABRT
// TODO: align bits so signals can be combined
// Signal::Terminate | Signal::Interupt
enum class Signal : int
{
Terminate = SIGTERM,
SegmentationFault = SIGSEGV,
Interupt = SIGINT,
Quit = SIGQUIT,
Abort = SIGABRT,
BusError = SIGBUS,
};
class SignalHandler {
private:
static std::map<int, std::function<void()>> handlers_;
class SignalHandler
{
private:
static std::map<int, std::function<void()>> handlers_;
static void handle(int signal) { handlers_[signal](); }
static void handle(int signal) { handlers_[signal](); }
public:
static void register_handler(Signal signal, Function func) {
int signal_number = static_cast<int>(signal);
handlers_[signal_number] = func;
std::signal(signal_number, SignalHandler::handle);
}
// TODO possible changes if signelton needed later
/*
static SignalHandler& instance() {
static SignalHandler instance;
return instance;
public:
static void register_handler(Signal signal, Function func)
{
int signal_number = static_cast<int>(signal);
handlers_[signal_number] = func;
std::signal(signal_number, SignalHandler::handle);
}
*/
// TODO possible changes if signelton needed later
/*
static SignalHandler& instance() {
static SignalHandler instance;
return instance;
}
*/
};
std::map<int, std::function<void()>> SignalHandler::handlers_ = {};

View File

@ -0,0 +1,11 @@
#pragma once
#include "logging/default.hpp"
#include "utils/stacktrace/stacktrace.hpp"
void log_stacktrace(const std::string& title)
{
Stacktrace stacktrace;
logging::info(title);
logging::info(stacktrace.dump());
}

View File

@ -1,10 +1,10 @@
#pragma once
#include <cxxabi.h>
#include <stdexcept>
#include <execinfo.h>
#include <fmt/format.h>
#include <stdexcept>
#include "utils/auto_scope.hpp"
class Stacktrace
@ -13,11 +13,13 @@ public:
class Line
{
public:
Line(const std::string& original) : original(original) {}
Line(const std::string &original) : original(original) {}
Line(const std::string& original, const std::string& function,
const std::string& location)
: original(original), function(function), location(location) {}
Line(const std::string &original, const std::string &function,
const std::string &location)
: original(original), function(function), location(location)
{
}
std::string original, function, location;
};
@ -26,17 +28,17 @@ public:
Stacktrace()
{
void* addresses[stacktrace_depth];
void *addresses[stacktrace_depth];
auto depth = backtrace(addresses, stacktrace_depth);
// will this leak if backtrace_symbols throws?
char** symbols = nullptr;
char **symbols = nullptr;
Auto(free(symbols));
symbols = backtrace_symbols(addresses, depth);
// skip the first one since it will be Stacktrace::Stacktrace()
for(int i = 1; i < depth; ++i)
for (int i = 1; i < depth; ++i)
lines.emplace_back(format(symbols[i]));
}
@ -48,54 +50,53 @@ public:
auto end() const { return lines.end(); }
auto cend() const { return lines.cend(); }
const Line& operator[](size_t idx) const
{
return lines[idx];
}
const Line &operator[](size_t idx) const { return lines[idx]; }
size_t size() const
{
return lines.size();
}
size_t size() const { return lines.size(); }
template <class Stream>
void dump(Stream& stream) {
stream << dump();
void dump(Stream &stream)
{
stream << dump();
}
std::string dump() {
std::string message;
for (int i = 0; i < size(); i++) {
message.append(fmt::format("at {} ({}) \n", lines[i].function,
lines[i].location));
}
return message;
std::string dump()
{
std::string message;
for (size_t i = 0; i < size(); i++)
{
message.append(fmt::format("at {} ({}) \n", lines[i].function,
lines[i].location));
}
return message;
}
private:
std::vector<Line> lines;
Line format(const std::string& original)
Line format(const std::string &original)
{
using namespace abi;
auto line = original;
auto begin = line.find('(');
auto end = line.find('+');
auto end = line.find('+');
if(begin == std::string::npos || end == std::string::npos)
if (begin == std::string::npos || end == std::string::npos)
return {original};
line[end] = '\0';
int s;
auto demangled = __cxa_demangle(line.data() + begin + 1, nullptr,
nullptr, &s);
auto demangled =
__cxa_demangle(line.data() + begin + 1, nullptr, nullptr, &s);
auto location = line.substr(0, begin);
auto function = demangled ? std::string(demangled)
: fmt::format("{}()", original.substr(begin + 1, end - begin - 1));
auto function =
demangled ? std::string(demangled)
: fmt::format("{}()", original.substr(begin + 1,
end - begin - 1));
return {original, function, location};
}

View File

@ -1,28 +1,34 @@
#pragma once
#include "utils/auto_scope.hpp"
#include "utils/stacktrace.hpp"
#include "utils/stacktrace/stacktrace.hpp"
#include <execinfo.h>
#include <iostream>
// TODO: log to local file or remote database
void stacktrace(std::ostream& stream) noexcept {
Stacktrace stacktrace;
stacktrace.dump(stream);
void stacktrace(std::ostream &stream) noexcept
{
Stacktrace stacktrace;
stacktrace.dump(stream);
}
// TODO: log to local file or remote database
void terminate_handler(std::ostream& stream) noexcept {
if (auto exc = std::current_exception()) {
try {
std::rethrow_exception(exc);
} catch (std::exception& ex) {
stream << ex.what() << std::endl << std::endl;
stacktrace(stream);
void terminate_handler(std::ostream &stream) noexcept
{
if (auto exc = std::current_exception())
{
try
{
std::rethrow_exception(exc);
}
catch (std::exception &ex)
{
stream << ex.what() << std::endl << std::endl;
stacktrace(stream);
}
}
}
std::abort();
std::abort();
}
void terminate_handler() noexcept { terminate_handler(std::cout); }

View File

@ -1,5 +1,5 @@
#include <signal.h>
#include <iostream>
#include <signal.h>
#include "communication/bolt/v1/server/server.hpp"
#include "communication/bolt/v1/server/worker.hpp"
@ -10,78 +10,74 @@
#include "logging/streams/stdout.hpp"
#include "utils/signals/handler.hpp"
#include "utils/stacktrace.hpp"
#include "utils/terminate_handler.hpp"
#include "utils/stacktrace/log.hpp"
static bolt::Server<bolt::Worker>* serverptr;
static bolt::Server<bolt::Worker> *serverptr;
Logger logger;
static constexpr const char* interface = "0.0.0.0";
static constexpr const char* port = "7687";
// TODO: load from configuration
static constexpr const char *interface = "0.0.0.0";
static constexpr const char *port = "7687";
void throw_and_stacktace(std::string message) {
Stacktrace stacktrace;
logger.info(stacktrace.dump());
}
int main(void) {
// TODO figure out what is the relationship between this and signals
// that are configured below
std::set_terminate(&terminate_handler);
// logger init
int main(void)
{
// logging init
#ifdef SYNC_LOGGER
logging::init_sync();
logging::init_sync();
#else
logging::init_async();
logging::init_async();
#endif
logging::log->pipe(std::make_unique<Stdout>());
logging::log->pipe(std::make_unique<Stdout>());
// get Main logger
logger = logging::log->logger("Main");
logger.info("{}", logging::log->type());
// logger init
logger = logging::log->logger("Main");
logger.info("{}", logging::log->type());
SignalHandler::register_handler(Signal::SegmentationFault, []() {
throw_and_stacktace("SegmentationFault signal raised");
exit(1);
});
// unhandled exception handler
std::set_terminate(&terminate_handler);
SignalHandler::register_handler(Signal::Terminate, []() {
throw_and_stacktace("Terminate signal raised");
exit(1);
});
// signal handling
SignalHandler::register_handler(Signal::SegmentationFault, []() {
log_stacktrace("SegmentationFault signal raised");
std::exit(EXIT_FAILURE);
});
SignalHandler::register_handler(Signal::Terminate, []() {
log_stacktrace("Terminate signal raised");
std::exit(EXIT_FAILURE);
});
SignalHandler::register_handler(Signal::Abort, []() {
log_stacktrace("Abort signal raised");
std::exit(EXIT_FAILURE);
});
SignalHandler::register_handler(Signal::Abort, []() {
throw_and_stacktace("Abort signal raised");
exit(1);
});
// initialize socket
io::Socket socket;
try
{
socket = io::Socket::bind(interface, port);
}
catch (io::NetworkError e)
{
logger.error("Cannot bind to socket on {} at {}", interface, port);
logger.error("{}", e.what());
std::exit(EXIT_FAILURE);
}
socket.set_non_blocking();
socket.listen(1024);
logger.info("Listening on {} at {}", interface, port);
io::Socket socket;
// initialize server
bolt::Server<bolt::Worker> server(std::move(socket));
serverptr = &server;
try {
socket = io::Socket::bind(interface, port);
} catch (io::NetworkError e) {
logger.error("Cannot bind to socket on {} at {}", interface, port);
logger.error("{}", e.what());
// server start with N threads
// TODO: N should be configurable
auto N = std::thread::hardware_concurrency();
logger.info("Starting {} workers", N);
server.start(N);
std::exit(EXIT_FAILURE);
}
socket.set_non_blocking();
socket.listen(1024);
logger.info("Listening on {} at {}", interface, port);
bolt::Server<bolt::Worker> server(std::move(socket));
serverptr = &server;
// TODO: N should be configurable
auto N = std::thread::hardware_concurrency();
logger.info("Starting {} workers", N);
server.start(N);
logger.info("Shutting down...");
return EXIT_SUCCESS;
logger.info("Shutting down...");
return EXIT_SUCCESS;
}

View File

@ -2,6 +2,7 @@
#include <cassert>
#include "utils/assert.hpp"
#include "storage/vertex_record.hpp"
#include "storage/edge_type/edge_type.hpp"
@ -10,10 +11,12 @@ void EdgeAccessor::remove() const
RecordAccessor::remove();
auto from_va = from();
assert(from_va.fill());
auto from_va_is_full = from_va.fill();
runtime_assert(from_va_is_full, "From Vertex Accessor is empty");
auto to_va = to();
assert(to_va.fill());
auto to_va_is_full = to_va.fill();
permanent_assert(to_va_is_full, "To Vertex Accessor is empty");
from_va.update().record->data.out.remove(vlist);
to_va.update().record->data.in.remove(vlist);

View File

@ -1,19 +1,24 @@
#include "_hardcoded_query/basic.hpp"
#include "logging/default.hpp"
#include "logging/streams/stdout.hpp"
#include "query/preprocesor.hpp"
#include "query/strip/stripper.hpp"
#include "utils/assert.hpp"
#include "utils/sysinfo/memory.hpp"
template <class S, class Q>
void run(size_t n, std::string &query, S &stripper, Q &qf)
QueryPreprocessor preprocessor;
template <class Q>
void run(size_t n, std::string &query, Q &qf)
{
auto stripped = stripper.strip(query);
std::cout << "Running query [" << stripped.hash << "] for " << n << " time."
<< std::endl;
auto stripped = preprocessor.preprocess(query);
logging::info("Running query [{}] x {}.", stripped.hash, n);
for (int i = 0; i < n; i++)
{
properties_t vec = stripped.arguments;
assert(qf[stripped.hash](std::move(vec)));
permanent_assert(qf[stripped.hash](std::move(vec)), "Query failed!");
}
}
@ -29,13 +34,10 @@ int main(void)
logging::init_async();
logging::log->pipe(std::make_unique<Stdout>());
size_t entities_number = 1000;
Db db("cleaning");
auto query_functions = hardcode::load_basic_functions(db);
auto stripper = make_query_stripper(TK_LONG, TK_FLOAT, TK_STR, TK_BOOL);
size_t entities_number = 1000;
auto query_functions = hardcode::load_basic_functions(db);
std::string create_vertex_label =
"CREATE (n:LABEL {name: \"cleaner_test\"}) RETURN n";
@ -49,17 +51,21 @@ int main(void)
// clean vertices
// delete vertices a
// clean vertices
run(entities_number, create_vertex_label, stripper, query_functions);
assert(db.graph.vertices.access().size() == entities_number);
run(entities_number, create_vertex_label, query_functions);
permanent_assert(db.graph.vertices.access().size() == entities_number,
"Entities number doesn't match");
clean_vertex(db);
assert(db.graph.vertices.access().size() == entities_number);
permanent_assert(db.graph.vertices.access().size() == entities_number,
"Entities number doesn't match (after cleaning)");
run(1, delete_label_vertices, stripper, query_functions);
assert(db.graph.vertices.access().size() == entities_number);
run(1, delete_label_vertices, query_functions);
permanent_assert(db.graph.vertices.access().size() == entities_number,
"Entities number doesn't match (delete label vertices)");
clean_vertex(db);
assert(db.graph.vertices.access().size() == 0);
permanent_assert(db.graph.vertices.access().size() == 0,
"Db should be empty");
// ******************************* TEST 2 ********************************//
// add vertices a
@ -68,26 +74,33 @@ int main(void)
// delete vertices a
// clean vertices
// delete vertices all
run(entities_number, create_vertex_label, stripper, query_functions);
assert(db.graph.vertices.access().size() == entities_number);
run(entities_number, create_vertex_label, query_functions);
permanent_assert(db.graph.vertices.access().size() == entities_number,
"Entities number doesn't match");
run(entities_number, create_vertex_other, stripper, query_functions);
assert(db.graph.vertices.access().size() == entities_number * 2);
run(entities_number, create_vertex_other, query_functions);
permanent_assert(db.graph.vertices.access().size() == entities_number * 2,
"Entities number doesn't match");
clean_vertex(db);
assert(db.graph.vertices.access().size() == entities_number * 2);
permanent_assert(db.graph.vertices.access().size() == entities_number * 2,
"Entities number doesn't match");
run(1, delete_label_vertices, stripper, query_functions);
assert(db.graph.vertices.access().size() == entities_number * 2);
run(1, delete_label_vertices, query_functions);
permanent_assert(db.graph.vertices.access().size() == entities_number * 2,
"Entities number doesn't match");
clean_vertex(db);
assert(db.graph.vertices.access().size() == entities_number);
permanent_assert(db.graph.vertices.access().size() == entities_number,
"Entities number doesn't match");
run(1, delete_all_vertices, stripper, query_functions);
assert(db.graph.vertices.access().size() == entities_number);
run(1, delete_all_vertices, query_functions);
permanent_assert(db.graph.vertices.access().size() == entities_number,
"Entities number doesn't match");
clean_vertex(db);
assert(db.graph.vertices.access().size() == 0);
permanent_assert(db.graph.vertices.access().size() == 0,
"Db should be empty");
// TODO: more tests

View File

@ -3,10 +3,16 @@
#include "_hardcoded_query/basic.hpp"
#include "logging/default.hpp"
#include "logging/streams/stdout.hpp"
#include "query/preprocesor.hpp"
#include "query/strip/stripper.hpp"
#include "storage/indexes/indexes.hpp"
#include "utils/assert.hpp"
#include "utils/signals/handler.hpp"
#include "utils/stacktrace/log.hpp"
#include "utils/sysinfo/memory.hpp"
QueryPreprocessor preprocessor;
// Returns uniform random size_t generator from range [0,n>
auto rand_gen(size_t n)
{
@ -17,44 +23,43 @@ auto rand_gen(size_t n)
void run(size_t n, std::string &query, Db &db)
{
auto stripper = make_query_stripper(TK_LONG, TK_FLOAT, TK_STR, TK_BOOL);
auto qf = hardcode::load_basic_functions(db);
auto stripped = preprocessor.preprocess(query);
auto qf = hardcode::load_basic_functions(db);
logging::info("Running query [{}] x {}.", stripped.hash, n);
auto stripped = stripper.strip(query);
std::cout << "Running query [" << stripped.hash << "] for " << n << " time."
<< std::endl;
for (int i = 0; i < n; i++) {
for (int i = 0; i < n; i++)
{
properties_t vec = stripped.arguments;
assert(qf[stripped.hash](std::move(vec)));
auto commited = qf[stripped.hash](std::move(vec));
permanent_assert(commited, "Query execution failed");
}
}
void add_edge(size_t n, Db &db)
{
auto stripper = make_query_stripper(TK_LONG, TK_FLOAT, TK_STR, TK_BOOL);
auto qf = hardcode::load_basic_functions(db);
std::string query = "MATCH (n1), (n2) WHERE ID(n1)=0 AND "
"ID(n2)=1 CREATE (n1)<-[r:IS {age: "
"25,weight: 70}]-(n2) RETURN r";
auto stripped = preprocessor.preprocess(query);
auto stripped = stripper.strip(query);
std::cout << "Running query [" << stripped.hash << "] for " << n
<< " time to add edge." << std::endl;
logging::info("Running query [{}] (add edge) x {}", stripped.hash, n);
std::vector<int64_t> vertices;
for (auto &v : db.graph.vertices.access()) {
for (auto &v : db.graph.vertices.access())
{
vertices.push_back(v.second.id);
}
permanent_assert(vertices.size() > 0, "Vertices size is zero");
auto rand = rand_gen(vertices.size());
for (int i = 0; i < n; i++) {
for (int i = 0; i < n; i++)
{
properties_t vec = stripped.arguments;
vec[0] = Property(Int64(vertices[rand()]), Flags::Int64);
vec[1] = Property(Int64(vertices[rand()]), Flags::Int64);
assert(qf[stripped.hash](std::move(vec)));
vec[0] = Property(Int64(vertices[rand()]), Flags::Int64);
vec[1] = Property(Int64(vertices[rand()]), Flags::Int64);
permanent_assert(qf[stripped.hash](std::move(vec)), "Add edge failed");
}
}
@ -64,7 +69,7 @@ void add_property(Db &db, StoredProperty<TypeGroupVertex> &prop)
t.vertex_access().fill().update().for_all([&](auto va) { va.set(prop); });
assert(t.commit());
permanent_assert(t.commit(), "Add property failed");
}
void add_vertex_property_serial_int(Db &db, PropertyFamily<TypeGroupVertex> &f)
@ -79,7 +84,7 @@ void add_vertex_property_serial_int(Db &db, PropertyFamily<TypeGroupVertex> &f)
i++;
});
assert(t.commit());
permanent_assert(t.commit(), "Add vertex property serial int failed");
}
void add_edge_property_serial_int(Db &db, PropertyFamily<TypeGroupEdge> &f)
@ -94,7 +99,7 @@ void add_edge_property_serial_int(Db &db, PropertyFamily<TypeGroupEdge> &f)
i++;
});
assert(t.commit());
permanent_assert(t.commit(), "Add Edge property serial int failed");
}
template <class TG>
@ -103,8 +108,9 @@ size_t size(Db &db, IndexHolder<TG, std::nullptr_t> &h)
DbAccessor t(db);
size_t count = 0;
auto oin = h.get_read();
if (oin.is_present()) {
auto oin = h.get_read();
if (oin.is_present())
{
oin.get()->for_range(t).for_all([&](auto va) mutable { count++; });
}
@ -115,8 +121,10 @@ size_t size(Db &db, IndexHolder<TG, std::nullptr_t> &h)
void assert_empty(Db &db)
{
assert(db.graph.vertices.access().size() == 0);
assert(db.graph.edges.access().size() == 0);
permanent_assert(db.graph.vertices.access().size() == 0,
"DB isn't empty (vertices)");
permanent_assert(db.graph.edges.access().size() == 0,
"DB isn't empty (edges)");
}
void clean_vertex(Db &db)
@ -136,7 +144,7 @@ void clean_edge(Db &db)
void clear_database(Db &db)
{
std::string delete_all_vertices = "MATCH (n) DELETE n";
std::string delete_all_edges = "MATCH ()-[r]-() DELETE r";
std::string delete_all_edges = "MATCH ()-[r]-() DELETE r";
run(1, delete_all_edges, db);
run(1, delete_all_vertices, db);
@ -151,14 +159,16 @@ bool equal(Db &a, Db &b)
auto acc_a = a.graph.vertices.access();
auto acc_b = b.graph.vertices.access();
if (acc_a.size() != acc_b.size()) {
if (acc_a.size() != acc_b.size())
{
return false;
}
auto it_a = acc_a.begin();
auto it_b = acc_b.begin();
for (auto i = acc_a.size(); i > 0; i--) {
for (auto i = acc_a.size(); i > 0; i--)
{
// TODO: compare
}
}
@ -167,14 +177,16 @@ bool equal(Db &a, Db &b)
auto acc_a = a.graph.edges.access();
auto acc_b = b.graph.edges.access();
if (acc_a.size() != acc_b.size()) {
if (acc_a.size() != acc_b.size())
{
return false;
}
auto it_a = acc_a.begin();
auto it_b = acc_b.begin();
for (auto i = acc_a.size(); i > 0; i--) {
for (auto i = acc_a.size(); i > 0; i--)
{
// TODO: compare
}
}
@ -187,6 +199,16 @@ int main(void)
logging::init_async();
logging::log->pipe(std::make_unique<Stdout>());
SignalHandler::register_handler(Signal::SegmentationFault, []() {
log_stacktrace("SegmentationFault signal raised");
std::exit(EXIT_FAILURE);
});
SignalHandler::register_handler(Signal::BusError, []() {
log_stacktrace("Bus error signal raised");
std::exit(EXIT_FAILURE);
});
size_t cvl_n = 1;
std::string create_vertex_label =
@ -194,7 +216,7 @@ int main(void)
std::string create_vertex_other =
"CREATE (n:OTHER {name: \"cleaner_test\"}) RETURN n";
std::string delete_label_vertices = "MATCH (n:LABEL) DELETE n";
std::string delete_all_vertices = "MATCH (n) DELETE n";
std::string delete_all_vertices = "MATCH (n) DELETE n";
IndexDefinition vertex_property_nonunique_unordered = {
IndexLocation{VertexSide, Option<std::string>("prop"),
@ -215,15 +237,19 @@ int main(void)
// ******************************* TEST 1 ********************************//
{
std::cout << "TEST1" << std::endl;
logging::info("TEST 1");
// add indexes
// add vertices LABEL
// add edges
// add vertices property
// assert index size.
Db db("index", false);
assert(db.indexes().add_index(vertex_property_nonunique_unordered));
assert(db.indexes().add_index(edge_property_nonunique_unordered));
permanent_assert(
db.indexes().add_index(vertex_property_nonunique_unordered),
"Add vertex index failed");
permanent_assert(
db.indexes().add_index(edge_property_nonunique_unordered),
"Add edge index failed");
run(cvl_n, create_vertex_label, db);
auto sp = StoredProperty<TypeGroupVertex>(
@ -232,18 +258,21 @@ int main(void)
.family_key());
add_property(db, sp);
assert(cvl_n ==
size(db, db.graph.vertices.property_family_find_or_create("prop")
.index));
permanent_assert(
cvl_n == size(db, db.graph.vertices
.property_family_find_or_create("prop")
.index),
"Create vertex property failed");
add_edge(cvl_n, db);
add_edge_property_serial_int(
db, db.graph.edges.property_family_find_or_create("prop"));
assert(
permanent_assert(
cvl_n ==
size(db,
db.graph.edges.property_family_find_or_create("prop").index));
size(db, db.graph.edges.property_family_find_or_create("prop")
.index),
"Create edge property failed");
}
// TODO: more tests

View File

@ -1,12 +1,18 @@
#include <random>
#include "_hardcoded_query/basic.hpp"
#include "logging/default.hpp"
#include "logging/streams/stdout.hpp"
#include "_hardcoded_query/basic.hpp"
#include "query/preprocesor.hpp"
#include "query/strip/stripper.hpp"
#include "storage/indexes/indexes.hpp"
#include "utils/assert.hpp"
#include "utils/signals/handler.hpp"
#include "utils/stacktrace/log.hpp"
#include "utils/sysinfo/memory.hpp"
QueryPreprocessor preprocessor;
// Returns uniform random size_t generator from range [0,n>
auto rand_gen(size_t n)
{
@ -17,32 +23,28 @@ auto rand_gen(size_t n)
void run(size_t n, std::string &query, Db &db)
{
auto stripper = make_query_stripper(TK_LONG, TK_FLOAT, TK_STR, TK_BOOL);
auto qf = hardcode::load_basic_functions(db);
auto stripped = preprocessor.preprocess(query);
auto qf = hardcode::load_basic_functions(db);
logging::info("Running query {} [{}] x {}.", query, stripped.hash, n);
auto stripped = stripper.strip(query);
std::cout << "Running query [" << stripped.hash << "] for " << n << " time."
<< std::endl;
for (int i = 0; i < n; i++)
{
properties_t vec = stripped.arguments;
assert(qf[stripped.hash](std::move(vec)));
permanent_assert(qf[stripped.hash](std::move(vec)), "Query aborted");
}
}
void add_edge(size_t n, Db &db)
{
auto stripper = make_query_stripper(TK_LONG, TK_FLOAT, TK_STR, TK_BOOL);
auto qf = hardcode::load_basic_functions(db);
auto qf = hardcode::load_basic_functions(db);
std::string query = "MATCH (n1), (n2) WHERE ID(n1)=0 AND "
"ID(n2)=1 CREATE (n1)<-[r:IS {age: "
"25,weight: 70}]-(n2) RETURN r";
auto stripped = preprocessor.preprocess(query);
auto stripped = stripper.strip(query);
std::cout << "Running query [" << stripped.hash << "] for " << n
<< " time to add edge." << std::endl;
logging::info("Running query {} [{}] x {}.", query, stripped.hash, n);
std::vector<int64_t> vertices;
for (auto &v : db.graph.vertices.access())
@ -56,7 +58,7 @@ void add_edge(size_t n, Db &db)
properties_t vec = stripped.arguments;
vec[0] = Property(Int64(vertices[rand()]), Flags::Int64);
vec[1] = Property(Int64(vertices[rand()]), Flags::Int64);
assert(qf[stripped.hash](std::move(vec)));
permanent_assert(qf[stripped.hash](std::move(vec)), "Query aborted");
}
}
@ -66,7 +68,8 @@ void add_property(Db &db, StoredProperty<TypeGroupVertex> &prop)
t.vertex_access().fill().for_all([&](auto va) { va.set(prop); });
assert(t.commit());
permanent_assert(t.commit(), "add property query aborted");
;
}
void add_property_different_int(Db &db, PropertyFamily<TypeGroupVertex> &f)
@ -81,7 +84,7 @@ void add_property_different_int(Db &db, PropertyFamily<TypeGroupVertex> &f)
i++;
});
assert(t.commit());
permanent_assert(t.commit(), "add property different int aborted");
}
size_t size(Db &db, IndexHolder<TypeGroupVertex, std::nullptr_t> &h)
@ -102,8 +105,8 @@ size_t size(Db &db, IndexHolder<TypeGroupVertex, std::nullptr_t> &h)
void assert_empty(Db &db)
{
assert(db.graph.vertices.access().size() == 0);
assert(db.graph.edges.access().size() == 0);
permanent_assert(db.graph.vertices.access().size() == 0, "Db isn't empty");
permanent_assert(db.graph.edges.access().size() == 0, "Db isn't empty");
}
void clean_vertex(Db &db)
@ -178,6 +181,11 @@ int main(void)
logging::init_async();
logging::log->pipe(std::make_unique<Stdout>());
SignalHandler::register_handler(Signal::SegmentationFault, []() {
log_stacktrace("SegmentationFault signal raised");
std::exit(EXIT_FAILURE);
});
size_t cvl_n = 1000;
std::string create_vertex_label =
@ -187,9 +195,8 @@ int main(void)
std::string delete_label_vertices = "MATCH (n:LABEL) DELETE n";
std::string delete_all_vertices = "MATCH (n) DELETE n";
// ******************************* TEST 1 ********************************//
{
std::cout << "TEST1" << std::endl;
logging::info("TEST 1");
// make snapshot of empty db
// add vertexs
// add edges
@ -203,11 +210,11 @@ int main(void)
clear_database(db);
db.snap_engine.import();
assert_empty(db);
logging::info("END of TEST 1");
}
// ******************************* TEST 2 ********************************//
{
std::cout << "TEST2" << std::endl;
logging::info("TEST 2");
// add vertexs
// add edges
// make snapshot of db
@ -223,13 +230,12 @@ int main(void)
db.snap_engine.import();
{
Db db2("snapshot");
assert(equal(db, db2));
permanent_assert(equal(db, db2), "Dbs aren't equal");
}
}
// ******************************* TEST 3 ********************************//
{
std::cout << "TEST3" << std::endl;
logging::info("TEST 3");
// add vertexs
// add edges
// make snapshot of db
@ -240,13 +246,12 @@ int main(void)
db.snap_engine.make_snapshot();
{
Db db2("not_snapshot");
assert(!equal(db, db2));
permanent_assert(!equal(db, db2), "Dbs are equal");
}
}
// ******************************* TEST 4 ********************************//
{
std::cout << "TEST4" << std::endl;
logging::info("TEST 4");
// add vertices LABEL
// add properties
// add vertices LABEL
@ -265,14 +270,17 @@ int main(void)
IndexLocation{VertexSide, Option<std::string>("prop"),
Option<std::string>(), Option<std::string>()},
IndexType{false, None}};
assert(db.indexes().add_index(idef));
assert(cvl_n == size(db, family.index));
permanent_assert(db.indexes().add_index(idef), "Index isn't added");
permanent_assert(cvl_n == size(db, family.index),
"Index size isn't valid");
db.snap_engine.make_snapshot();
{
Db db2("snapshot");
assert(cvl_n == size(db, db2.graph.vertices
.property_family_find_or_create("prop")
.index));
permanent_assert(
cvl_n == size(db, db2.graph.vertices
.property_family_find_or_create("prop")
.index),
"Index size isn't valid");
}
}

View File

@ -6,14 +6,15 @@
#include <utility>
#include "utils/signals/handler.hpp"
#include "utils/stacktrace.hpp"
#include "utils/stacktrace/stacktrace.hpp"
TEST_CASE("SignalHandler Segmentation Fault Test") {
SignalHandler::register_handler(Signal::SegmentationFault, []() {
std::cout << "Segmentation Fault" << std::endl;
Stacktrace stacktrace;
std::cout << stacktrace.dump() << std::endl;
});
TEST_CASE("SignalHandler Segmentation Fault Test")
{
SignalHandler::register_handler(Signal::SegmentationFault, []() {
std::cout << "Segmentation Fault" << std::endl;
Stacktrace stacktrace;
std::cout << stacktrace.dump() << std::endl;
});
std::raise(SIGSEGV);
std::raise(SIGSEGV);
}