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,143 @@
# Define project
project (UnitTest_SDV_Control VERSION 1.0 LANGUAGES CXX)
# Find the IDL compiler
# REMARKS The compiler can only be found after it has build. Having both the compiler and the unittest project build, causes an
# error during the scanning phase of CMake.
#find_program(SDVIDL NAMES "sdv_idl_compiler" PATHS "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/../../bin/" NO_CACHE)
set (SDVIDL "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/../../bin/sdv_idl_compiler")
message("Use IDL compiler: ${SDVIDL}")
# Compile the IDL
add_custom_command(
OUTPUT ${PROJECT_SOURCE_DIR}/generated/test_component.h
DEPENDS sdv_idl_compiler
MAIN_DEPENDENCY test_component.idl
COMMENT "Build test_component.idl"
COMMAND ${SDVIDL} "${PROJECT_SOURCE_DIR}/test_component.idl" "-I${PROJECT_SOURCE_DIR}/../../../export" "-O${PROJECT_SOURCE_DIR}/generated"
VERBATIM
)
set_source_files_properties(preinstalled_test_service.cpp OBJECT_DEPENDS ${PROJECT_SOURCE_DIR}/generated/test_component.h)
set_source_files_properties(test_component_ps.cpp OBJECT_DEPENDS ${PROJECT_SOURCE_DIR}/generated/test_component.h)
set_source_files_properties(test_component.cpp OBJECT_DEPENDS ${PROJECT_SOURCE_DIR}/generated/test_component.h)
set_source_files_properties(test_app.cpp OBJECT_DEPENDS ${PROJECT_SOURCE_DIR}/generated/test_component.h)
set_source_files_properties(test_basic_service.cpp OBJECT_DEPENDS ${PROJECT_SOURCE_DIR}/generated/test_component.h)
set_source_files_properties(test_complex_service1.cpp OBJECT_DEPENDS ${PROJECT_SOURCE_DIR}/generated/test_component.h)
set_source_files_properties(test_complex_service2.cpp OBJECT_DEPENDS ${PROJECT_SOURCE_DIR}/generated/test_component.h)
set_source_files_properties(test_device.cpp OBJECT_DEPENDS ${PROJECT_SOURCE_DIR}/generated/test_component.h)
set_source_files_properties(test_system_service.cpp OBJECT_DEPENDS ${PROJECT_SOURCE_DIR}/generated/test_component.h)
set_source_files_properties(test_utility1.cpp OBJECT_DEPENDS ${PROJECT_SOURCE_DIR}/generated/test_component.h)
set_source_files_properties(test_utility2.cpp OBJECT_DEPENDS ${PROJECT_SOURCE_DIR}/generated/test_component.h)
# Add the prxy/stub library
add_library(UnitTest_SDV_Control_ps SHARED "test_component_ps.cpp")
set_target_properties(UnitTest_SDV_Control_ps PROPERTIES PREFIX "")
set_target_properties(UnitTest_SDV_Control_ps PROPERTIES SUFFIX ".sdv")
# Build module for test
add_library(UnitTest_SDV_Control_PreInstalled_Service SHARED preinstalled_test_service.cpp)
target_link_libraries(UnitTest_SDV_Control_PreInstalled_Service ${CMAKE_DL_LIBS} GTest::GTest)
set_target_properties(UnitTest_SDV_Control_PreInstalled_Service PROPERTIES PREFIX "")
set_target_properties(UnitTest_SDV_Control_PreInstalled_Service PROPERTIES SUFFIX ".sdv")
# Build module for app test
add_executable(UnitTest_SDV_Control_Test_App test_app.cpp)
target_link_libraries(UnitTest_SDV_Control_Test_App ${CMAKE_DL_LIBS} GTest::GTest)
# Build module for basic service test
add_library(UnitTest_SDV_Control_Test_Basic_Service SHARED test_basic_service.cpp)
target_link_libraries(UnitTest_SDV_Control_Test_Basic_Service ${CMAKE_DL_LIBS} GTest::GTest)
set_target_properties(UnitTest_SDV_Control_Test_Basic_Service PROPERTIES PREFIX "")
set_target_properties(UnitTest_SDV_Control_Test_Basic_Service PROPERTIES SUFFIX ".sdv")
# Build module for complex service #1 test
add_library(UnitTest_SDV_Control_Test_Complex_Service1 SHARED test_complex_service1.cpp)
target_link_libraries(UnitTest_SDV_Control_Test_Complex_Service1 ${CMAKE_DL_LIBS} GTest::GTest)
set_target_properties(UnitTest_SDV_Control_Test_Complex_Service1 PROPERTIES PREFIX "")
set_target_properties(UnitTest_SDV_Control_Test_Complex_Service1 PROPERTIES SUFFIX ".sdv")
# Build module for complex service #2 test
add_library(UnitTest_SDV_Control_Test_Complex_Service2 SHARED test_complex_service2.cpp)
target_link_libraries(UnitTest_SDV_Control_Test_Complex_Service2 ${CMAKE_DL_LIBS} GTest::GTest)
set_target_properties(UnitTest_SDV_Control_Test_Complex_Service2 PROPERTIES PREFIX "")
set_target_properties(UnitTest_SDV_Control_Test_Complex_Service2 PROPERTIES SUFFIX ".sdv")
# Build module for device test
add_library(UnitTest_SDV_Control_Test_Device SHARED test_device.cpp)
target_link_libraries(UnitTest_SDV_Control_Test_Device ${CMAKE_DL_LIBS} GTest::GTest)
set_target_properties(UnitTest_SDV_Control_Test_Device PROPERTIES PREFIX "")
set_target_properties(UnitTest_SDV_Control_Test_Device PROPERTIES SUFFIX ".sdv")
# Build module for system service test
add_library(UnitTest_SDV_Control_Test_System_Service SHARED test_system_service.cpp)
target_link_libraries(UnitTest_SDV_Control_Test_System_Service ${CMAKE_DL_LIBS} GTest::GTest)
set_target_properties(UnitTest_SDV_Control_Test_System_Service PROPERTIES PREFIX "")
set_target_properties(UnitTest_SDV_Control_Test_System_Service PROPERTIES SUFFIX ".sdv")
# Build module for utility #1 test
add_library(UnitTest_SDV_Control_Test_Utility1 SHARED test_utility1.cpp)
target_link_libraries(UnitTest_SDV_Control_Test_Utility1 ${CMAKE_DL_LIBS} GTest::GTest)
set_target_properties(UnitTest_SDV_Control_Test_Utility1 PROPERTIES PREFIX "")
set_target_properties(UnitTest_SDV_Control_Test_Utility1 PROPERTIES SUFFIX ".sdv")
# Build module for utility #2 test
add_library(UnitTest_SDV_Control_Test_Utility2 SHARED test_utility2.cpp)
target_link_libraries(UnitTest_SDV_Control_Test_Utility2 ${CMAKE_DL_LIBS} GTest::GTest)
set_target_properties(UnitTest_SDV_Control_Test_Utility2 PROPERTIES PREFIX "")
set_target_properties(UnitTest_SDV_Control_Test_Utility2 PROPERTIES SUFFIX ".sdv")
# Execute the installation helper utility to create an installation manifest for the core files.
add_custom_target(UnitTest_SDV_Control_install_manifest
# TODO EVE
# COMMAND "$<TARGET_FILE:sdv_packager>" DIRECT_INSTALL ComponentTest_Repository --instance2007 "$<TARGET_FILE:UnitTest_SDV_Control_PreInstalled_Service>" "$<TARGET_FILE:UnitTest_SDV_Control_ps>" "-I$<TARGET_FILE_DIR:UnitTest_SDV_Control_PreInstalled_Service>" --settings --create_configtest.toml --exclude_config_class"TestObject_CreateChain" --exclude_config_class"TestObject_CreateChainLock" --exclude_config_class"TestObject_CreateChainLockThread" --exclude_config_class"TestObject_CreateDuringShutdown" --exclude_config_class"TestObject_IObjectControlFail"
COMMAND "$<TARGET_FILE:sdv_packager>" DIRECT_INSTALL ComponentTest_SDV_Control --instance2007 "$<TARGET_FILE:UnitTest_SDV_Control_PreInstalled_Service>" "$<TARGET_FILE:UnitTest_SDV_Control_ps>" "-I$<TARGET_FILE_DIR:UnitTest_SDV_Control_PreInstalled_Service>" --overwrite --user_config
DEPENDS UnitTest_SDV_Control_PreInstalled_Service UnitTest_SDV_Control_ps
WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
)
# Compile the source code
add_executable(UnitTest_SDV_Control
"main.cpp"
"includes.h"
"startup_shutdown.cpp"
"list_info.cpp" "start_stop_service.cpp" "preinstalled_test_service.cpp" "test_component_ps.cpp" "install_update_uninstall.cpp")
target_link_libraries(UnitTest_SDV_Control ${CMAKE_DL_LIBS} GTest::GTest)
# Add the IDL Compiler unittest
add_test(NAME UnitTest_SDV_Control COMMAND UnitTest_SDV_Control)
# Execute the test
# Currently disabled due to issues causing the application to regularly crash. A bug ticket has been filed for MINGW:
# https://dev.azure.com/SW4ZF/AZP-074_DivDI_SofDCarResearch/_workitems/edit/608132
# and for ARM:
# https://dev.azure.com/SW4ZF/AZP-431_DivDI_Vehicle_API/_workitems/edit/686503
#add_custom_command(TARGET UnitTest_SDV_Control POST_BUILD
# COMMAND ${CMAKE_COMMAND} -E env TEST_EXECUTION_MODE=CMake "$<TARGET_FILE:UnitTest_SDV_Control>" --gtest_output=xml:${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/UnitTest_SDV_Control.xml
# VERBATIM
#)
# Build dependencies
add_dependencies(UnitTest_SDV_Control_PreInstalled_Service install_manifest)
add_dependencies(UnitTest_SDV_Control_PreInstalled_Service dependency_sdv_components)
add_dependencies(UnitTest_SDV_Control dependency_sdv_components)
add_dependencies(UnitTest_SDV_Control_ps dependency_sdv_components)
add_dependencies(UnitTest_SDV_Control UnitTest_SDV_Control_PreInstalled_Service)
add_dependencies(UnitTest_SDV_Control UnitTest_SDV_Control_Test_App)
add_dependencies(UnitTest_SDV_Control UnitTest_SDV_Control_Test_Basic_Service)
add_dependencies(UnitTest_SDV_Control UnitTest_SDV_Control_Test_Complex_Service1)
add_dependencies(UnitTest_SDV_Control UnitTest_SDV_Control_Test_Complex_Service2)
add_dependencies(UnitTest_SDV_Control UnitTest_SDV_Control_Test_Device)
add_dependencies(UnitTest_SDV_Control UnitTest_SDV_Control_Test_System_Service)
add_dependencies(UnitTest_SDV_Control UnitTest_SDV_Control_Test_Utility1)
add_dependencies(UnitTest_SDV_Control UnitTest_SDV_Control_Test_Utility2)
add_dependencies(UnitTest_SDV_Control UnitTest_SDV_Control_ps)
add_dependencies(UnitTest_SDV_Control UnitTest_SDV_Control_install_manifest)
add_dependencies(UnitTest_SDV_Control_Test_App dependency_sdv_components)
add_dependencies(UnitTest_SDV_Control_Test_Basic_Service dependency_sdv_components)
add_dependencies(UnitTest_SDV_Control_Test_Complex_Service1 dependency_sdv_components)
add_dependencies(UnitTest_SDV_Control_Test_Complex_Service2 dependency_sdv_components)
add_dependencies(UnitTest_SDV_Control_Test_Device dependency_sdv_components)
add_dependencies(UnitTest_SDV_Control_Test_System_Service dependency_sdv_components)
add_dependencies(UnitTest_SDV_Control_Test_Utility1 dependency_sdv_components)
add_dependencies(UnitTest_SDV_Control_Test_Utility2 dependency_sdv_components)

