Add extracted tools: CitrineOS, OpenOCPP, ShapeShifter

- CitrineOS core extracted (CSMS OCPP 2.0.1)
- OpenOCPP extracted (firmware OCPP 1.6J/2.0.1)
- ShapeShifter library installed (pip install -e)
- ShapeShifter specification extracted
- EVerest extracted

TODO updated with progress
This commit is contained in:
Eric F
2026-06-08 00:38:27 -04:00
parent 468cfeaa50
commit d398a6ced2
7326 changed files with 1177561 additions and 7 deletions

View File

@@ -0,0 +1,30 @@
set(TARGET_NAME ${PROJECT_NAME}_module_error_history_tests)
add_executable(${TARGET_NAME})
target_sources(${TARGET_NAME}
PRIVATE
error_database_sqlite_tests.cpp
../ErrorDatabaseSqlite.cpp
helpers.cpp
)
# target_include_directories(module_error_history_tests
# PRIVATE
# )
target_link_libraries(${TARGET_NAME}
PRIVATE
everest::framework
everest::log
everest::sqlite
SQLite::SQLite3
Catch2::Catch2WithMain
)
if(NOT DISABLE_EDM)
list(APPEND CMAKE_MODULE_PATH ${CPM_PACKAGE_catch2_SOURCE_DIR}/extras)
include(Catch)
catch_discover_tests(${TARGET_NAME})
endif()
add_test(${TARGET_NAME} ${TARGET_NAME})
ev_register_test_target(${TARGET_NAME})

View File

