From 362bc3ba48abf40529111e6aa6b3404d6d5ea2ab Mon Sep 17 00:00:00 2001
From: Marko Budiselic <mbudiselicbuda@gmail.com>
Date: Mon, 19 Dec 2016 18:32:44 +0100
Subject: [PATCH] Bug fixes: RELEASE MODE - asserts

---
 cmake/copy_includes.cmake                     |   3 +-
 include/utils/assert.hpp                      |   5 +-
 include/utils/exceptions/basic_exception.hpp  |  52 +++-----
 include/utils/signals/handler.hpp             |  52 ++++----
 include/utils/stacktrace/log.hpp              |  11 ++
 include/utils/{ => stacktrace}/stacktrace.hpp |  69 +++++------
 include/utils/terminate_handler.hpp           |  32 +++--
 src/memgraph_bolt.cpp                         | 114 +++++++++---------
 src/storage/edge_accessor.cpp                 |   7 +-
 tests/integration/cleaning.cpp                |  69 ++++++-----
 tests/integration/index.cpp                   | 109 +++++++++++------
 tests/integration/snapshot.cpp                |  72 ++++++-----
 tests/unit/signal_handler.cpp                 |  17 +--
 13 files changed, 338 insertions(+), 274 deletions(-)
 create mode 100644 include/utils/stacktrace/log.hpp
 rename include/utils/{ => stacktrace}/stacktrace.hpp (52%)

diff --git a/cmake/copy_includes.cmake b/cmake/copy_includes.cmake
index 4b0ad5a4b..5508be6cd 100644
--- a/cmake/copy_includes.cmake
+++ b/cmake/copy_includes.cmake
@@ -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)
diff --git a/include/utils/assert.hpp b/include/utils/assert.hpp
index 52c4ee49c..b5fec6070 100644
--- a/include/utils/assert.hpp
+++ b/include/utils/assert.hpp
@@ -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());
 
diff --git a/include/utils/exceptions/basic_exception.hpp b/include/utils/exceptions/basic_exception.hpp
index 32459dcbf..9a30e854b 100644
--- a/include/utils/exceptions/basic_exception.hpp
+++ b/include/utils/exceptions/basic_exception.hpp
@@ -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_;
 };
diff --git a/include/utils/signals/handler.hpp b/include/utils/signals/handler.hpp
index 18d833870..c9328b28d 100644
--- a/include/utils/signals/handler.hpp
+++ b/include/utils/signals/handler.hpp
@@ -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_ = {};
diff --git a/include/utils/stacktrace/log.hpp b/include/utils/stacktrace/log.hpp
new file mode 100644
index 000000000..31f273f4f
--- /dev/null
+++ b/include/utils/stacktrace/log.hpp
@@ -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());
+}
diff --git a/include/utils/stacktrace.hpp b/include/utils/stacktrace/stacktrace.hpp
similarity index 52%
rename from include/utils/stacktrace.hpp
rename to include/utils/stacktrace/stacktrace.hpp
index ce063438a..e33050def 100644
--- a/include/utils/stacktrace.hpp
+++ b/include/utils/stacktrace/stacktrace.hpp
@@ -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};
     }
diff --git a/include/utils/terminate_handler.hpp b/include/utils/terminate_handler.hpp
index 467522e44..c24e1a27f 100644
--- a/include/utils/terminate_handler.hpp
+++ b/include/utils/terminate_handler.hpp
@@ -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); }
diff --git a/src/memgraph_bolt.cpp b/src/memgraph_bolt.cpp
index 1c0585068..7f6498794 100644
--- a/src/memgraph_bolt.cpp
+++ b/src/memgraph_bolt.cpp
@@ -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;
 }
diff --git a/src/storage/edge_accessor.cpp b/src/storage/edge_accessor.cpp
index c8267e91b..3dbded0f7 100644
--- a/src/storage/edge_accessor.cpp
+++ b/src/storage/edge_accessor.cpp
@@ -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);
diff --git a/tests/integration/cleaning.cpp b/tests/integration/cleaning.cpp
index 7bdbb3bf8..1cbfeb45b 100644
--- a/tests/integration/cleaning.cpp
+++ b/tests/integration/cleaning.cpp
@@ -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
 
diff --git a/tests/integration/index.cpp b/tests/integration/index.cpp
index 6afc345b6..762134d58 100644
--- a/tests/integration/index.cpp
+++ b/tests/integration/index.cpp
@@ -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
diff --git a/tests/integration/snapshot.cpp b/tests/integration/snapshot.cpp
index 6c8309e44..2c2157c87 100644
--- a/tests/integration/snapshot.cpp
+++ b/tests/integration/snapshot.cpp
@@ -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");
         }
     }
 
diff --git a/tests/unit/signal_handler.cpp b/tests/unit/signal_handler.cpp
index 12ee95e5a..d61e50e09 100644
--- a/tests/unit/signal_handler.cpp
+++ b/tests/unit/signal_handler.cpp
@@ -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);
 }