View File

@@ -0,0 +1,198 @@
#ifndef INCLUDES_H
#define INCLUDES_H
#include "../../include/gtest_custom.h"
#include <support/sdv_core.h>
#include <support/app_control.h>
#include <support/pssup.h>
#include "../../../global/exec_dir_helper.h"
#include "../../../sdv_executables/sdv_control/startup_shutdown.h"
/**
* @brief App control helper with automated server shutdown
*/
class CAppControlHelper : public sdv::app::CAppControl
{
public:
/**
* @brief Constructor
* @param[in] bAutoStartServer When set, the constructor will start the server and the destructor will shutdown the server.
* @param[in] uiInstanceID The instance ID to use or 0 for the default instance.
*/
CAppControlHelper(bool bAutoStartServer = false, uint32_t uiInstanceID = 0u) : m_bAutoStartServer(bAutoStartServer),
m_uiInstanceID(uiInstanceID)
{
// Initialize system
std::string ssStartup = R"code(
[LogHandler]
ViewFilter = "Fatal"
[Application]
Mode = "Maintenance"
)code";
if (uiInstanceID) ssStartup += "Instance = " + std::to_string(uiInstanceID) + "\n";
Startup(ssStartup);
// Automatically start the server
if (bAutoStartServer)
{
// Startup the server
int iRet = StartupSDVServer(CreateContext("STARTUP"));
m_bServerStarted = iRet == 0 ? true : false;
EXPECT_EQ(iRet, 0);
}
}
/**
* @brief Destructor
*/
~CAppControlHelper()
{
// Automatically shut down the server
if (m_bServerStarted)
{
// Shutdown the server
ShutdownSDVServer(CreateContext("SHUTDOWN"));
}
// Wait shortly to allow the shutdown to take place.
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
// Terminate (in case the shutdown got stuck).
TerminateServerProcess();
// Shutdown
Shutdown();
}
/**
* @brief Terminate a process with the ID.
*/
void TerminateServerProcess(sdv::process::TProcessID tServerProcessID = GetServerProcessID())
{
// Get the process control service and terminate the process
sdv::process::IProcessControl* pProcessControl = sdv::core::GetObject<sdv::process::IProcessControl>("ProcessControlService");
if (tServerProcessID && pProcessControl) pProcessControl->Terminate(tServerProcessID);
}
/**
* @brief Returns whether the server was started automatically.
* @return The server start status.
*/
bool ServerAutoStarted() const
{
return m_bServerStarted;
}
/**
* @brief Create a context structure
* @param[in] rssCommands One or more commands separated by a space.
* @return The context structure.
*/
SContext CreateContext(const std::string& rssCommands) const
{
SContext sContext;
sContext.bSilent = true;
sContext.bServerSilent = true;
sContext.pathInstallDir = "../tests/bin/" + std::to_string(m_uiInstanceID ? m_uiInstanceID : 1000u);
if (m_uiInstanceID)
sContext.uiInstanceID = m_uiInstanceID;
size_t nPos = 0;
while (true)
{
size_t nSeparator = rssCommands.find_first_of(" \f\n\r\t\v", nPos);
sContext.seqCmdLine.push_back(rssCommands.substr(nPos, nSeparator - nPos));
if (nSeparator == std::string::npos) break;
nPos = nSeparator + 1;
}
return sContext;
}
private:
bool m_bAutoStartServer = false; ///< When set, the constructor will start the server and the destructor will
///< shutdown the server.
bool m_bServerStarted = false; ///< When set, the server was started successfully by this class.
uint32_t m_uiInstanceID = 0; ///< The instance ID to use for the connection.
};
/**
* @brief Interpret a table returned by the list command.
* @param[in] rssTable Reference to the string holding the table.
* @return Vector with rows containing a vector each with cells.
*/
inline std::vector<std::vector<std::string>> InterpretTable(const std::string& rssTable)
{
// Read a cell; call until string is empty. Newline detected is set when the last cell on the line or in the table has been
// read.
size_t nPos = 0;
auto fnReadCell = [&nPos, rssTable](bool& rbStartNewLine) -> std::string
{
// Skip whitespace except newline
nPos = rssTable.find_first_not_of(" \f\r\t\v", nPos);
// Check for a newline
if (nPos != std::string::npos && rssTable[nPos] == '\n')
{
rbStartNewLine = true;
nPos++;
// Skip a header bar
if (rbStartNewLine && nPos != rssTable.size() && rssTable[nPos] == '-')
{
nPos = rssTable.find_first_of("\n", nPos);
if (nPos != std::string::npos) nPos++;
}
}
// Skip whitespace
nPos = rssTable.find_first_not_of(" \f\n\r\t\v", nPos);
if (nPos > rssTable.size()) return {};
// Find text
std::string ssCell;
size_t nStart = nPos;
size_t nStop = 0;
while (true)
{
// Find the next whitespace
nPos = rssTable.find_first_of(" \f\n\r\t\v", nPos);
nStop = nPos;
if (nPos == std::string::npos)
break;
// If there at the most one space to the next word, this is considered to belong to the text
if (rssTable[nPos] != ' ') break;
nPos++;
if (nPos == rssTable.size()) break;
if (std::isspace(rssTable[nPos])) break;
}
// Return the cel text
return rssTable.substr(nStart, nStop - nStart);
};
// Run through the table and add rows with cells.
bool bStartNewRow = true;
std::vector<std::vector<std::string>> vecTable;
std::string ssCell;
while (!(ssCell = fnReadCell(bStartNewRow)).empty())
{
// Start a new row?
if (bStartNewRow)
vecTable.resize(vecTable.size() + 1);
bStartNewRow = false;
// Get a reference to the last row
if (vecTable.empty()) break; // Should not happen!
std::vector<std::string>& rvecRow = vecTable.back();
// Insert the cell
rvecRow.push_back(std::move(ssCell));
}
// Return the table
return vecTable;
}
#endif // !defined INCLUDES_H

