Precommit (#1)

* first commit

* cleanup
This commit is contained in:
tompzf
2025-11-04 13:28:06 +01:00
committed by GitHub
parent dba45dc636
commit 6ed4b1534e
898 changed files with 256340 additions and 0 deletions

View File

@@ -0,0 +1,32 @@
# Define project (multiple EXEs)
project(ModuleControlTests VERSION 1.0 LANGUAGES CXX)
# ModuleControl test executable
add_executable(UnitTest_ModuleControl
module_control_test.cpp
"mock.h" "main.cpp")
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
target_link_libraries(UnitTest_ModuleControl GTest::GTest ${CMAKE_THREAD_LIBS_INIT} stdc++fs)
if (WIN32)
target_link_libraries(UnitTest_ModuleControl Ws2_32 Winmm Rpcrt4.lib)
else()
target_link_libraries(UnitTest_ModuleControl ${CMAKE_DL_LIBS} rt)
endif()
else()
target_link_libraries(UnitTest_ModuleControl GTest::GTest Rpcrt4.lib)
endif()
# Add the ModuleControl unittest
add_test(NAME UnitTest_ModuleControl COMMAND UnitTest_ModuleControl)
# Execute the test
add_custom_command(TARGET UnitTest_ModuleControl POST_BUILD
COMMAND ${CMAKE_COMMAND} -E env TEST_EXECUTION_MODE=CMake "$<TARGET_FILE:UnitTest_ModuleControl>" --gtest_output=xml:${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/UnitTest_ModuleControl.xml
VERBATIM
)
# Build dependencies
add_dependencies(UnitTest_ModuleControl dependency_sdv_components)
add_dependencies(UnitTest_ModuleControl install_manifest)
add_dependencies(UnitTest_ModuleControl data_dispatch_service)
add_dependencies(UnitTest_ModuleControl core_ps)

View File

@@ -0,0 +1,23 @@
#include <gtest/gtest.h>
#include "../../../global/process_watchdog.h"
#include "mock.h"
#include "../../../sdv_services/core/toml_parser/parser_toml.cpp"
#include "../../../sdv_services/core/toml_parser/lexer_toml.cpp"
#include "../../../sdv_services/core/toml_parser/parser_node_toml.cpp"
#include "../../../sdv_services/core/toml_parser/character_reader_utf_8.cpp"
#include "../../../sdv_services/core/module_control.cpp"
#include "../../../sdv_services/core/module.cpp"
#include "../../../sdv_services/core/app_config.cpp"
#include "../../../sdv_services/core/installation_manifest.cpp"
#if defined(_WIN32) && defined(_UNICODE)
extern "C" int wmain(int argc, wchar_t* argv[])
#else
extern "C" int main(int argc, char* argv[])
#endif
{
CProcessWatchdog watchdog;
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@@ -0,0 +1,63 @@
#ifndef MOCK_H
#define MOCK_H
#define DO_NOT_INCLUDE_IN_UNIT_TEST
#include "../../../sdv_services/core/module_control.h"
#include "../../../sdv_services/core/module.h"
#include "../../../sdv_services/core/sdv_core.h"
#include "../../../global/exec_dir_helper.h"
#include "../../../sdv_services/core/app_config.h"
class CMock
{
public:
CMock() : m_root("root")
{
auto ptrElement = std::make_shared<CNormalTable>("Install");
m_root.AddElement(ptrElement);
auto ptrValue = std::make_shared<CStringNode>("Directory", "install/test");
ptrElement->AddElement(ptrValue);
}
void DestroyModuleObjects(sdv::core::TModuleID) {}
bool IsStandaloneApplication() { return true; }
bool IsEssentialApplication() { return false; }
bool IsMainApplication() { return false; }
bool IsIsolatedApplication() { return false; }
bool IsMaintenanceApplication() { return false; }
bool IsConsoleSilent() { return true; }
bool IsConsoleVerbose() { return false; }
uint32_t GetInstanceID() { return 1234u; }
sdv::app::EAppOperationState GetOperationState() const { return sdv::app::EAppOperationState::running; }
std::filesystem::path GetInstallDir() const { return GetExecDirectory(); }
std::filesystem::path FindInstalledModule(const std::filesystem::path&) const { return {}; }
std::optional<CInstallManifest::SComponent> FindInstalledComponent(const std::string&) const { return {}; }
std::string FindInstalledModuleManifest(const std::filesystem::path&) { return {}; }
sdv::core::TObjectID CreateObjectFromModule(sdv::core::TModuleID, const sdv::u8string&, const sdv::u8string&, const sdv::u8string&) { return 0; }
sdv::core::TObjectID CreateObject2(const sdv::u8string&, const sdv::u8string&, const sdv::u8string&) { return 0; }
std::string SaveConfig() { return {}; }
void ResetConfigBaseline() {}
sdv::core::TModuleID Load(const sdv::u8string&) { return 0; }
sdv::core::TModuleID ContextLoad(const std::filesystem::path&, const sdv::u8string&) { return 0; }
bool ContextUnload(sdv::core::TModuleID, bool) { return false; }
CNormalTable m_root;
bool m_bIsMain = false;
bool m_bIsIsolated = false;
};
inline CMock& GetMock()
{
static CMock mock;
return mock;
}
#define CRepository CMock
#define CAppControl CMock
#define GetRepository GetMock
#define GetAppControl GetMock
#define GetAppConfig GetMock
#define GetModuleControl GetMock
inline std::filesystem::path GetCoreDirectory() { return "../../bin"; }
#endif // !defined MOCK_H

View File

@@ -0,0 +1,198 @@
#include <gtest/gtest.h>
#include "mock.h"
#include "../../../global/exec_dir_helper.h"
#include "../../../global/tracefifo/trace_fifo.cpp"
TEST(ModuleControlTest, OpenInvalidFileName)
{
CModuleControl control;
EXPECT_EQ(0, control.Load((GetExecDirectory() / "foobar42.sdv").generic_u8string().c_str()));
}
TEST(ModuleControlTest, OpenNullptrFileName)
{
CModuleControl control;
EXPECT_EQ(0, control.Load(nullptr));
}
TEST(ModuleControlTest, OpenNotAPathFileName)
{
CModuleControl control;
EXPECT_EQ(0, control.Load("ads<EFBFBD>pwb<EFBFBD>g<EFBFBD>a"));
}
TEST(ModuleControlTest, AddResourceModulePathAbsolut)
{
CModuleControl control;
EXPECT_TRUE(control.AddModuleSearchDir((GetExecDirectory() / "../../bin").generic_u8string().c_str()));
EXPECT_FALSE(control.AddModuleSearchDir((GetExecDirectory() / "../../something").generic_u8string().c_str()));
}
TEST(ModuleControlTest, AddResourceModulePathRelative)
{
CModuleControl control;
EXPECT_TRUE(control.AddModuleSearchDir("../bin"));
EXPECT_FALSE(control.AddModuleSearchDir("../soemething"));
}
TEST(ModuleControlTest, AddResourceModulePathRelativeAndLoadModule)
{
// Create a test subdirectory
try
{
std::filesystem::remove_all(GetExecDirectory() / "unittest_module_control_rel");
std::filesystem::create_directories(GetExecDirectory() / "unittest_module_control_rel");
std::filesystem::copy_file(GetExecDirectory() / "../../bin/data_dispatch_service.sdv",
GetExecDirectory() / "unittest_module_control_rel" / "test_rel.sdv");
} catch (const std::filesystem::filesystem_error&)
{}
CModuleControl control;
EXPECT_EQ(0, control.Load("test_rel.sdv"));
EXPECT_TRUE(control.AddModuleSearchDir("unittest_module_control_rel"));
sdv::core::TModuleID tModuleID = control.Load("test_rel.sdv");
EXPECT_NE(tModuleID, 0u);
EXPECT_NE(control.GetModule(tModuleID), nullptr);
EXPECT_TRUE(control.Unload(tModuleID));
// Clean up...
try
{
std::filesystem::remove_all(GetExecDirectory() / "unittest_module_control_rel");
} catch (const std::filesystem::filesystem_error&)
{}
}
TEST(ModuleControlTest, AddResourceModulePathAbsolutAndLoadModule)
{
// Create a test subdirectory
try
{
std::filesystem::remove_all(GetExecDirectory() / "unittest_module_control_abs");
std::filesystem::create_directories(GetExecDirectory() / "unittest_module_control_abs");
std::filesystem::copy_file(GetExecDirectory() / "../../bin/data_dispatch_service.sdv",
GetExecDirectory() / "unittest_module_control_abs" / "test_abs.sdv");
} catch (const std::filesystem::filesystem_error&)
{}
CModuleControl control;
EXPECT_EQ(0, control.Load("test.abs.sdv"));
EXPECT_TRUE(control.AddModuleSearchDir((GetExecDirectory() / "unittest_module_control_abs").generic_u8string().c_str()));
sdv::core::TModuleID tModuleID = control.Load("test_abs.sdv");
EXPECT_NE(tModuleID, 0u);
EXPECT_NE(control.GetModule(tModuleID), nullptr);
EXPECT_TRUE(control.Unload(tModuleID));
try
{
std::filesystem::remove_all(GetExecDirectory() / "unittest_module_control_abs");
} catch (const std::filesystem::filesystem_error&)
{}
}
TEST(ModuleControlTest, LoadModuleNoResourcePath)
{
CModuleControl control;
sdv::core::TModuleID tModuleID = control.Load((GetExecDirectory() / "../../bin/data_dispatch_service.sdv").generic_u8string().c_str());
EXPECT_NE(tModuleID, 0u);
EXPECT_NE(control.GetModule(tModuleID), nullptr);
EXPECT_TRUE(control.Unload(tModuleID));
}
TEST(ModuleControlTest, HappyPath)
{
//load repository service module
CModuleControl control;
EXPECT_TRUE(control.AddModuleSearchDir("../../bin"));
sdv::core::TModuleID tModuleID = control.Load("data_dispatch_service.sdv");
EXPECT_NE(tModuleID, 0u);
std::shared_ptr<CModuleInst> ptrModule = control.GetModule(tModuleID);
ASSERT_NE(ptrModule, nullptr);
//create an object via factory and verify HasActiveObjects functionality
EXPECT_FALSE(ptrModule->HasActiveObjects());
auto pService = ptrModule->CreateObject("DataDispatchService");
EXPECT_NE(pService, nullptr);
EXPECT_TRUE(ptrModule->HasActiveObjects());
EXPECT_NO_THROW(ptrModule->DestroyObject(pService));
EXPECT_TRUE(control.Unload(tModuleID));
}
TEST(ModuleControlTest, OpenCloseDuplicateModule)
{
CModuleControl control;
EXPECT_TRUE(control.AddModuleSearchDir("../../bin"));
sdv::core::TModuleID tModuleID_1 = control.Load("data_dispatch_service.sdv");
EXPECT_NE(0, tModuleID_1);
sdv::core::TModuleID tModuleID_2 = control.Load("data_dispatch_service.sdv");
EXPECT_NE(0, tModuleID_2);
EXPECT_EQ(tModuleID_1, tModuleID_2);
// The decision to unload is based on running objects.
EXPECT_TRUE(control.Unload(tModuleID_1)); // No more running objects; unload successful.
EXPECT_TRUE(control.Unload(tModuleID_2)); // No module any more, unload succeeds since no running objects.
EXPECT_TRUE(control.Unload(tModuleID_1)); // No module any more, unload succeeds since no running objects.
}
TEST(ModuleControlTest, AccessModuleAfterClose)
{
CModuleControl control;
EXPECT_TRUE(control.AddModuleSearchDir("../../bin"));
sdv::core::TModuleID tModuleID = control.Load("data_dispatch_service.sdv");
EXPECT_NE(tModuleID, 0u);
EXPECT_NE(control.GetModule(tModuleID), nullptr);
EXPECT_TRUE(control.Unload(tModuleID));
EXPECT_EQ(control.GetModule(tModuleID), nullptr);
}
TEST(ModuleControlTest, LoadUnloadMultiModule)
{
CModuleControl control;
EXPECT_TRUE(control.AddModuleSearchDir("../../bin"));
//load and unload module
sdv::core::TModuleID tModuleID_1 = control.Load("data_dispatch_service.sdv");
EXPECT_NE(tModuleID_1, 0);
EXPECT_NE(control.GetModule(tModuleID_1), nullptr);
EXPECT_TRUE(control.Unload(tModuleID_1));
EXPECT_EQ(control.GetModule(tModuleID_1), nullptr);
//load same module again
sdv::core::TModuleID tModuleID_2 = control.Load("data_dispatch_service.sdv");
EXPECT_NE(tModuleID_2, 0);
EXPECT_NE(control.GetModule(tModuleID_2), nullptr);
//load another module
sdv::core::TModuleID tModuleID_3 = control.Load("core_ps.sdv");
EXPECT_NE(tModuleID_3, 0);
EXPECT_NE(control.GetModule(tModuleID_3), nullptr);
ASSERT_NE(tModuleID_2, tModuleID_3);
//unload other module - original module should still be loaded properly
EXPECT_TRUE(control.Unload(tModuleID_3));
EXPECT_EQ(control.GetModule(tModuleID_3), nullptr);
EXPECT_NE(control.GetModule(tModuleID_2), nullptr);
//unload remaining module
EXPECT_TRUE(control.Unload(tModuleID_2));
EXPECT_EQ(control.GetModule(tModuleID_2), nullptr);
}