@@ -0,0 +1,288 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright Pionix GmbH and Contributors to EVerest
#include <catch2/catch_all.hpp>
#include "../ErrorDatabaseSqlite.hpp"
#include "helpers.hpp"
SCENARIO("Check ErrorDatabaseSqlite class", "[!throws]") {
GIVEN("An ErrorDatabaseSqlite object") {
const std::string bin_dir = get_bin_dir().string() + "/";
const std::string db_name = get_unique_db_name();
TestDatabase db(bin_dir + "/databases/" + db_name, true);
WHEN("Getting all errors") {
THEN("The database should be empty") {
auto errors = db.get_errors(std::list<Everest::error::ErrorFilter>());
REQUIRE(errors.empty());
}
}
WHEN("Adding an error") {
std::vector<Everest::error::ErrorPtr> test_errors = {std::make_shared<Everest::error::Error>(
"test_type", "test_sub_type", "test_message", "test_description",
ImplementationIdentifier("test_origin_module", "test_origin_implementation"), "everest-test",
Everest::error::Severity::Low, date::utc_clock::now(), Everest::error::UUID(),
Everest::error::State::Active)};
db.add_error(test_errors.at(0));
THEN("The error should be in the database") {
check_expected_errors_in_list(test_errors, db.get_errors(std::list<Everest::error::ErrorFilter>()));
}
}
WHEN("Adding multiple errors") {
std::vector<Everest::error::ErrorPtr> test_errors = {
std::make_shared<Everest::error::Error>(
"test_type_a", "test_sub_type_a", "test_message_a", "test_description_a",
ImplementationIdentifier("test_origin_module_a", "test_origin_implementation_a"), "everest-test",
Everest::error::Severity::High, date::utc_clock::now(), Everest::error::UUID(),
Everest::error::State::ClearedByModule),
std::make_shared<Everest::error::Error>(
"test_type_b", "test_sub_type_b", "test_message_b", "test_description_b",
ImplementationIdentifier("test_origin_module_b", "test_origin_implementation_b"), "everest-test",
Everest::error::Severity::Medium, date::utc_clock::now(), Everest::error::UUID(),
Everest::error::State::ClearedByReboot)};
for (Everest::error::ErrorPtr error : test_errors) {
db.add_error(error);
}
THEN("The errors should be in the database") {
auto errors = db.get_errors(std::list<Everest::error::ErrorFilter>());
check_expected_errors_in_list(test_errors, errors);
}
}
}
GIVEN("12 Errors in a connected ErrorDatabaseSqlite object") {
const std::string bin_dir = get_bin_dir().string() + "/";
const std::string db_name = get_unique_db_name();
TestDatabase db(bin_dir + "/databases/" + db_name, true);
std::vector<Everest::error::ErrorPtr> test_errors = get_test_errors();
for (Everest::error::ErrorPtr error : test_errors) {
db.add_error(error);
}
WHEN("Getting all errors") {
auto errors = db.get_errors(std::list<Everest::error::ErrorFilter>());
THEN("The result should contain all 12 errors") {
check_expected_errors_in_list(test_errors, errors);
}
}
WHEN("Getting all errors with StateFilter") {
auto errors = db.get_errors({Everest::error::ErrorFilter(Everest::error::StateFilter::Active)});
THEN("The result should contain specific errors") {
std::vector<Everest::error::ErrorPtr> expected_errors({test_errors[3], test_errors[4], test_errors[5]});
check_expected_errors_in_list(expected_errors, errors);
}
}
WHEN("Getting all errors with OriginFilter") {
auto errors = db.get_errors({Everest::error::ErrorFilter(
Everest::error::OriginFilter("test_origin_module_a", "test_origin_implementation_a"))});
THEN("The result should contain specific errors") {
std::vector<Everest::error::ErrorPtr> expected_errors(
{test_errors[0], test_errors[2], test_errors[4], test_errors[6], test_errors[8], test_errors[10]});
check_expected_errors_in_list(expected_errors, errors);
}
}
WHEN("Getting all errors with TypeFilter") {
auto errors = db.get_errors({Everest::error::ErrorFilter(Everest::error::TypeFilter("test_type_c"))});
THEN("The result should contain specific errors") {
std::vector<Everest::error::ErrorPtr> expected_errors(
{test_errors[2], test_errors[3], test_errors[4], test_errors[5], test_errors[9], test_errors[10]});
check_expected_errors_in_list(expected_errors, errors);
}
}
WHEN("Getting all errors with SeverityFilter") {
auto errors = db.get_errors({Everest::error::ErrorFilter(Everest::error::SeverityFilter::MEDIUM_GE)});
THEN("The result should contain specific errors") {
std::vector<Everest::error::ErrorPtr> expected_errors({test_errors[4], test_errors[5], test_errors[6],
test_errors[7], test_errors[8], test_errors[9],
test_errors[10], test_errors[11]});
check_expected_errors_in_list(expected_errors, errors);
}
}
WHEN("Getting all errors with TimePeriodFilter") {
auto errors = db.get_errors({Everest::error::ErrorFilter(
Everest::error::TimePeriodFilter{date::utc_clock::now() + std::chrono::minutes(150),
date::utc_clock::now() + std::chrono::minutes(270)})});
THEN("The result should contain specific errors") {
std::vector<Everest::error::ErrorPtr> expected_errors({test_errors[3], test_errors[4]});
check_expected_errors_in_list(expected_errors, errors);
}
}
WHEN("Getting all errors with HandleFilter") {
auto errors =
db.get_errors({Everest::error::ErrorFilter(Everest::error::HandleFilter(test_errors[4]->uuid))});
THEN("The result should contain specific errors") {
std::vector<Everest::error::ErrorPtr> expected_errors({test_errors[4]});
check_expected_errors_in_list(expected_errors, errors);
}
}
WHEN("Getting all errors with multiple filters") {
auto errors = db.get_errors({Everest::error::ErrorFilter(Everest::error::StateFilter::Active),
Everest::error::ErrorFilter(Everest::error::OriginFilter(
"test_origin_module_a", "test_origin_implementation_a"))});
THEN("The result should contain specific errors") {
std::vector<Everest::error::ErrorPtr> expected_errors({test_errors[4]});
check_expected_errors_in_list(expected_errors, errors);
}
}
WHEN("Filtering all errors out") {
auto errors = db.get_errors({
Everest::error::ErrorFilter(Everest::error::StateFilter::ClearedByModule),
Everest::error::ErrorFilter(
Everest::error::OriginFilter("test_origin_module_a", "test_origin_implementation_a")),
Everest::error::ErrorFilter(Everest::error::TypeFilter("test_type_c")),
Everest::error::ErrorFilter(Everest::error::SeverityFilter::HIGH_GE),
});
THEN("The result should contain no errors") {
REQUIRE(errors.empty());
}
}
WHEN("Edit error type") {
std::list<Everest::error::ErrorFilter> filters = {
Everest::error::ErrorFilter(Everest::error::HandleFilter(test_errors[4]->uuid))};
Everest::error::ErrorDatabase::EditErrorFunc edit_func = [](Everest::error::ErrorPtr error) {
error->type = "new_type";
};
REQUIRE(db.get_errors(filters).size() > 0);
db.edit_errors(filters, edit_func);
THEN("The error should be edited") {
auto errors = db.get_errors(filters);
REQUIRE(errors.size() == 1);
REQUIRE(errors.front()->type == "new_type");
}
}
WHEN("Edit error state") {
std::list<Everest::error::ErrorFilter> filters = {
Everest::error::ErrorFilter(Everest::error::HandleFilter(test_errors[4]->uuid))};
Everest::error::ErrorDatabase::EditErrorFunc edit_func = [](Everest::error::ErrorPtr error) {
error->state = Everest::error::State::ClearedByModule;
};
REQUIRE(db.get_errors(filters).size() > 0);
db.edit_errors(filters, edit_func);
THEN("The error should be edited") {
auto errors = db.get_errors(filters);
REQUIRE(errors.size() == 1);
REQUIRE(errors.front()->state == Everest::error::State::ClearedByModule);
}
}
WHEN("Edit error severity") {
std::list<Everest::error::ErrorFilter> filters = {
Everest::error::ErrorFilter(Everest::error::HandleFilter(test_errors[4]->uuid))};
Everest::error::ErrorDatabase::EditErrorFunc edit_func = [](Everest::error::ErrorPtr error) {
error->severity = Everest::error::Severity::High;
};
REQUIRE(db.get_errors(filters).size() > 0);
db.edit_errors(filters, edit_func);
THEN("The error should be edited") {
auto errors = db.get_errors(filters);
REQUIRE(errors.size() == 1);
REQUIRE(errors.front()->severity == Everest::error::Severity::High);
}
}
WHEN("Edit error message") {
std::list<Everest::error::ErrorFilter> filters = {
Everest::error::ErrorFilter(Everest::error::HandleFilter(test_errors[4]->uuid))};
Everest::error::ErrorDatabase::EditErrorFunc edit_func = [](Everest::error::ErrorPtr error) {
error->message = "new_message";
};
REQUIRE(db.get_errors(filters).size() > 0);
db.edit_errors(filters, edit_func);
THEN("The error should be edited") {
auto errors = db.get_errors(filters);
REQUIRE(errors.size() == 1);
REQUIRE(errors.front()->message == "new_message");
}
}
WHEN("Edit error description") {
std::list<Everest::error::ErrorFilter> filters = {
Everest::error::ErrorFilter(Everest::error::HandleFilter(test_errors[4]->uuid))};
Everest::error::ErrorDatabase::EditErrorFunc edit_func = [](Everest::error::ErrorPtr error) {
error->description = "new_description";
};
REQUIRE(db.get_errors(filters).size() > 0);
db.edit_errors(filters, edit_func);
THEN("The error should be edited") {
auto errors = db.get_errors(filters);
REQUIRE(errors.size() == 1);
REQUIRE(errors.front()->description == "new_description");
}
}
WHEN("Edit error origin") {
std::list<Everest::error::ErrorFilter> filters = {
Everest::error::ErrorFilter(Everest::error::HandleFilter(test_errors[4]->uuid))};
Everest::error::ErrorDatabase::EditErrorFunc edit_func = [](Everest::error::ErrorPtr error) {
error->origin = ImplementationIdentifier("new_origin_module", "new_origin_implementation");
};
REQUIRE(db.get_errors(filters).size() > 0);
db.edit_errors(filters, edit_func);
THEN("The error should be edited") {
auto errors = db.get_errors(filters);
REQUIRE(errors.size() == 1);
REQUIRE(errors.front()->origin ==
ImplementationIdentifier("new_origin_module", "new_origin_implementation"));
}
}
WHEN("Edit error timestamp") {
std::list<Everest::error::ErrorFilter> filters = {
Everest::error::ErrorFilter(Everest::error::HandleFilter(test_errors[4]->uuid))};
auto new_timestamp = date::utc_clock::now() + std::chrono::hours(10);
Everest::error::ErrorDatabase::EditErrorFunc edit_func = [&new_timestamp](Everest::error::ErrorPtr error) {
error->timestamp = new_timestamp;
};
REQUIRE(db.get_errors(filters).size() > 0);
db.edit_errors(filters, edit_func);
THEN("The error should be edited") {
auto errors = db.get_errors(filters);
REQUIRE(errors.size() == 1);
REQUIRE(Everest::Date::to_rfc3339(errors.front()->timestamp) ==
Everest::Date::to_rfc3339(new_timestamp));
}
}
WHEN("Edit error uuid") {
Everest::error::UUID new_uuid;
std::list<Everest::error::ErrorFilter> filters = {
Everest::error::ErrorFilter(Everest::error::HandleFilter(test_errors[4]->uuid))};
Everest::error::ErrorDatabase::EditErrorFunc edit_func = [&new_uuid](Everest::error::ErrorPtr error) {
error->uuid = new_uuid;
};
REQUIRE(db.get_errors(filters).size() > 0);
db.edit_errors(filters, edit_func);
THEN("The error should be edited") {
auto errors = db.get_errors(filters);
REQUIRE(errors.size() == 0);
errors = db.get_errors({Everest::error::ErrorFilter(Everest::error::HandleFilter(new_uuid))});
REQUIRE(errors.size() == 1);
}
}
WHEN("Remove error") {
std::list<Everest::error::ErrorFilter> filters = {
Everest::error::ErrorFilter(Everest::error::HandleFilter(test_errors[4]->uuid))};
REQUIRE(db.get_errors(filters).size() > 0);
db.remove_errors(filters);
THEN("The error should be removed") {
auto errors = db.get_errors(filters);
REQUIRE(errors.size() == 0);
}
}
WHEN("Remove multiple errors") {
std::list<Everest::error::ErrorFilter> filters = {
Everest::error::ErrorFilter(Everest::error::StateFilter::Active),
Everest::error::ErrorFilter(
Everest::error::OriginFilter("test_origin_module_c", "test_origin_implementation_c"))};
REQUIRE(db.get_errors(filters).size() > 0);
db.remove_errors(filters);
THEN("The errors should be removed") {
auto errors = db.get_errors(filters);
REQUIRE(errors.size() == 0);
}
}
WHEN("Remove all errors") {
std::list<Everest::error::ErrorFilter> filters = {};
REQUIRE(db.get_errors(filters).size() > 0);
db.remove_errors(filters);
THEN("The errors should be removed") {
auto errors = db.get_errors(filters);
REQUIRE(errors.size() == 0);
}
}
}
}