View File

@@ -0,0 +1,30 @@
#include "includes.h"
#include "../../../sdv_executables/sdv_control/list_elements.h"
/*
* The following tests are needed: (- not implemented; + implemented)
* - install complex service - not running
* - update complex service - not running
* - uninstall complex service - not running
* - install complex service - running after installation
* - update complex service - running, stop, running after installation
* - uninstall complex service - running, stop, uninstall
* - install utility - not running
* - install utility - running
* - update utility - running
* - uninstall utility - not running
* - uninstall utility - running
* - install device - visible after restart
* - uninstall device - visible after restart
* - install basic service - visible after restart
* - uninstall basic service - visible after restart
* - install system service - visible after restart
* - uninstall system service - visible after restart
* - install complex service with dependencies of existing components - install okay, start okay
* - install complex service with dependencies of non-existing components - install okay, start not okay
* - uninstall complex service being dependent on for other complex service - uninstall okay, other component doesn't start
* - uninstall complex service being dependent on for other non-service component (e.g. utility) - uninstall after restart
* - uninstall complex service with modules having other components - uninstall after restart
* - update complex service with modules having other components - update fails
*/

View File

@@ -0,0 +1,50 @@
#include "includes.h"
#include "../../../sdv_executables/sdv_control/list_elements.h"
/*
* The following tests are needed: (- not implemented; + implemented)
* - List modules - normal list
* - List modules - short list
* - List modules - ID list
* - List classes - normal list
* - List classes - short list
* + List components - normal list
* - List components - short list
* - List components - ID list
* - List installations - normal list
* - List installations - short list
* - List installed files for an installation
* - List connections - normal list
* - List connections - short list
* - List connections - ID list
* - List information with additional external app
* - List filter
* - List header suppression
* - List dependencies in modules, classes and components
* - List location in components and connections
*/
TEST(SDV_Control_Test, DISABLED_ListComponents)
{
CAppControlHelper appcontrol(true, 2007);
EXPECT_TRUE(appcontrol.ServerAutoStarted());
std::stringstream sstreamTable;
EXPECT_EQ(ListElements(appcontrol.CreateContext("LIST COMPONENTS"), sstreamTable), 0);
auto vecTable = InterpretTable(sstreamTable.str());
std::cout << sstreamTable.str() << std::endl;
bool bRepositoryFound = false;
bool bComplexHelloServiceFound = false;
for (const auto& rvecRow : vecTable)
{
if (rvecRow.size() < 2) continue;
if (rvecRow[2] == "RepositoryService")
bRepositoryFound = true;
if (rvecRow[2] == "SDVControl_Test_PreInstalled_ComplexService")
bComplexHelloServiceFound = true;
}
EXPECT_TRUE(bRepositoryFound);
EXPECT_TRUE(bComplexHelloServiceFound);
}

View File

@@ -0,0 +1,21 @@
#include "includes.h"
#include "../../../global/process_watchdog.h"
#include "../../../global/cmdlnparser/cmdlnparser.cpp"
#include "../../../sdv_executables/sdv_control/startup_shutdown.cpp"
#include "../../../sdv_executables/sdv_control/list_elements.cpp"
#include "../../../sdv_executables/sdv_control/start_stop_service.cpp"
/**
* @brief Main function
*/
#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,107 @@
#include <gtest/gtest.h>
#include <support/component_impl.h>
#include "generated/test_component.h"
/**
* @brief Basic complex test component #1
*/
class CPreInstalledComplexService : public sdv::CSdvObject, public sdv::IObjectControl, public IHello
{
public:
/**
* @brief Constructor
*/
~CPreInstalledComplexService()
{
EXPECT_EQ(m_eObjectStatus, sdv::EObjectStatus::destruction_pending);
}
// Interface map
BEGIN_SDV_INTERFACE_MAP()
SDV_INTERFACE_ENTRY(sdv::IObjectControl)
SDV_INTERFACE_ENTRY(IHello)
END_SDV_INTERFACE_MAP()
// Object declarations
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::ComplexService)
DECLARE_OBJECT_CLASS_NAME("SDVControl_Test_PreInstalled_ComplexService")
/**
* @brief Initialize method. On success, a subsequent call to GetStatus returns EObjectStatus::running
* @param[in] ssObjectConfig Optional configuration string.
*/
virtual void Initialize([[maybe_unused]] const sdv::u8string& ssObjectConfig)
{
EXPECT_EQ(m_eObjectStatus, sdv::EObjectStatus::initialization_pending);
m_eObjectStatus = sdv::EObjectStatus::initialized;
}
/**
* @brief Gets the current status of the object
* @return EObjectStatus The current status of the object
*/
virtual sdv::EObjectStatus GetStatus() const
{
return m_eObjectStatus;
}
/**
* @brief Set the component operation mode. Overload of sdv::IObjectControl::SetOperationMode.
* @param[in] eMode The operation mode, the component should run in.
*/
void SetOperationMode(sdv::EOperationMode eMode)
{
switch (eMode)
{
case sdv::EOperationMode::configuring:
if (m_eObjectStatus == sdv::EObjectStatus::running || m_eObjectStatus == sdv::EObjectStatus::initialized)
m_eObjectStatus = sdv::EObjectStatus::configuring;
break;
case sdv::EOperationMode::running:
if (m_eObjectStatus == sdv::EObjectStatus::configuring || m_eObjectStatus == sdv::EObjectStatus::initialized)
m_eObjectStatus = sdv::EObjectStatus::running;
break;
default:
break;
}
}
/**
* @brief Shutdown method called before the object is destroyed.
* @attention Implement calls to other SDV objects here as this is no longer considered safe during the destructor of the object!
* After a call to shutdown any threads/callbacks/etc that could call other SDV objects need to have been stopped.
* The SDV object itself is to remain in a state where it can respond to calls to its interfaces as other objects may still call it during the shutdown sequence!
* Any subsequent call to GetStatus should return EObjectStatus::destruction_pending
*/
virtual void Shutdown()
{
EXPECT_TRUE(m_eObjectStatus == sdv::EObjectStatus::running || m_eObjectStatus == sdv::EObjectStatus::initialized ||
m_eObjectStatus == sdv::EObjectStatus::configuring);
if (m_eObjectStatus != sdv::EObjectStatus::running && m_eObjectStatus != sdv::EObjectStatus::initialized
&& m_eObjectStatus != sdv::EObjectStatus::configuring)
std::cout << "Object status = " << static_cast<uint32_t>(m_eObjectStatus) << " (expected initialized=" <<
static_cast<uint32_t>(sdv::EObjectStatus::initialized) << " or configuring=" <<
static_cast<uint32_t>(sdv::EObjectStatus::configuring) << " or running=" <<
static_cast<uint32_t>(sdv::EObjectStatus::running) << ")." << std::endl;
m_eObjectStatus = sdv::EObjectStatus::destruction_pending;
}
/**
* @brief Say hello. Overload of IHello::SayHello.
* @return The greetings string.
*/
virtual sdv::u8string SayHello() const override
{
return "Hello from pre-installed complex service";
}
private:
sdv::EObjectStatus m_eObjectStatus = sdv::EObjectStatus::initialization_pending; ///< Object status
};
DEFINE_SDV_OBJECT(CPreInstalledComplexService)

