mirror of
https://github.com/eclipse-openvehicle-api/openvehicle-api.git
synced 2026-07-02 05:35:11 +00:00
32
tests/unit_tests/module_control/CMakeLists.txt
Normal file
32
tests/unit_tests/module_control/CMakeLists.txt
Normal 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)
|
||||
23
tests/unit_tests/module_control/main.cpp
Normal file
23
tests/unit_tests/module_control/main.cpp
Normal 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();
|
||||
}
|
||||
63
tests/unit_tests/module_control/mock.h
Normal file
63
tests/unit_tests/module_control/mock.h
Normal 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
|
||||
198
tests/unit_tests/module_control/module_control_test.cpp
Normal file
198
tests/unit_tests/module_control/module_control_test.cpp
Normal 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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user