View File

@@ -0,0 +1,134 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright Pionix GmbH and Contributors to EVerest
#include "helpers.hpp"
#include <catch2/catch_all.hpp>
#include <utils/error.hpp>
fs::path get_bin_dir() {
return fs::canonical("/proc/self/exe").parent_path();
}
std::string get_unique_db_name() {
return "error_database_sqlite_" + Everest::error::UUID().to_string() + ".db";
}
std::vector<Everest::error::ErrorPtr> get_test_errors() {
return {// index 0
std::make_shared<Everest::error::Error>(
"test_type_a", "test_sub_type_a", "test_message_a", "test_description_a",
ImplementationIdentifier("test_origin_module_a", "test_origin_implementation_a"), "everest-test",
Everest::error::Severity::Low, date::utc_clock::now(), Everest::error::UUID(),
Everest::error::State::ClearedByModule),
// index 1
std::make_shared<Everest::error::Error>(
"test_type_b", "test_sub_type_b", "test_message_b", "test_description_b",
ImplementationIdentifier("test_origin_module_b", "test_origin_implementation_b"), "everest-test",
Everest::error::Severity::Low, date::utc_clock::now() + std::chrono::hours(1), Everest::error::UUID(),
Everest::error::State::ClearedByModule),
// index 2
std::make_shared<Everest::error::Error>(
"test_type_c", "test_sub_type_c", "test_message_c", "test_description_c",
ImplementationIdentifier("test_origin_module_a", "test_origin_implementation_a"), "everest-test",
Everest::error::Severity::Low, date::utc_clock::now() + std::chrono::hours(2), Everest::error::UUID(),
Everest::error::State::ClearedByModule),
// index 3
std::make_shared<Everest::error::Error>(
"test_type_c", "test_sub_type_c", "test_message_c", "test_description_c",
ImplementationIdentifier("test_origin_module_c", "test_origin_implementation_c"), "everest-test",
Everest::error::Severity::Low, date::utc_clock::now() + std::chrono::hours(3), Everest::error::UUID(),
Everest::error::State::Active),
// index 4
std::make_shared<Everest::error::Error>(
"test_type_c", "test_sub_type_a", "test_message_c", "test_description_c",
ImplementationIdentifier("test_origin_module_a", "test_origin_implementation_a"), "everest-test",
Everest::error::Severity::Medium, date::utc_clock::now() + std::chrono::hours(4),
Everest::error::UUID(), Everest::error::State::Active),
// index 5
std::make_shared<Everest::error::Error>(
"test_type_c", "test_sub_type_a", "test_message_c", "test_description_c",
ImplementationIdentifier("test_origin_module_c", "test_origin_implementation_c"), "everest-test",
Everest::error::Severity::Medium, date::utc_clock::now() + std::chrono::hours(5),
Everest::error::UUID(), Everest::error::State::Active),
// index 6
std::make_shared<Everest::error::Error>(
"test_type_a", "test_sub_type_a", "test_message_a", "test_description_a",
ImplementationIdentifier("test_origin_module_a", "test_origin_implementation_a"), "everest-test",
Everest::error::Severity::Medium, date::utc_clock::now() + std::chrono::hours(6),
Everest::error::UUID(), Everest::error::State::ClearedByReboot),
// index 7
std::make_shared<Everest::error::Error>(
"test_type_a", "test_sub_type_a", "test_message_a", "test_description_a",
ImplementationIdentifier("test_origin_module_c", "test_origin_implementation_c"), "everest-test",
Everest::error::Severity::Medium, date::utc_clock::now() + std::chrono::hours(7),
Everest::error::UUID(), Everest::error::State::ClearedByReboot),
// index 8
std::make_shared<Everest::error::Error>(
"test_type_a", "test_sub_type_a", "test_message_a", "test_description_a",
ImplementationIdentifier("test_origin_module_a", "test_origin_implementation_a"), "everest-test",
Everest::error::Severity::High, date::utc_clock::now() + std::chrono::hours(8), Everest::error::UUID(),
Everest::error::State::ClearedByReboot),
// index 9
std::make_shared<Everest::error::Error>(
"test_type_c", "test_sub_type_c", "test_message_c", "test_description_c",
ImplementationIdentifier("test_origin_module_c", "test_origin_implementation_c"), "everest-test",
Everest::error::Severity::High, date::utc_clock::now() + std::chrono::hours(9), Everest::error::UUID(),
Everest::error::State::ClearedByReboot),
// index 10
std::make_shared<Everest::error::Error>(
"test_type_c", "test_sub_type_c", "test_message_c", "test_description_c",
ImplementationIdentifier("test_origin_module_a", "test_origin_implementation_a"), "everest-test",
Everest::error::Severity::High, date::utc_clock::now() + std::chrono::hours(10), Everest::error::UUID(),
Everest::error::State::ClearedByReboot),
// index 11
std::make_shared<Everest::error::Error>(
"test_type_b", "test_sub_type_b", "test_message_b", "test_description_b",
ImplementationIdentifier("test_origin_module_c", "test_origin_implementation_c"), "everest-test",
Everest::error::Severity::High, date::utc_clock::now() + std::chrono::hours(11), Everest::error::UUID(),
Everest::error::State::ClearedByReboot)};
}
void check_expected_errors_in_list(const std::vector<Everest::error::ErrorPtr>& expected_errors,
const std::list<Everest::error::ErrorPtr>& errors) {
REQUIRE(expected_errors.size() == errors.size());
for (Everest::error::ErrorPtr exp_err : expected_errors) {
auto result = std::find_if(errors.begin(), errors.end(), [&exp_err](const Everest::error::ErrorPtr& err) {
return exp_err->uuid == err->uuid;
});
REQUIRE(result != errors.end());
REQUIRE((*result)->type == exp_err->type);
REQUIRE((*result)->message == exp_err->message);
REQUIRE((*result)->description == exp_err->description);
REQUIRE((*result)->origin == exp_err->origin);
REQUIRE((*result)->severity == exp_err->severity);
REQUIRE(Everest::Date::to_rfc3339((*result)->timestamp) == Everest::Date::to_rfc3339(exp_err->timestamp));
REQUIRE((*result)->state == exp_err->state);
}
}
TestDatabase::TestDatabase(const fs::path& db_path_, const bool reset_) :
db_path(db_path_), db(std::make_unique<module::ErrorDatabaseSqlite>(db_path_, reset_)) {
}
TestDatabase::~TestDatabase() {
fs::remove(db_path);
}
void TestDatabase::add_error(Everest::error::ErrorPtr error) {
db->add_error(error);
}
std::list<Everest::error::ErrorPtr>
TestDatabase::get_errors(const std::list<Everest::error::ErrorFilter>& filters) const {
return db->get_errors(filters);
}
std::list<Everest::error::ErrorPtr> TestDatabase::edit_errors(const std::list<Everest::error::ErrorFilter>& filters,
Everest::error::ErrorDatabase::EditErrorFunc edit_func) {
return db->edit_errors(filters, edit_func);
}
std::list<Everest::error::ErrorPtr> TestDatabase::remove_errors(const std::list<Everest::error::ErrorFilter>& filters) {
return db->remove_errors(filters);
}