View File

@@ -0,0 +1,72 @@
#include "includes.h"
#include "../../../sdv_executables/sdv_control/list_elements.h"
#include "../../../sdv_executables/sdv_control/start_stop_service.h"
/*
* The following tests are needed: (- not implemented; + implemented)
* + Start complex service by class and name
* - Start complex service by name
* + Stop complex service by name
* - Start complex service depending on other services
* - Stop complex service depending on other services
* - Stop complex service being dependent on by other services - other services stop as well
* - Stop complex service being dependent on by other component - fails
* - Start complex service depending on non-existing service - fails
* - Start other component - fails
* - Stop other component - fails
*/
/**
* @brief Find the SDVControl_Test_PreInstalled_ComplexService component.
* @param[in] rAppControl Reference to the app control to create a context.
* @return Return whether the service was found or not.
*/
inline bool ComplexServiceFound(const CAppControlHelper& rAppControl)
{
std::stringstream sstreamTable;
if (ListElements(rAppControl.CreateContext("LIST COMPONENTS"), sstreamTable) != 0) return false;
auto vecTable = InterpretTable(sstreamTable.str());
for (const auto& rvecRow : vecTable)
{
if (rvecRow.size() < 2) continue;
if (rvecRow[2] == "SDVControl_Test_PreInstalled_ComplexService")
return true;
}
return false;
}
TEST(SDV_Control_Test, DestroyComplexService)
{
CAppControlHelper appcontrol(true, 2007);
EXPECT_TRUE(appcontrol.ServerAutoStarted());
// Find the SDVControl_Test_PreInstalled_ComplexService component
EXPECT_TRUE(ComplexServiceFound(appcontrol));
// Destroy the object
EXPECT_EQ(StopService(appcontrol.CreateContext("STOP SDVControl_Test_PreInstalled_ComplexService")), 0);
// Find the SDVControl_Test_PreInstalled_ComplexService component
EXPECT_FALSE(ComplexServiceFound(appcontrol));
}
TEST(SDV_Control_Test, RestartComplexService)
{
CAppControlHelper appcontrol(true, 2007);
EXPECT_TRUE(appcontrol.ServerAutoStarted());
// Find the SDVControl_Test_PreInstalled_ComplexService component
EXPECT_TRUE(ComplexServiceFound(appcontrol));
// Destroy the object
EXPECT_EQ(StopService(appcontrol.CreateContext("STOP SDVControl_Test_PreInstalled_ComplexService")), 0);
// Find the SDVControl_Test_PreInstalled_ComplexService component
EXPECT_FALSE(ComplexServiceFound(appcontrol));
// Destroy the object
EXPECT_EQ(StartService(appcontrol.CreateContext("START SDVControl_Test_PreInstalled_ComplexService SDVControl_Test_PreInstalled_ComplexService")), 0);
// Find the SDVControl_Test_PreInstalled_ComplexService component
EXPECT_TRUE(ComplexServiceFound(appcontrol));
}

View File

@@ -0,0 +1,259 @@
#include "includes.h"
#include "../../../sdv_executables/sdv_control/startup_shutdown.h"
/*
* The following tests are needed: (- not implemented; + implemented; o disabled)
* + Startup default instance
* + Startup specific instance
* + Shutdown default instance
* + Shutdown specific instance
* + Shutdown not-running default instance - fails
* + Shutdown not-running specific instance - fails
* o Recurring startup and shutdown default instance
* o Recurring startup and shutdown specific instance
* + Startup already running default instance - fails
* + Startup multiple specific services simultaneously
*/
TEST(SDV_Control_Test, StartupServerDefaultInstance)
{
CAppControlHelper appcontrol;
// Startup the server
SContext sContext;
sContext.bSilent = true;
sContext.bServerSilent = true;
sContext.seqCmdLine = { "STARTUP" };
int iRet = StartupSDVServer(sContext);
EXPECT_EQ(iRet, 0);
}
TEST(SDV_Control_Test, StartupServerSpecificInstance)
{
CAppControlHelper appcontrol;
// Startup the server
SContext sContext;
sContext.bSilent = true;
sContext.uiInstanceID = 1234;
sContext.bServerSilent = true;
sContext.seqCmdLine = { "STARTUP" };
int iRet = StartupSDVServer(sContext);
EXPECT_EQ(iRet, 0);
}
TEST(SDV_Control_Test, StartupShutdownServerDefaultInstance)
{
CAppControlHelper appcontrol;
// Startup the server
SContext sContext;
sContext.bSilent = true;
sContext.bServerSilent = true;
sContext.seqCmdLine ={ "STARTUP" };
int iRet = StartupSDVServer(sContext);
EXPECT_EQ(iRet, 0);
// Shutdown the server
sContext.seqCmdLine = { "SHUTDOWN" };
iRet = ShutdownSDVServer(sContext);
EXPECT_EQ(iRet, 0);
}
TEST(SDV_Control_Test, StartupShutdownServerSpecificInstance)
{
CAppControlHelper appcontrol;
// Startup the server
SContext sContext;
sContext.uiInstanceID = 1234;
sContext.bSilent = true;
sContext.bServerSilent = true;
sContext.seqCmdLine = { "STARTUP"};
int iRet = StartupSDVServer(sContext);
EXPECT_EQ(iRet, 0);
// Shutdown the server
sContext.seqCmdLine = { "SHUTDOWN" };
iRet = ShutdownSDVServer(sContext);
EXPECT_EQ(iRet, 0);
}
TEST(SDV_Control_Test, TryShutdownNonexistantServerDefaultInstance)
{
CAppControlHelper appcontrol;
// Startup the server
SContext sContext;
sContext.bSilent = true;
sContext.bServerSilent = true;
sContext.seqCmdLine = { "SHUTDOWN" };
int iRet = ShutdownSDVServer(sContext);
EXPECT_EQ(iRet, -124);
}
TEST(SDV_Control_Test, TryShutdownNonexistantServerSpecificInstance)
{
CAppControlHelper appcontrol;
// Startup the server
SContext sContext;
sContext.uiInstanceID = 1234;
sContext.bSilent = true;
sContext.bServerSilent = true;
sContext.seqCmdLine = { "SHUTDOWN" };
int iRet = ShutdownSDVServer(sContext);
EXPECT_EQ(iRet, -124);
}
// TODO: SDV_Control test has been disabled due to failing test issues during the build process. Bug report has been filed under:
// https://dev.azure.com/SW4ZF/AZP-074_DivDI_SofDCarResearch/_workitems/edit/608132
TEST(SDV_Control_Test, DISABLED_RecurringStartupShutdownServerDefaultInstance)
{
CAppControlHelper appcontrol;
SContext sContext;
sContext.bSilent = true;
sContext.bServerSilent = true;
sdv::process::TProcessID rgtServerID[3] = {};
for (uint32_t ui = 0; ui < 3; ui++)
{
// Startup the server
sContext.seqCmdLine = { "STARTUP" };
int iRet = StartupSDVServer(sContext);
if (iRet != 0)
std::cout << "Failure on iteration: " << ui << std::endl;
EXPECT_EQ(iRet, 0);
rgtServerID[ui] = GetServerProcessID();
// Shutdown the server
sContext.seqCmdLine = { "SHUTDOWN" };
iRet = ShutdownSDVServer(sContext);
EXPECT_EQ(iRet, 0);
// Wait three seconds before starting the next iteration (allow the server to shut down).
std::this_thread::sleep_for(std::chrono::milliseconds(3000));
}
// Just in case...
for (uint32_t ui = 0; ui < 3; ui++)
appcontrol.TerminateServerProcess(rgtServerID[ui]);
}
// TODO: SDV_Control test has been disabled due to failing test issues during the build process. Bug report has been filed under:
// https://dev.azure.com/SW4ZF/AZP-074_DivDI_SofDCarResearch/_workitems/edit/608132
TEST(SDV_Control_Test, DISABLED_RecurringStartupShutdownServerSpecificInstance)
{
CAppControlHelper appcontrol;
SContext sContext;
sContext.uiInstanceID = 1234;
sContext.bSilent = true;
sContext.bServerSilent = true;
sdv::process::TProcessID rgtServerID[3] = {};
for (uint32_t ui = 0; ui < 3; ui++)
{
// Startup the server
sContext.seqCmdLine = { "STARTUP" };
int iRet = StartupSDVServer(sContext);
EXPECT_EQ(iRet, 0);
rgtServerID[ui] = GetServerProcessID();
// Shutdown the server
sContext.seqCmdLine = { "SHUTDOWN" };
iRet = ShutdownSDVServer(sContext);
EXPECT_EQ(iRet, 0);
// Wait three seconds before starting the next iteration (allow the server to shut down).
std::this_thread::sleep_for(std::chrono::milliseconds(3000));
}
// Just in case...
for (uint32_t ui = 0; ui < 3; ui++)
appcontrol.TerminateServerProcess(rgtServerID[ui]);
}
TEST(SDV_Control_Test, TryStartupShutdownDuplicateServerDefaultInstance)
{
CAppControlHelper appcontrol;
SContext sContext;
sContext.bSilent = true;
sContext.bServerSilent = true;
// Startup the server #0
sContext.seqCmdLine ={ "STARTUP" };
int iRet = StartupSDVServer(sContext);
EXPECT_EQ(iRet, 0);
sdv::process::TProcessID tServerID0 = GetServerProcessID();
// Startup the server #1
iRet = StartupSDVServer(sContext);
EXPECT_EQ(iRet, -822);
sdv::process::TProcessID tServerID1 = GetServerProcessID();
// Shutdown the server #0
sContext.seqCmdLine = { "SHUTDOWN" };
iRet = ShutdownSDVServer(sContext);
EXPECT_EQ(iRet, 0);
// Just in case...
appcontrol.TerminateServerProcess(tServerID0);
appcontrol.TerminateServerProcess(tServerID1);
}
TEST(SDV_Control_Test, StartupShutdownMultipleServerInstances)
{
CAppControlHelper appcontrol;
SContext sContext0;
sContext0.bSilent = true;
sContext0.bServerSilent = true;
SContext sContext1;
sContext1.uiInstanceID = 1234;
sContext1.bSilent = true;
sContext1.bServerSilent = true;
SContext sContext2;
sContext2.uiInstanceID = 5678;
sContext2.bSilent = true;
sContext2.bServerSilent = true;
// Startup the server #0
sContext0.seqCmdLine = { "STARTUP" };
int iRet = StartupSDVServer(sContext0);
EXPECT_EQ(iRet, 0);
sdv::process::TProcessID tServerID0 = GetServerProcessID();
// Startup the server #1
sContext1.seqCmdLine = { "STARTUP" };
iRet = StartupSDVServer(sContext1);
EXPECT_EQ(iRet, 0);
sdv::process::TProcessID tServerID1 = GetServerProcessID();
// Startup the server #2
sContext2.seqCmdLine = { "STARTUP" };
iRet = StartupSDVServer(sContext2);
EXPECT_EQ(iRet, 0);
sdv::process::TProcessID tServerID2 = GetServerProcessID();
// Shutdown the server #0
sContext0.seqCmdLine = { "SHUTDOWN" };
iRet = ShutdownSDVServer(sContext0);
EXPECT_EQ(iRet, 0);
// Shutdown the server #1
sContext1.seqCmdLine = { "SHUTDOWN" };
iRet = ShutdownSDVServer(sContext1);
EXPECT_EQ(iRet, 0);
// Shutdown the server #2
sContext2.seqCmdLine = { "SHUTDOWN" };
iRet = ShutdownSDVServer(sContext2);
EXPECT_EQ(iRet, 0);
// Just in case...
appcontrol.TerminateServerProcess(tServerID0);
appcontrol.TerminateServerProcess(tServerID1);
appcontrol.TerminateServerProcess(tServerID2);
}

