diff --git a/lib/tests/meson.build b/lib/tests/meson.build index fb7c275a..ab233f25 100644 --- a/lib/tests/meson.build +++ b/lib/tests/meson.build @@ -50,11 +50,11 @@ test('test-parser', install: false, dependencies: [glib_dep, gmime_dep, lib_mu_dep, lib_test_mu_common_dep])) -# test('test-store-query', -# executable('test-store-query', -# 'test-mu-store-query.cc', -# install: false, -# dependencies: [glib_dep, gmime_dep, lib_mu_dep, lib_test_mu_common_dep])) +test('test-store-query', + executable('test-store-query', + 'test-mu-store-query.cc', + install: false, + dependencies: [glib_dep, gmime_dep, lib_mu_dep, lib_test_mu_common_dep])) # # benchmarks # diff --git a/lib/tests/test-mu-store-query.cc b/lib/tests/test-mu-store-query.cc new file mode 100644 index 00000000..2134300c --- /dev/null +++ b/lib/tests/test-mu-store-query.cc @@ -0,0 +1,166 @@ +/* +** Copyright (C) 2022 Dirk-Jan C. Binnema +** +** This program is free software; you can redistribute it and/or modify it +** under the terms of the GNU General Public License as published by the +** Free Software Foundation; either version 3, or (at your option) any +** later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, +** Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +** +*/ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +using namespace Mu; + + +/// map of some (unique) path-tail to the message-text +using TestMap = std::unordered_map; + +static Store +make_test_store(const std::string& test_path, const TestMap& test_map, + const StringVec &personal_addresses) +{ + std::string maildir = test_path + "/Maildir"; + + /* write messages to disk */ + for (auto&& item: test_map) { + + const auto msgpath = maildir + "/" + item.first; + + /* create the directory for the message */ + auto dir = to_string_gchar(g_path_get_dirname(msgpath.c_str())); + if (g_test_verbose()) + g_message("create message dir %s", dir.c_str()); + + g_assert_cmpuint(g_mkdir_with_parents(dir.c_str(), 0700), ==, 0); + + /* write the file */ + std::ofstream stream(msgpath); + stream.write(item.second.data(), item.second.size()); + g_assert_true(stream.good()); + stream.close(); + } + + /* make the store */ + auto store = Store::make_new(test_path, maildir, personal_addresses, {}); + assert_valid_result(store); + + /* index the messages */ + auto res = store->indexer().start({}); + g_assert_true(res); + while(store->indexer().is_running()) { + using namespace std::chrono_literals; + std::this_thread::sleep_for(100ms); + } + g_assert_true(!store->empty()); + g_assert_cmpuint(store->size(),==,test_map.size()); + + /* and we have a fully-ready store */ + return std::move(store.value()); +} + + +static void +test_simple() +{ + + const TestMap test_msgs = {{ + +// "sqlite-msg" "Simple mailing list message. +{ +"basic/cur/sqlite-msg:2,S", +R"(Return-Path: +X-Original-To: xxxx@localhost +Delivered-To: xxxx@localhost +Received: from mindcrime (localhost [127.0.0.1]) + by mail.xxxxsoftware.nl (Postfix) with ESMTP id 32F276963F + for ; Mon, 4 Aug 2008 21:49:34 +0300 (EEST) +Message-Id: <83B5AF40-DBFA-4578-A043-04C80276E195@sqlabs.net> +From: "Foo Example" +To: sqlite-dev@sqlite.org +Cc: "Bank of America" +Mime-Version: 1.0 (Apple Message framework v926) +Date: Mon, 4 Aug 2008 11:40:49 +0200 +X-Mailer: Apple Mail (2.926) +Subject: [sqlite-dev] VM optimization inside sqlite3VdbeExec +Precedence: list +Reply-To: sqlite-dev@sqlite.org +List-Id: +Content-Type: text/plain; charset="us-ascii" +Content-Transfer-Encoding: 7bit +Sender: sqlite-dev-bounces@sqlite.org +Content-Length: 639 + +Inside sqlite3VdbeExec there is a very big switch statement. +In order to increase performance with few modifications to the +original code, why not use this technique ? +http://docs.freebsd.org/info/gcc/gcc.info.Labels_as_Values.html + +With a properly defined "instructions" array, instead of the switch +statement you can use something like: +goto * instructions[pOp->opcode]; +)"}, +}}; + TempDir tdir; + auto store{make_test_store(tdir.path(), test_msgs, {})}; + + // matches + for (auto&& expr: { + "Inside", + "from:foo@example.com", + "from:Foo", + "from:\"Foo Example\"", + "from:/Foo.*Example/", + "recip:\"Bank Of America\"", + "date:2008-08-01..2008-09-01", + "prio:low", + "to:sqlite-dev@sqlite.org", + "list:sqlite-dev.sqlite.org"}) { + + if (g_test_verbose()) + g_message("query: '%s'", expr); + auto qr = store.run_query(expr); + assert_valid_result(qr); + g_assert_false(qr->empty()); + g_assert_cmpuint(qr->size(), ==, 1); + } + + auto qr = store.run_query("statement"); + assert_valid_result(qr); + g_assert_false(qr->empty()); + g_assert_cmpuint(qr->size(), ==, 1); + + assert_equal(qr->begin().subject().value_or(""), + "[sqlite-dev] VM optimization inside sqlite3VdbeExec"); + g_assert_true(qr->begin().references().empty()); + //g_assert_cmpuint(qr->begin().date().value_or(0), ==, 123454); +} + + +int +main(int argc, char* argv[]) +{ + g_test_init(&argc, &argv, NULL); + + g_test_add_func("/store/query/simple", test_simple); + + return g_test_run(); +}