View File

@@ -0,0 +1,60 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright Pionix GmbH and Contributors to EVerest
#ifndef ERROR_HISTORY_TESTS_HELPERS_HPP
#define ERROR_HISTORY_TESTS_HELPERS_HPP
#include "../ErrorDatabaseSqlite.hpp"
#include <filesystem>
#include <list>
#include <utils/error.hpp>
namespace fs = std::filesystem;
///
/// \brief get the path to the binary directory
/// \return the path to the binary directory
///
fs::path get_bin_dir();
///
/// \brief get a unique database name
/// \return a unique database name
///
std::string get_unique_db_name();
///
/// \brief get a vector of test errors
/// \return a vector of test errors
///
std::vector<Everest::error::ErrorPtr> get_test_errors();
///
/// \brief check if the given errors are equal
/// \param expected_errors the expected errors
/// \param errors the errors to check
///
void check_expected_errors_in_list(const std::vector<Everest::error::ErrorPtr>& expected_errors,
const std::list<Everest::error::ErrorPtr>& errors);
///
/// \brief wrapper class for the ErrorDatabaseSqlite class
/// This class is used to test the ErrorDatabaseSqlite class
/// It proxies the ErrorDatabaseSqlite class, but
/// the destructor deletes the database file
///
class TestDatabase {
public:
explicit TestDatabase(const fs::path& db_path_, const bool reset_ = false);
~TestDatabase();
void add_error(Everest::error::ErrorPtr error);
std::list<Everest::error::ErrorPtr> get_errors(const std::list<Everest::error::ErrorFilter>& filters) const;
std::list<Everest::error::ErrorPtr> edit_errors(const std::list<Everest::error::ErrorFilter>& filters,
Everest::error::ErrorDatabase::EditErrorFunc edit_func);
std::list<Everest::error::ErrorPtr> remove_errors(const std::list<Everest::error::ErrorFilter>& filters);
private:
std::unique_ptr<module::ErrorDatabaseSqlite> db;
const fs::path db_path;
};
#endif // ERROR_HISTORY_TESTS_HELPERS_HPP