View File

@@ -0,0 +1,107 @@
#include <gtest/gtest.h>
#include <support/component_impl.h>
#include "generated/test_component.h"
/**
* @brief Basic service test component
*/
class CTestBasicService : public sdv::CSdvObject, public sdv::IObjectControl, public IHello
{
public:
/**
* @brief Constructor
*/
~CTestBasicService()
{
EXPECT_EQ(m_eObjectStatus, sdv::EObjectStatus::destruction_pending);
}
// Interface map
BEGIN_SDV_INTERFACE_MAP()
SDV_INTERFACE_ENTRY(sdv::IObjectControl)
SDV_INTERFACE_ENTRY(IHello)
END_SDV_INTERFACE_MAP()
// Object declarations
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::BasicService)
DECLARE_OBJECT_CLASS_NAME("SDVControl_Test_BasicService")
/**
* @brief Initialize method. On success, a subsequent call to GetStatus returns EObjectStatus::running
* @param[in] ssObjectConfig Optional configuration string.
*/
virtual void Initialize([[maybe_unused]] const sdv::u8string& ssObjectConfig)
{
EXPECT_EQ(m_eObjectStatus, sdv::EObjectStatus::initialization_pending);
m_eObjectStatus = sdv::EObjectStatus::initialized;
}
/**
* @brief Gets the current status of the object
* @return EObjectStatus The current status of the object
*/
virtual sdv::EObjectStatus GetStatus() const
{
return m_eObjectStatus;
}
/**
* @brief Set the component operation mode. Overload of sdv::IObjectControl::SetOperationMode.
* @param[in] eMode The operation mode, the component should run in.
*/
void SetOperationMode(sdv::EOperationMode eMode)
{
switch (eMode)
{
case sdv::EOperationMode::configuring:
if (m_eObjectStatus == sdv::EObjectStatus::running || m_eObjectStatus == sdv::EObjectStatus::initialized)
m_eObjectStatus = sdv::EObjectStatus::configuring;
break;
case sdv::EOperationMode::running:
if (m_eObjectStatus == sdv::EObjectStatus::configuring || m_eObjectStatus == sdv::EObjectStatus::initialized)
m_eObjectStatus = sdv::EObjectStatus::running;
break;
default:
break;
}
}
/**
* @brief Shutdown method called before the object is destroyed.
* @attention Implement calls to other SDV objects here as this is no longer considered safe during the destructor of the object!
* After a call to shutdown any threads/callbacks/etc that could call other SDV objects need to have been stopped.
* The SDV object itself is to remain in a state where it can respond to calls to its interfaces as other objects may still call it during the shutdown sequence!
* Any subsequent call to GetStatus should return EObjectStatus::destruction_pending
*/
virtual void Shutdown()
{
EXPECT_TRUE(m_eObjectStatus == sdv::EObjectStatus::running || m_eObjectStatus == sdv::EObjectStatus::initialized ||
m_eObjectStatus == sdv::EObjectStatus::configuring);
if (m_eObjectStatus != sdv::EObjectStatus::running && m_eObjectStatus != sdv::EObjectStatus::initialized
&& m_eObjectStatus != sdv::EObjectStatus::configuring)
std::cout << "Object status = " << static_cast<uint32_t>(m_eObjectStatus) << " (expected initialized=" <<
static_cast<uint32_t>(sdv::EObjectStatus::initialized) << " or configuring=" <<
static_cast<uint32_t>(sdv::EObjectStatus::configuring) << " or running=" <<
static_cast<uint32_t>(sdv::EObjectStatus::running) << ")." << std::endl;
m_eObjectStatus = sdv::EObjectStatus::destruction_pending;
}
/**
* @brief Say hello. Overload of IHello::SayHello.
* @return The greetings string.
*/
virtual sdv::u8string SayHello() const override
{
return "Hello from basic service";
}
private:
sdv::EObjectStatus m_eObjectStatus = sdv::EObjectStatus::initialization_pending; ///< Object status
};
DEFINE_SDV_OBJECT(CTestBasicService)

