~aleteoryx/muditaos

cd1012669c32e07d01a8d8b75a188130e83363de — RobertPiet 5 years ago 89237cb
[EGD-5118] Settings api tests dependencies updated

Temporary test for ASAN error.
Stub Database introduced to cut the connection SettingsAgent to
sqlite for UT.
Settings ut moved to other directory - new target.
File_indexer UT fixed.
Alarms, Notes and Query UT missing initialization of vfs.
M module-db/tests/AlarmsRecord_tests.cpp => module-db/tests/AlarmsRecord_tests.cpp +1 -0
@@ 24,6 24,7 @@

TEST_CASE("Alarms Record tests")
{
    vfs.Init();
    Database::initialize();

    const auto alarmsPath = purefs::dir::getUserDiskPath() / "alarms.db";

M module-db/tests/AlarmsTable_tests.cpp => module-db/tests/AlarmsTable_tests.cpp +1 -0
@@ 19,6 19,7 @@

TEST_CASE("Alarms Table tests")
{
    vfs.Init();
    Database::initialize();

    const auto alarmsPath = purefs::dir::getUserDiskPath() / "alarms.db";

M module-db/tests/NotesRecord_tests.cpp => module-db/tests/NotesRecord_tests.cpp +2 -0
@@ 1,6 1,7 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "vfs.hpp"
#include <catch2/catch.hpp>

#include <Interface/NotesRecord.hpp>


@@ 15,6 16,7 @@

TEST_CASE("Notes Record tests")
{
    vfs.Init();
    Database::initialize();

    const auto notesDbPath = purefs::dir::getUserDiskPath() / "notes.db";

M module-db/tests/NotesTable_tests.cpp => module-db/tests/NotesTable_tests.cpp +2 -0
@@ 1,6 1,7 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "vfs.hpp"
#include <catch2/catch.hpp>

#include <Tables/NotesTable.hpp>


@@ 10,6 11,7 @@

TEST_CASE("Notes Table tests")
{
    vfs.Init();
    Database::initialize();

    const auto notesDbPath = purefs::dir::getUserDiskPath() / "notes.db";

M module-db/tests/QueryInterface.cpp => module-db/tests/QueryInterface.cpp +1 -0
@@ 37,6 37,7 @@ namespace db

TEST_CASE("Query interface")
{
    vfs.Init();
    Database::initialize();

    auto contactsDB      = std::make_unique<ContactsDB>((purefs::dir::getUserDiskPath() / "contacts.db").c_str());

M module-services/service-db/agents/settings/SettingsAgent.cpp => module-services/service-db/agents/settings/SettingsAgent.cpp +6 -7
@@ 1,4 1,4 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "SettingsAgent.hpp"


@@ 83,7 83,7 @@ auto SettingsAgent::getAgentName() -> const std::string
// dbSingleVar
auto SettingsAgent::dbGetValue(settings::EntryPath path) -> std::optional<std::string>
{
    auto retQuery = database->query(settings::Statements::getValue, path.to_string().c_str());
    auto retQuery = database->query(settings::Statements::getValue, path.variable.c_str());
    if (nullptr == retQuery || 1 != retQuery->getRowCount()) {
        return std::string{};
    }


@@ 174,7 174,7 @@ auto SettingsAgent::dbGetCurrentMode() -> std::string

auto SettingsAgent::dbGetAllModes() -> std::list<std::string>
{
    auto qModes = database->query(settings::Statements::getDictValue, settings::DbPaths::phone_profile);
    auto qModes = database->query(settings::Statements::getDictValue, settings::DbPaths::phone_mode);
    if (nullptr == qModes || 0 == qModes->getRowCount()) {
        return std::list<std::string>{};
    }


@@ 211,7 211,6 @@ auto SettingsAgent::handleSetVariable(sys::Message *req) -> sys::MessagePointer
        auto oldValue = dbGetValue(path);
        if (oldValue.has_value() && oldValue.value() != value) {
            dbSetValue(path, value);
            LOG_DEBUG("[SettingsAgent::handleSetVariable] %s=%s", path.to_string().c_str(), value.c_str());
            for (auto regPath : variableChangeRecipents[path.to_string()]) {
                if (regPath.service != path.service) {
                    auto updateMsg =


@@ 230,9 229,9 @@ auto SettingsAgent::handleRegisterOnVariableChange(sys::Message *req) -> sys::Me
    if (auto msg = dynamic_cast<settings::Messages::RegisterOnVariableChange *>(req)) {
        auto path = msg->getPath();
        if (dbRegisterValueChange(path)) {
            auto it = variableChangeRecipents.find(path.to_string());
            auto it = variableChangeRecipents.find(path.variable);
            if (variableChangeRecipents.end() == it || it->second.end() == it->second.find(path)) {
                variableChangeRecipents[path.to_string()] = {path};
                variableChangeRecipents[path.variable]    = {path.service};
                auto currentValue                         = dbGetValue(path).value_or("");
                auto msgValue = std::make_shared<::settings::Messages::VariableChanged>(path, currentValue, "");
                sys::Bus::SendUnicast(std::move(msgValue), msg->sender, parentService);


@@ 254,7 253,7 @@ auto SettingsAgent::handleUnregisterOnVariableChange(sys::Message *req) -> sys::
    if (auto msg = dynamic_cast<settings::Messages::UnregisterOnVariableChange *>(req)) {
        auto path = msg->getPath();
        if (dbUnregisterValueChange(path)) {
            auto it = variableChangeRecipents.find(path.to_string());
            auto it = variableChangeRecipents.find(path.variable);
            if (variableChangeRecipents.end() != it) {
                it->second.erase(path);
                LOG_DEBUG("[SettingsAgent::handleUnregisterOnVariableChange] %s", path.to_string().c_str());

M module-services/service-db/test/CMakeLists.txt => module-services/service-db/test/CMakeLists.txt +1 -2
@@ 6,7 6,6 @@ add_catch2_executable(
            main.cpp
            test-service-db-api.cpp
            test-service-db-settings-messages.cpp
            #test-service-db-settings-api.cpp
            test-service-db-file_indexer.cpp
        LIBS
            service-audio


@@ 18,4 17,4 @@ add_catch2_executable(
        DEPS
            PurePhone.img-target
)

add_subdirectory(test-settings)

M module-services/service-db/test/test-service-db-file_indexer.cpp => module-services/service-db/test/test-service-db-file_indexer.cpp +6 -0
@@ 40,8 40,12 @@ class ClientService : public sys::Service
    }
};

#include <vfs.hpp>

TEST_CASE("FileIndexer")
{
    vfs.Init();
    Database::initialize();
    std::string serviceName = "file_indexer_client";
    ClientService file_indexer_client_service(serviceName);
    file_indexer_client_service.InitHandler();


@@ 312,4 316,6 @@ TEST_CASE("FileIndexer")
        REQUIRE(fileCountAfterDel == 0);
        std::cout << "DeleteFile /DeleteAllFilesInDir  finished" << std::endl << std::flush;
    }

    Database::deinitialize();
}

A module-services/service-db/test/test-settings/CMakeLists.txt => module-services/service-db/test/test-settings/CMakeLists.txt +17 -0
@@ 0,0 1,17 @@
# service-db tests
add_catch2_executable(
        NAME
            service-db-settings
        SRCS
            main.cpp
            test-service-db-settings-api.cpp
        LIBS
            service-audio
            module-vfs
            module-audio
            service-cellular
            module-cellular
            iosyscalls
        DEPS
            PurePhone.img-target
)

A module-services/service-db/test/test-settings/Database.cpp => module-services/service-db/test/test-settings/Database.cpp +221 -0
@@ 0,0 1,221 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "module-db/Database/Database.hpp"

#include "log/log.hpp"

#include <purefs/filesystem_paths.hpp>
#include <gsl/gsl_util>

#include <cassert>
#include <cstring>
#include <memory>

#include <module-services/service-db/agents/settings/Settings_queries.hpp>

#include <map>
#include <string>

class DatabaseInitializer
{
  public:
    DatabaseInitializer(Database *)
    {}
    virtual ~DatabaseInitializer() = default;
};

std::map<std::string, std::string> variables;
std::string profile = "_startProfileValue";
std::string mode    = "_initialModeValue";
std::set<std::string> profiles, modes;
const std::string system_phone_mode("system/phone_mode");
const std::string system_phone_profile("system/phone_profile");

bool stubExecute(const std::string &format, const std::string &path, const std::string &val)
{
    if (format.empty()) {
        return false;
    }

    if (format == std::string(settings::Statements::insertValue)) {
        LOG_DEBUG("Database::execute set %s = %s", path.c_str(), val.c_str());
        variables[path] = val;
        return true;
    }

    if (format == std::string(settings::Statements::setNotification)) {
        return true;
    }
    if (format == std::string(settings::Statements::clearNotificationdRow)) {
        return true;
    }

    if (format == std::string(settings::Statements::updateValue)) {
        // profile change, mode change
        if (val == system_phone_mode) {
            mode = path;
            return true;
        }
        if (val == system_phone_profile) {
            profile = path;
            return true;
        }
        return false;
    }

    if (format == std::string(settings::Statements::addDictValue)) {
        // add new profile, add new mode
        if (path == system_phone_mode) {
            modes.insert(val);
            return true;
        }
        if (path == system_phone_profile) {
            profiles.insert(val);
            return true;
        }
        return false;
    }

    return false;
}

std::unique_ptr<QueryResult> stubQuery(const std::string &format, const std::string &what)
{
    std::vector<Field> row;
    auto queryResult = std::make_unique<QueryResult>();
    if (std::string(settings::Statements::getValue) == format) {
        if (system_phone_mode == what) // settings::DbPaths::phone_mode
        {
            row.push_back(Field{mode.c_str()});
        }
        else if (system_phone_profile == what) // settings::DbPaths::phone_profile
        {
            row.push_back(Field{profile.c_str()});
        }
        else // variable
        {
            if (variables.end() == variables.find(what)) {
                variables[what] = what + " _initialValue";
            }
            LOG_DEBUG("Database::query for %s returns %s", what.c_str(), variables[what].c_str());
            row.push_back(Field{variables[what].c_str()});
        }
        queryResult->addRow(row);
    }
    else if (std::string(settings::Statements::getDictValue) == format) {
        if (system_phone_mode == what) {
            for (const auto &mode : modes) {
                row.clear();
                row.push_back(Field{mode.c_str()});
                queryResult->addRow(row);
            }
        }
        else if (system_phone_profile == what) {
            for (const auto &profile : profiles) {
                row.clear();
                row.push_back(Field{profile.c_str()});
                queryResult->addRow(row);
            }
        }
        // allProfiles, allModes
    }
    return queryResult;
}

Database::Database(const char *name)
    : dbName(name), queryStatementBuffer{nullptr}, isInitialized_(false),
      initializer(std::make_unique<DatabaseInitializer>(this))
{
    isInitialized_ = true;
}

void Database::initQueryStatementBuffer()
{}

void Database::clearQueryStatementBuffer()
{
    std::memset(queryStatementBuffer, 0, maxQueryLen);
}

Database::~Database()
{}

bool Database::initialize()
{
    return true;
}

bool Database::deinitialize()
{
    return true;
}

bool Database::execute(const char *format, ...)
{
    if (format == nullptr) {
        return false;
    }
    std::string format_str(format);
    if (format_str.find("%") == std::string::npos) {
        return true;
    }
    std::string path, val;
    va_list ap;
    va_start(ap, format);
    format = va_arg(ap, const char *);
    if (format != nullptr) {
        path   = std::string(format);
        format = va_arg(ap, const char *);
        if (format != nullptr) {
            val = std::string(format);
        }
    }
    va_end(ap);
    if (!path.empty() && !val.empty()) {
        return stubExecute(format_str, path, val);
    }
    return true;
}

std::unique_ptr<QueryResult> Database::query(const char *format, ...)
{
    if (format == nullptr) {
        return nullptr;
    }

    std::string format_str(format);
    if (format_str.find("%") == std::string::npos) {
        return nullptr;
    }
    std::string what;
    va_list ap;
    va_start(ap, format);
    format = va_arg(ap, const char *);
    if (format != nullptr) {
        what = std::string(format);
    }
    va_end(ap);
    if (what.empty()) {
        return nullptr;
    }
    return stubQuery(format_str, what);
}

int Database::queryCallback(void *usrPtr, int count, char **data, char **columns)
{
    return 0;
}

uint32_t Database::getLastInsertRowId()
{
    return 1;
}

void Database::pragmaQuery(const std::string &pragmaStatemnt)
{}

bool Database::storeIntoFile(const std::string &backupPath)
{
    return true;
}

A module-services/service-db/test/test-settings/main.cpp => module-services/service-db/test/test-settings/main.cpp +8 -0
@@ 0,0 1,8 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#define CATCH_CONFIG_MAIN
#include <catch2/catch.hpp>
#include <vfs.hpp>

class vfs vfs; // needed for compilation, our vfs is global

R module-services/service-db/test/test-service-db-settings-api.cpp => module-services/service-db/test/test-settings/test-service-db-settings-api.cpp +2 -4
@@ 17,9 17,9 @@
#include "test-service-db-settings-testmsgs.hpp"
#include "test-service-db-settings-testservices.hpp"
#include "test-service-db-settings-testapps.hpp"
#include "Database.cpp"
#include <vfs.hpp>


TEST_CASE("SettingsApi")
{
    vfs.Init();


@@ 33,10 33,10 @@ TEST_CASE("SettingsApi")
        std::shared_ptr<settings::ServiceProfile> profWritter;
        std::shared_ptr<settings::ServiceProfile> profReader;
        std::shared_ptr<settings::AppTestProfileMode> testProf;
        std::shared_ptr<std::mutex> testStart;
        std::shared_ptr<settings::ServiceMode> modeWritter;
        std::shared_ptr<settings::ServiceMode> modeReader;
        std::shared_ptr<settings::AppTestProfileMode> testMode;
        std::shared_ptr<std::mutex> testStart;

        manager->StartSystem([manager,
                              &varWritter,


@@ 120,7 120,6 @@ TEST_CASE("SettingsApi")
        REQUIRE(testProf->v[1] == testProf->v[0] + "1");
        REQUIRE(testProf->v[2] == testProf->v[0] + "12");
        REQUIRE(testProf->v[3] == "other");
        REQUIRE(testProf->v[4] == "other");

        std::cout << "testMode values:" << std::endl << std::flush;
        for (auto s : testMode->v) {


@@ 129,6 128,5 @@ TEST_CASE("SettingsApi")
        REQUIRE(testMode->v[1] == testMode->v[0] + "1");
        REQUIRE(testMode->v[2] == testMode->v[0] + "12");
        REQUIRE(testMode->v[3] == "other");
        REQUIRE(testMode->v[4] == "other");
    }
}

R module-services/service-db/test/test-service-db-settings-testapps.hpp => module-services/service-db/test/test-settings/test-service-db-settings-testapps.hpp +0 -0
R module-services/service-db/test/test-service-db-settings-testmsgs.hpp => module-services/service-db/test/test-settings/test-service-db-settings-testmsgs.hpp +0 -0
R module-services/service-db/test/test-service-db-settings-testservices.hpp => module-services/service-db/test/test-settings/test-service-db-settings-testservices.hpp +0 -0