View File

@@ -0,0 +1,107 @@
#include <gtest/gtest.h>
#include <support/component_impl.h>
#include "generated/test_component.h"
/**
* @brief Basic complex test component #1
*/
class CTestComplexService1 : public sdv::CSdvObject, public sdv::IObjectControl, public IHello
{
public:
/**
* @brief Constructor
*/
~CTestComplexService1()
{
EXPECT_EQ(m_eObjectStatus, sdv::EObjectStatus::destruction_pending);
}
// Interface map
BEGIN_SDV_INTERFACE_MAP()
SDV_INTERFACE_ENTRY(sdv::IObjectControl)
SDV_INTERFACE_ENTRY(IHello)
END_SDV_INTERFACE_MAP()
// Object declarations
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::ComplexService)
DECLARE_OBJECT_CLASS_NAME("SDVControl_Test_ComplexService1")
/**
* @brief Initialize method. On success, a subsequent call to GetStatus returns EObjectStatus::running
* @param[in] ssObjectConfig Optional configuration string.
*/
virtual void Initialize([[maybe_unused]] const sdv::u8string& ssObjectConfig)
{
EXPECT_EQ(m_eObjectStatus, sdv::EObjectStatus::initialization_pending);
m_eObjectStatus = sdv::EObjectStatus::initialized;
}
/**
* @brief Gets the current status of the object
* @return EObjectStatus The current status of the object
*/
virtual sdv::EObjectStatus GetStatus() const
{
return m_eObjectStatus;
}
/**
* @brief Set the component operation mode. Overload of sdv::IObjectControl::SetOperationMode.
* @param[in] eMode The operation mode, the component should run in.
*/
void SetOperationMode(sdv::EOperationMode eMode)
{
switch (eMode)
{
case sdv::EOperationMode::configuring:
if (m_eObjectStatus == sdv::EObjectStatus::running || m_eObjectStatus == sdv::EObjectStatus::initialized)
m_eObjectStatus = sdv::EObjectStatus::configuring;
break;
case sdv::EOperationMode::running:
if (m_eObjectStatus == sdv::EObjectStatus::configuring || m_eObjectStatus == sdv::EObjectStatus::initialized)
m_eObjectStatus = sdv::EObjectStatus::running;
break;
default:
break;
}
}
/**
* @brief Shutdown method called before the object is destroyed.
* @attention Implement calls to other SDV objects here as this is no longer considered safe during the destructor of the object!
* After a call to shutdown any threads/callbacks/etc that could call other SDV objects need to have been stopped.
* The SDV object itself is to remain in a state where it can respond to calls to its interfaces as other objects may still call it during the shutdown sequence!
* Any subsequent call to GetStatus should return EObjectStatus::destruction_pending
*/
virtual void Shutdown()
{
EXPECT_TRUE(m_eObjectStatus == sdv::EObjectStatus::running || m_eObjectStatus == sdv::EObjectStatus::initialized ||
m_eObjectStatus == sdv::EObjectStatus::configuring);
if (m_eObjectStatus != sdv::EObjectStatus::running && m_eObjectStatus != sdv::EObjectStatus::initialized
&& m_eObjectStatus != sdv::EObjectStatus::configuring)
std::cout << "Object status = " << static_cast<uint32_t>(m_eObjectStatus) << " (expected initialized=" <<
static_cast<uint32_t>(sdv::EObjectStatus::initialized) << " or configuring=" <<
static_cast<uint32_t>(sdv::EObjectStatus::configuring) << " or running=" <<
static_cast<uint32_t>(sdv::EObjectStatus::running) << ")." << std::endl;
m_eObjectStatus = sdv::EObjectStatus::destruction_pending;
}
/**
* @brief Say hello. Overload of IHello::SayHello.
* @return The greetings string.
*/
virtual sdv::u8string SayHello() const override
{
return "Hello from complex service #1";
}
private:
sdv::EObjectStatus m_eObjectStatus = sdv::EObjectStatus::initialization_pending; ///< Object status
};
DEFINE_SDV_OBJECT(CTestComplexService1)

View File

@@ -0,0 +1,107 @@
#include <gtest/gtest.h>
#include <support/component_impl.h>
#include "generated/test_component.h"
/**
* @brief Complex service test component #2
*/
class CTestComplexService2 : public sdv::CSdvObject, public sdv::IObjectControl, public IHello
{
public:
/**
* @brief Constructor
*/
~CTestComplexService2()
{
EXPECT_EQ(m_eObjectStatus, sdv::EObjectStatus::destruction_pending);
}
// Interface map
BEGIN_SDV_INTERFACE_MAP()
SDV_INTERFACE_ENTRY(sdv::IObjectControl)
SDV_INTERFACE_ENTRY(IHello)
END_SDV_INTERFACE_MAP()
// Object declarations
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::ComplexService)
DECLARE_OBJECT_CLASS_NAME("SDVControl_Test_ComplexService2")
/**
* @brief Initialize method. On success, a subsequent call to GetStatus returns EObjectStatus::running
* @param[in] ssObjectConfig Optional configuration string.
*/
virtual void Initialize([[maybe_unused]] const sdv::u8string& ssObjectConfig)
{
EXPECT_EQ(m_eObjectStatus, sdv::EObjectStatus::initialization_pending);
m_eObjectStatus = sdv::EObjectStatus::initialized;
}
/**
* @brief Gets the current status of the object
* @return EObjectStatus The current status of the object
*/
virtual sdv::EObjectStatus GetStatus() const
{
return m_eObjectStatus;
}
/**
* @brief Set the component operation mode. Overload of sdv::IObjectControl::SetOperationMode.
* @param[in] eMode The operation mode, the component should run in.
*/
void SetOperationMode(sdv::EOperationMode eMode)
{
switch (eMode)
{
case sdv::EOperationMode::configuring:
if (m_eObjectStatus == sdv::EObjectStatus::running || m_eObjectStatus == sdv::EObjectStatus::initialized)
m_eObjectStatus = sdv::EObjectStatus::configuring;
break;
case sdv::EOperationMode::running:
if (m_eObjectStatus == sdv::EObjectStatus::configuring || m_eObjectStatus == sdv::EObjectStatus::initialized)
m_eObjectStatus = sdv::EObjectStatus::running;
break;
default:
break;
}
}
/**
* @brief Shutdown method called before the object is destroyed.
* @attention Implement calls to other SDV objects here as this is no longer considered safe during the destructor of the object!
* After a call to shutdown any threads/callbacks/etc that could call other SDV objects need to have been stopped.
* The SDV object itself is to remain in a state where it can respond to calls to its interfaces as other objects may still call it during the shutdown sequence!
* Any subsequent call to GetStatus should return EObjectStatus::destruction_pending
*/
virtual void Shutdown()
{
EXPECT_TRUE(m_eObjectStatus == sdv::EObjectStatus::running || m_eObjectStatus == sdv::EObjectStatus::initialized ||
m_eObjectStatus == sdv::EObjectStatus::configuring);
if (m_eObjectStatus != sdv::EObjectStatus::running && m_eObjectStatus != sdv::EObjectStatus::initialized
&& m_eObjectStatus != sdv::EObjectStatus::configuring)
std::cout << "Object status = " << static_cast<uint32_t>(m_eObjectStatus) << " (expected initialized=" <<
static_cast<uint32_t>(sdv::EObjectStatus::initialized) << " or configuring=" <<
static_cast<uint32_t>(sdv::EObjectStatus::configuring) << " or running=" <<
static_cast<uint32_t>(sdv::EObjectStatus::running) << ")." << std::endl;
m_eObjectStatus = sdv::EObjectStatus::destruction_pending;
}
/**
* @brief Say hello. Overload of IHello::SayHello.
* @return The greetings string.
*/
virtual sdv::u8string SayHello() const override
{
return "Hello from complex service #2";
}
private:
sdv::EObjectStatus m_eObjectStatus = sdv::EObjectStatus::initialization_pending; ///< Object status
};
DEFINE_SDV_OBJECT(CTestComplexService2)

View File

@@ -0,0 +1,35 @@
#include <interfaces/core.idl>
#include <interfaces/process.idl>
/**
* @brief Example interface
*/
interface ITestLock
{
/**
* @brief Lock Mutex
*/
void Lock();
/**
* @brief Unlock Mutex
*/
void Unlock();
};
/**
* @brief Hello interface
*/
interface IHello
{
/**
* @brief Say hello
* @return The greetings string.
*/
u8string SayHello() const;
/**
* @brief Get the PID of the process the component is running in...
*/
//sdv::process::TProcessID GetPID() const;
};

View File

@@ -0,0 +1 @@
#include "generated/ps/proxystub.cpp"

View File

@@ -0,0 +1,107 @@
#include <gtest/gtest.h>
#include <support/component_impl.h>
#include "generated/test_component.h"
/**
* @brief Device test component
*/
class CTestDevice : public sdv::CSdvObject, public sdv::IObjectControl, public IHello
{
public:
/**
* @brief Constructor
*/
~CTestDevice()
{
EXPECT_EQ(m_eObjectStatus, sdv::EObjectStatus::destruction_pending);
}
// Interface map
BEGIN_SDV_INTERFACE_MAP()
SDV_INTERFACE_ENTRY(sdv::IObjectControl)
SDV_INTERFACE_ENTRY(IHello)
END_SDV_INTERFACE_MAP()
// Object declarations
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::Device)
DECLARE_OBJECT_CLASS_NAME("SDVControl_Test_Device")
/**
* @brief Initialize method. On success, a subsequent call to GetStatus returns EObjectStatus::running
* @param[in] ssObjectConfig Optional configuration string.
*/
virtual void Initialize([[maybe_unused]] const sdv::u8string& ssObjectConfig)
{
EXPECT_EQ(m_eObjectStatus, sdv::EObjectStatus::initialization_pending);
m_eObjectStatus = sdv::EObjectStatus::initialized;
}
/**
* @brief Gets the current status of the object
* @return EObjectStatus The current status of the object
*/
virtual sdv::EObjectStatus GetStatus() const
{
return m_eObjectStatus;
}
/**
* @brief Set the component operation mode. Overload of sdv::IObjectControl::SetOperationMode.
* @param[in] eMode The operation mode, the component should run in.
*/
void SetOperationMode(sdv::EOperationMode eMode)
{
switch (eMode)
{
case sdv::EOperationMode::configuring:
if (m_eObjectStatus == sdv::EObjectStatus::running || m_eObjectStatus == sdv::EObjectStatus::initialized)
m_eObjectStatus = sdv::EObjectStatus::configuring;
break;
case sdv::EOperationMode::running:
if (m_eObjectStatus == sdv::EObjectStatus::configuring || m_eObjectStatus == sdv::EObjectStatus::initialized)
m_eObjectStatus = sdv::EObjectStatus::running;
break;
default:
break;
}
}
/**
* @brief Shutdown method called before the object is destroyed.
* @attention Implement calls to other SDV objects here as this is no longer considered safe during the destructor of the object!
* After a call to shutdown any threads/callbacks/etc that could call other SDV objects need to have been stopped.
* The SDV object itself is to remain in a state where it can respond to calls to its interfaces as other objects may still call it during the shutdown sequence!
* Any subsequent call to GetStatus should return EObjectStatus::destruction_pending
*/
virtual void Shutdown()
{
EXPECT_TRUE(m_eObjectStatus == sdv::EObjectStatus::running || m_eObjectStatus == sdv::EObjectStatus::initialized ||
m_eObjectStatus == sdv::EObjectStatus::configuring);
if (m_eObjectStatus != sdv::EObjectStatus::running && m_eObjectStatus != sdv::EObjectStatus::initialized
&& m_eObjectStatus != sdv::EObjectStatus::configuring)
std::cout << "Object status = " << static_cast<uint32_t>(m_eObjectStatus) << " (expected initialized=" <<
static_cast<uint32_t>(sdv::EObjectStatus::initialized) << " or configuring=" <<
static_cast<uint32_t>(sdv::EObjectStatus::configuring) << " or running=" <<
static_cast<uint32_t>(sdv::EObjectStatus::running) << ")." << std::endl;
m_eObjectStatus = sdv::EObjectStatus::destruction_pending;
}
/**
* @brief Say hello. Overload of IHello::SayHello.
* @return The greetings string.
*/
virtual sdv::u8string SayHello() const override
{
return "Hello from device";
}
private:
sdv::EObjectStatus m_eObjectStatus = sdv::EObjectStatus::initialization_pending; ///< Object status
};
DEFINE_SDV_OBJECT(CTestDevice)

View File

@@ -0,0 +1,107 @@
#include <gtest/gtest.h>
#include <support/component_impl.h>
#include "generated/test_component.h"
/**
* @brief System service test component
*/
class CTestSystemService : public sdv::CSdvObject, public sdv::IObjectControl, public IHello
{
public:
/**
* @brief Constructor
*/
~CTestSystemService()
{
EXPECT_EQ(m_eObjectStatus, sdv::EObjectStatus::destruction_pending);
}
// Interface map
BEGIN_SDV_INTERFACE_MAP()
SDV_INTERFACE_ENTRY(sdv::IObjectControl)
SDV_INTERFACE_ENTRY(IHello)
END_SDV_INTERFACE_MAP()
// Object declarations
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::SystemObject)
DECLARE_OBJECT_CLASS_NAME("SDVControl_Test_SystemService")
/**
* @brief Initialize method. On success, a subsequent call to GetStatus returns EObjectStatus::running
* @param[in] ssObjectConfig Optional configuration string.
*/
virtual void Initialize([[maybe_unused]] const sdv::u8string& ssObjectConfig)
{
EXPECT_EQ(m_eObjectStatus, sdv::EObjectStatus::initialization_pending);
m_eObjectStatus = sdv::EObjectStatus::initialized;
}
/**
* @brief Gets the current status of the object
* @return EObjectStatus The current status of the object
*/
virtual sdv::EObjectStatus GetStatus() const
{
return m_eObjectStatus;
}
/**
* @brief Set the component operation mode. Overload of sdv::IObjectControl::SetOperationMode.
* @param[in] eMode The operation mode, the component should run in.
*/
void SetOperationMode(sdv::EOperationMode eMode)
{
switch (eMode)
{
case sdv::EOperationMode::configuring:
if (m_eObjectStatus == sdv::EObjectStatus::running || m_eObjectStatus == sdv::EObjectStatus::initialized)
m_eObjectStatus = sdv::EObjectStatus::configuring;
break;
case sdv::EOperationMode::running:
if (m_eObjectStatus == sdv::EObjectStatus::configuring || m_eObjectStatus == sdv::EObjectStatus::initialized)
m_eObjectStatus = sdv::EObjectStatus::running;
break;
default:
break;
}
}
/**
* @brief Shutdown method called before the object is destroyed.
* @attention Implement calls to other SDV objects here as this is no longer considered safe during the destructor of the object!
* After a call to shutdown any threads/callbacks/etc that could call other SDV objects need to have been stopped.
* The SDV object itself is to remain in a state where it can respond to calls to its interfaces as other objects may still call it during the shutdown sequence!
* Any subsequent call to GetStatus should return EObjectStatus::destruction_pending
*/
virtual void Shutdown()
{
EXPECT_TRUE(m_eObjectStatus == sdv::EObjectStatus::running || m_eObjectStatus == sdv::EObjectStatus::initialized ||
m_eObjectStatus == sdv::EObjectStatus::configuring);
if (m_eObjectStatus != sdv::EObjectStatus::running && m_eObjectStatus != sdv::EObjectStatus::initialized
&& m_eObjectStatus != sdv::EObjectStatus::configuring)
std::cout << "Object status = " << static_cast<uint32_t>(m_eObjectStatus) << " (expected initialized=" <<
static_cast<uint32_t>(sdv::EObjectStatus::initialized) << " or configuring=" <<
static_cast<uint32_t>(sdv::EObjectStatus::configuring) << " or running=" <<
static_cast<uint32_t>(sdv::EObjectStatus::running) << ")." << std::endl;
m_eObjectStatus = sdv::EObjectStatus::destruction_pending;
}
/**
* @brief Say hello. Overload of IHello::SayHello.
* @return The greetings string.
*/
virtual sdv::u8string SayHello() const override
{
return "Hello from system service";
}
private:
sdv::EObjectStatus m_eObjectStatus = sdv::EObjectStatus::initialization_pending; ///< Object status
};
DEFINE_SDV_OBJECT(CTestSystemService)

View File

@@ -0,0 +1,107 @@
#include <gtest/gtest.h>
#include <support/component_impl.h>
#include "generated/test_component.h"
/**
* @brief Utility test component #1
*/
class CTestUtility1 : public sdv::CSdvObject, public sdv::IObjectControl, public IHello
{
public:
/**
* @brief Constructor
*/
~CTestUtility1()
{
EXPECT_EQ(m_eObjectStatus, sdv::EObjectStatus::destruction_pending);
}
// Interface map
BEGIN_SDV_INTERFACE_MAP()
SDV_INTERFACE_ENTRY(sdv::IObjectControl)
SDV_INTERFACE_ENTRY(IHello)
END_SDV_INTERFACE_MAP()
// Object declarations
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::Utility)
DECLARE_OBJECT_CLASS_NAME("SDVControl_Test_Utility1")
/**
* @brief Initialize method. On success, a subsequent call to GetStatus returns EObjectStatus::running
* @param[in] ssObjectConfig Optional configuration string.
*/
virtual void Initialize([[maybe_unused]] const sdv::u8string& ssObjectConfig)
{
EXPECT_EQ(m_eObjectStatus, sdv::EObjectStatus::initialization_pending);
m_eObjectStatus = sdv::EObjectStatus::initialized;
}
/**
* @brief Gets the current status of the object
* @return EObjectStatus The current status of the object
*/
virtual sdv::EObjectStatus GetStatus() const
{
return m_eObjectStatus;
}
/**
* @brief Set the component operation mode. Overload of sdv::IObjectControl::SetOperationMode.
* @param[in] eMode The operation mode, the component should run in.
*/
void SetOperationMode(sdv::EOperationMode eMode)
{
switch (eMode)
{
case sdv::EOperationMode::configuring:
if (m_eObjectStatus == sdv::EObjectStatus::running || m_eObjectStatus == sdv::EObjectStatus::initialized)
m_eObjectStatus = sdv::EObjectStatus::configuring;
break;
case sdv::EOperationMode::running:
if (m_eObjectStatus == sdv::EObjectStatus::configuring || m_eObjectStatus == sdv::EObjectStatus::initialized)
m_eObjectStatus = sdv::EObjectStatus::running;
break;
default:
break;
}
}
/**
* @brief Shutdown method called before the object is destroyed.
* @attention Implement calls to other SDV objects here as this is no longer considered safe during the destructor of the object!
* After a call to shutdown any threads/callbacks/etc that could call other SDV objects need to have been stopped.
* The SDV object itself is to remain in a state where it can respond to calls to its interfaces as other objects may still call it during the shutdown sequence!
* Any subsequent call to GetStatus should return EObjectStatus::destruction_pending
*/
virtual void Shutdown()
{
EXPECT_TRUE(m_eObjectStatus == sdv::EObjectStatus::running || m_eObjectStatus == sdv::EObjectStatus::initialized ||
m_eObjectStatus == sdv::EObjectStatus::configuring);
if (m_eObjectStatus != sdv::EObjectStatus::running && m_eObjectStatus != sdv::EObjectStatus::initialized
&& m_eObjectStatus != sdv::EObjectStatus::configuring)
std::cout << "Object status = " << static_cast<uint32_t>(m_eObjectStatus) << " (expected initialized=" <<
static_cast<uint32_t>(sdv::EObjectStatus::initialized) << " or configuring=" <<
static_cast<uint32_t>(sdv::EObjectStatus::configuring) << " or running=" <<
static_cast<uint32_t>(sdv::EObjectStatus::running) << ")." << std::endl;
m_eObjectStatus = sdv::EObjectStatus::destruction_pending;
}
/**
* @brief Say hello. Overload of IHello::SayHello.
* @return The greetings string.
*/
virtual sdv::u8string SayHello() const override
{
return "Hello from utility #1";
}
private:
sdv::EObjectStatus m_eObjectStatus = sdv::EObjectStatus::initialization_pending; ///< Object status
};
DEFINE_SDV_OBJECT(CTestUtility1)

View File

@@ -0,0 +1,107 @@
#include <gtest/gtest.h>
#include <support/component_impl.h>
#include "generated/test_component.h"
/**
* @brief Utility test component #2
*/
class CTestUtility2 : public sdv::CSdvObject, public sdv::IObjectControl, public IHello
{
public:
/**
* @brief Constructor
*/
~CTestUtility2()
{
EXPECT_EQ(m_eObjectStatus, sdv::EObjectStatus::destruction_pending);
}
// Interface map
BEGIN_SDV_INTERFACE_MAP()
SDV_INTERFACE_ENTRY(sdv::IObjectControl)
SDV_INTERFACE_ENTRY(IHello)
END_SDV_INTERFACE_MAP()
// Object declarations
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::Utility)
DECLARE_OBJECT_CLASS_NAME("SDVControl_Test_Utility2")
/**
* @brief Initialize method. On success, a subsequent call to GetStatus returns EObjectStatus::running
* @param[in] ssObjectConfig Optional configuration string.
*/
virtual void Initialize([[maybe_unused]] const sdv::u8string& ssObjectConfig)
{
EXPECT_EQ(m_eObjectStatus, sdv::EObjectStatus::initialization_pending);
m_eObjectStatus = sdv::EObjectStatus::initialized;
}
/**
* @brief Gets the current status of the object
* @return EObjectStatus The current status of the object
*/
virtual sdv::EObjectStatus GetStatus() const
{
return m_eObjectStatus;
}
/**
* @brief Set the component operation mode. Overload of sdv::IObjectControl::SetOperationMode.
* @param[in] eMode The operation mode, the component should run in.
*/
void SetOperationMode(sdv::EOperationMode eMode)
{
switch (eMode)
{
case sdv::EOperationMode::configuring:
if (m_eObjectStatus == sdv::EObjectStatus::running || m_eObjectStatus == sdv::EObjectStatus::initialized)
m_eObjectStatus = sdv::EObjectStatus::configuring;
break;
case sdv::EOperationMode::running:
if (m_eObjectStatus == sdv::EObjectStatus::configuring || m_eObjectStatus == sdv::EObjectStatus::initialized)
m_eObjectStatus = sdv::EObjectStatus::running;
break;
default:
break;
}
}
/**
* @brief Shutdown method called before the object is destroyed.
* @attention Implement calls to other SDV objects here as this is no longer considered safe during the destructor of the object!
* After a call to shutdown any threads/callbacks/etc that could call other SDV objects need to have been stopped.
* The SDV object itself is to remain in a state where it can respond to calls to its interfaces as other objects may still call it during the shutdown sequence!
* Any subsequent call to GetStatus should return EObjectStatus::destruction_pending
*/
virtual void Shutdown()
{
EXPECT_TRUE(m_eObjectStatus == sdv::EObjectStatus::running || m_eObjectStatus == sdv::EObjectStatus::initialized ||
m_eObjectStatus == sdv::EObjectStatus::configuring);
if (m_eObjectStatus != sdv::EObjectStatus::running && m_eObjectStatus != sdv::EObjectStatus::initialized
&& m_eObjectStatus != sdv::EObjectStatus::configuring)
std::cout << "Object status = " << static_cast<uint32_t>(m_eObjectStatus) << " (expected initialized=" <<
static_cast<uint32_t>(sdv::EObjectStatus::initialized) << " or configuring=" <<
static_cast<uint32_t>(sdv::EObjectStatus::configuring) << " or running=" <<
static_cast<uint32_t>(sdv::EObjectStatus::running) << ")." << std::endl;
m_eObjectStatus = sdv::EObjectStatus::destruction_pending;
}
/**
* @brief Say hello. Overload of IHello::SayHello.
* @return The greetings string.
*/
virtual sdv::u8string SayHello() const override
{
return "Hello from utility #2";
}
private:
sdv::EObjectStatus m_eObjectStatus = sdv::EObjectStatus::initialization_pending; ///< Object status
};
DEFINE_SDV_OBJECT(CTestUtility2)