mirror of
https://github.com/eclipse-openvehicle-api/openvehicle-api.git
synced 2026-08-30 04:15:10 +00:00
connection between 2 systems and bug fixes (#14)
This commit is contained in:
156
tests/component_tests/app_connect/CMakeLists.txt
Normal file
156
tests/component_tests/app_connect/CMakeLists.txt
Normal file
@@ -0,0 +1,156 @@
|
||||
#*******************************************************************************
|
||||
# Copyright (c) 2025-2026 ZF Friedrichshafen AG
|
||||
#
|
||||
# This program and the accompanying materials are made available under the
|
||||
# terms of the Apache License Version 2.0 which is available at
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Contributors:
|
||||
# Erik Verhoeven - initial API and implementation
|
||||
#*******************************************************************************
|
||||
|
||||
# Define project
|
||||
project (ComponentTest_App_Connect 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 ${PROJECT_SOURCE_DIR}/generated/ps/proxystub.cpp ${PROJECT_SOURCE_DIR}/generated/serdes/test_component_serdes.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(test_component_ps.cpp OBJECT_DEPENDS ${PROJECT_SOURCE_DIR}/generated/test_component.h)
|
||||
set_source_files_properties(test_component_ps.cpp OBJECT_DEPENDS ${PROJECT_SOURCE_DIR}/generated/ps/proxystub.cpp)
|
||||
set_source_files_properties(test_component_ps.cpp OBJECT_DEPENDS ${PROJECT_SOURCE_DIR}/generated/serdes/test_component_serdes.h)
|
||||
set_source_files_properties(test_component_device.cpp OBJECT_DEPENDS ${PROJECT_SOURCE_DIR}/generated/test_component.h)
|
||||
set_source_files_properties(test_component_basic_service.cpp OBJECT_DEPENDS ${PROJECT_SOURCE_DIR}/generated/test_component.h)
|
||||
set_source_files_properties(test_component_complex_service.cpp OBJECT_DEPENDS ${PROJECT_SOURCE_DIR}/generated/test_component.h)
|
||||
set_source_files_properties(test_component_system_service.cpp OBJECT_DEPENDS ${PROJECT_SOURCE_DIR}/generated/test_component.h)
|
||||
set_source_files_properties(test_component_utility.cpp OBJECT_DEPENDS ${PROJECT_SOURCE_DIR}/generated/test_component.h)
|
||||
|
||||
# Create the proxy stub dynamic library
|
||||
add_library(AppConnect_Component_ps SHARED "test_component_ps.cpp")
|
||||
set_target_properties(AppConnect_Component_ps PROPERTIES PREFIX "")
|
||||
set_target_properties(AppConnect_Component_ps PROPERTIES SUFFIX ".sdv")
|
||||
|
||||
# Create the device dynamic library
|
||||
add_library(AppConnect_Component_Device SHARED "test_component_device.cpp")
|
||||
set_target_properties(AppConnect_Component_Device PROPERTIES PREFIX "")
|
||||
set_target_properties(AppConnect_Component_Device PROPERTIES SUFFIX ".sdv")
|
||||
|
||||
# Create the basic service dynamic library
|
||||
add_library(AppConnect_Component_BasicService SHARED "test_component_basic_service.cpp")
|
||||
set_target_properties(AppConnect_Component_BasicService PROPERTIES PREFIX "")
|
||||
set_target_properties(AppConnect_Component_BasicService PROPERTIES SUFFIX ".sdv")
|
||||
|
||||
# Create the complex service dynamic library
|
||||
add_library(AppConnect_Component_ComplexService SHARED "test_component_complex_service.cpp")
|
||||
set_target_properties(AppConnect_Component_ComplexService PROPERTIES PREFIX "")
|
||||
set_target_properties(AppConnect_Component_ComplexService PROPERTIES SUFFIX ".sdv")
|
||||
|
||||
# Create the system service dynamic library
|
||||
add_library(AppConnect_Component_SystemService SHARED "test_component_system_service.cpp")
|
||||
set_target_properties(AppConnect_Component_SystemService PROPERTIES PREFIX "")
|
||||
set_target_properties(AppConnect_Component_SystemService PROPERTIES SUFFIX ".sdv")
|
||||
|
||||
# Create the utility dynamic library
|
||||
add_library(AppConnect_Component_Utility SHARED "test_component_utility.cpp")
|
||||
set_target_properties(AppConnect_Component_Utility PROPERTIES PREFIX "")
|
||||
set_target_properties(AppConnect_Component_Utility PROPERTIES SUFFIX ".sdv")
|
||||
|
||||
# Server instances: Install the device, system, basic and complex service, utility and prox/stub components in server instances
|
||||
# shared memory: 195 and 196
|
||||
# UDS: 199 and 200
|
||||
# Tunnel-UDS: 203 and 204
|
||||
# Client instances: Install the proxy/stub components
|
||||
# shared memory: 197 and 198
|
||||
# UDS: 201 and 202
|
||||
# Tunnel-UDS: 205 and 206
|
||||
add_custom_target(AppConnect_Component_Install
|
||||
COMMAND "$<TARGET_FILE:sdv_packager>" DIRECT_INSTALL AppConnect_Component --instance195 "AppConnect_Component_*.sdv" "-I$<TARGET_FILE_DIR:AppConnect_Component_ps>" --overwrite
|
||||
COMMAND "$<TARGET_FILE:sdv_packager>" DIRECT_INSTALL AppConnect_Component --instance196 "AppConnect_Component_*.sdv" "-I$<TARGET_FILE_DIR:AppConnect_Component_ps>" --overwrite
|
||||
COMMAND "$<TARGET_FILE:sdv_packager>" DIRECT_INSTALL AppConnect_Component_ps --instance197 "AppConnect_Component_ps.sdv" "-I$<TARGET_FILE_DIR:AppConnect_Component_ps>" --overwrite
|
||||
COMMAND "$<TARGET_FILE:sdv_packager>" DIRECT_INSTALL AppConnect_Component_ps --instance198 "AppConnect_Component_ps.sdv" "-I$<TARGET_FILE_DIR:AppConnect_Component_ps>" --overwrite
|
||||
COMMAND "$<TARGET_FILE:sdv_packager>" DIRECT_INSTALL AppConnect_Component --instance199 "AppConnect_Component_*.sdv" "-I$<TARGET_FILE_DIR:AppConnect_Component_ps>" --overwrite
|
||||
COMMAND "$<TARGET_FILE:sdv_packager>" DIRECT_INSTALL AppConnect_Component --instance200 "AppConnect_Component_*.sdv" "-I$<TARGET_FILE_DIR:AppConnect_Component_ps>" --overwrite
|
||||
COMMAND "$<TARGET_FILE:sdv_packager>" DIRECT_INSTALL AppConnect_Component_ps --instance201 "AppConnect_Component_ps.sdv" "-I$<TARGET_FILE_DIR:AppConnect_Component_ps>" --overwrite
|
||||
COMMAND "$<TARGET_FILE:sdv_packager>" DIRECT_INSTALL AppConnect_Component_ps --instance202 "AppConnect_Component_ps.sdv" "-I$<TARGET_FILE_DIR:AppConnect_Component_ps>" --overwrite
|
||||
COMMAND "$<TARGET_FILE:sdv_packager>" DIRECT_INSTALL AppConnect_Component --instance203 "AppConnect_Component_*.sdv" "-I$<TARGET_FILE_DIR:AppConnect_Component_ps>" --overwrite
|
||||
COMMAND "$<TARGET_FILE:sdv_packager>" DIRECT_INSTALL AppConnect_Component --instance204 "AppConnect_Component_*.sdv" "-I$<TARGET_FILE_DIR:AppConnect_Component_ps>" --overwrite
|
||||
COMMAND "$<TARGET_FILE:sdv_packager>" DIRECT_INSTALL AppConnect_Component_ps --instance205 "AppConnect_Component_ps.sdv" "-I$<TARGET_FILE_DIR:AppConnect_Component_ps>" --overwrite
|
||||
COMMAND "$<TARGET_FILE:sdv_packager>" DIRECT_INSTALL AppConnect_Component_ps --instance206 "AppConnect_Component_ps.sdv" "-I$<TARGET_FILE_DIR:AppConnect_Component_ps>" --overwrite
|
||||
DEPENDS dependency_sdv_components AppConnect_Component_ps AppConnect_Component_Device AppConnect_Component_BasicService AppConnect_Component_ComplexService AppConnect_Component_SystemService AppConnect_Component_Utility
|
||||
WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
|
||||
)
|
||||
|
||||
# Configure listener for server instance
|
||||
# Shared memory: 196 (195 is default)
|
||||
# UDS: 199, 200
|
||||
# Tunnel-UDS: 203, 204
|
||||
# Connections for client instances
|
||||
# Shared memory: 197 and 198
|
||||
# UDS: 201 and 202
|
||||
# Tunnel-UDS: 205 and 206
|
||||
add_custom_target(AppConnect_Communication_Install
|
||||
COMMAND "$<TARGET_FILE:sdv_control>" LISTENER ADD MySpecialListener DefaultSharedMemory Name=private_channel_196_198 --instance196
|
||||
COMMAND "$<TARGET_FILE:sdv_control>" CONNECTION ADD DefaultChannelTo195 DefaultSharedMemory Name=DEFAULT_CHANNEL_195 --instance197
|
||||
COMMAND "$<TARGET_FILE:sdv_control>" CONNECTION ADD MySpecialConnection DefaultSharedMemory Name=private_channel_196_198 --instance198
|
||||
COMMAND "$<TARGET_FILE:sdv_control>" LISTENER ADD Default unix_domain_sockets Name=DEFAULT_CHANNEL_199 --instance199
|
||||
COMMAND "$<TARGET_FILE:sdv_control>" LISTENER ADD MySpecialListener unix_domain_sockets Name=private_channel_200_202 --instance200
|
||||
COMMAND "$<TARGET_FILE:sdv_control>" CONNECTION ADD DefaultChannelTo199 unix_domain_sockets Name=DEFAULT_CHANNEL_199 --instance201
|
||||
COMMAND "$<TARGET_FILE:sdv_control>" CONNECTION ADD MySpecialConnection unix_domain_sockets Name=private_channel_200_202 --instance202
|
||||
COMMAND "$<TARGET_FILE:sdv_control>" LISTENER ADD Default unix_domain_sockets_tunnel Name=DEFAULT_CHANNEL_203 --instance203
|
||||
COMMAND "$<TARGET_FILE:sdv_control>" LISTENER ADD MySpecialListener unix_domain_sockets_tunnel Name=private_channel_204_206 --instance204
|
||||
COMMAND "$<TARGET_FILE:sdv_control>" CONNECTION ADD DefaultChannelTo203 unix_domain_sockets_tunnel Name=DEFAULT_CHANNEL_203 --instance205
|
||||
COMMAND "$<TARGET_FILE:sdv_control>" CONNECTION ADD MySpecialConnection unix_domain_sockets_tunnel Name=private_channel_204_206 --instance206
|
||||
DEPENDS dependency_sdv_components AppConnect_Component_ps AppConnect_Component_Device AppConnect_Component_BasicService AppConnect_Component_ComplexService AppConnect_Component_SystemService AppConnect_Component_Utility
|
||||
WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
|
||||
)
|
||||
|
||||
# Compile the source code of the server
|
||||
add_executable(AppConnect_Server
|
||||
"main_server.cpp")
|
||||
target_link_libraries(AppConnect_Server ${CMAKE_DL_LIBS})
|
||||
|
||||
# Compile the source code
|
||||
add_executable(ComponentTest_App_Connect
|
||||
"main.cpp"
|
||||
"app_connect_tests_shared_mem.cpp"
|
||||
"app_connect_tests_uds.cpp"
|
||||
"app_connect_tests_uds_tunnel.cpp"
|
||||
)
|
||||
target_link_libraries(ComponentTest_App_Connect ${CMAKE_DL_LIBS} GTest::GTest)
|
||||
|
||||
# Add the connect test
|
||||
add_test(NAME ComponentTest_App_Connect COMMAND ComponentTest_App_Connect)
|
||||
|
||||
# Execute the test
|
||||
add_custom_command(TARGET ComponentTest_App_Connect POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E env TEST_EXECUTION_MODE=CMake "$<TARGET_FILE:ComponentTest_App_Connect>" --gtest_output=xml:${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ComponentTest_App_Connect.xml
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
# Build dependencies
|
||||
add_dependencies(AppConnect_Server dependency_sdv_components)
|
||||
add_dependencies(ComponentTest_App_Connect dependency_sdv_components)
|
||||
add_dependencies(ComponentTest_App_Connect AppConnect_Server)
|
||||
add_dependencies(ComponentTest_App_Connect AppConnect_Component_Install)
|
||||
add_dependencies(ComponentTest_App_Connect AppConnect_Communication_Install)
|
||||
add_dependencies(AppConnect_Component_ps dependency_sdv_components)
|
||||
add_dependencies(AppConnect_Component_Device dependency_sdv_components)
|
||||
add_dependencies(AppConnect_Component_BasicService dependency_sdv_components)
|
||||
add_dependencies(AppConnect_Component_ComplexService dependency_sdv_components)
|
||||
add_dependencies(AppConnect_Component_SystemService dependency_sdv_components)
|
||||
add_dependencies(AppConnect_Component_Utility dependency_sdv_components)
|
||||
@@ -0,0 +1,519 @@
|
||||
/********************************************************************************
|
||||
* Copyright (c) 2025-2026 ZF Friedrichshafen AG
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Apache License Version 2.0 which is available at
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Erik Verhoeven - initial API and implementation
|
||||
********************************************************************************/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include "../../../sdv_services/process_control/process_control.h"
|
||||
#include "../../../global/ipc_named_mutex.h"
|
||||
#include "../../../global/exec_dir_helper.h"
|
||||
#include "generated/test_component.h"
|
||||
#include <interfaces/app.h>
|
||||
#include <support/app_control.h>
|
||||
#include <support/mem_access.h>
|
||||
#include <support/sdv_core.h>
|
||||
|
||||
// The test use the following instance numbers (all configured as main application):
|
||||
// - instance 195 server without additional listener configured (channel: DEFAULT_CHANNEL_195)
|
||||
// - instance 196 server with additional listener configured (channels: DEFAULT_CHANNEL_196 and private_channel_196_198)
|
||||
// - instance 197 client with 195-default connection configured (channel: DEFAULT_CHANNEL_195)
|
||||
// - instance 198 client with 196-special connection configured (channel: private_channel_196_198)
|
||||
|
||||
TEST(AppConnect, ServerStart_DefaultSharedMemory)
|
||||
{
|
||||
// The default instance
|
||||
sdv::app::CAppControl control;
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = control.Startup(R"toml([Application]
|
||||
Mode = "Main"
|
||||
Instance = 195
|
||||
[Console]
|
||||
RedirectMon = true
|
||||
)toml");
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_TRUE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::main);
|
||||
EXPECT_EQ(control.GetInstanceID(), 195u);
|
||||
|
||||
// Within the server instance all objects should be accessible.
|
||||
// NOTE: The complex service is running isolated.
|
||||
|
||||
// Test utility
|
||||
SStages sStages{};
|
||||
std::string ss;
|
||||
auto ptrUtilityHelloObject = sdv::core::CreateUtility("TestObject_HelloUtility");
|
||||
EXPECT_TRUE(ptrUtilityHelloObject);
|
||||
auto pHelloObject = ptrUtilityHelloObject.GetInterface<IHello>();
|
||||
EXPECT_TRUE(pHelloObject);
|
||||
if (pHelloObject) ss = pHelloObject->SayHello(sStages);
|
||||
EXPECT_FALSE(ss.empty());
|
||||
EXPECT_FALSE(sStages.bDevice);
|
||||
EXPECT_FALSE(sStages.bBasicService);
|
||||
EXPECT_FALSE(sStages.bComplexService);
|
||||
EXPECT_FALSE(sStages.bSystemService);
|
||||
EXPECT_TRUE(sStages.bUtility);
|
||||
std::cout << "Utility reports:" << std::endl << ss;
|
||||
|
||||
// Test system object
|
||||
sStages = {};
|
||||
ss.clear();
|
||||
pHelloObject = sdv::core::GetObject<IHello>("TestObject_SystemHelloService");
|
||||
EXPECT_TRUE(pHelloObject);
|
||||
if (pHelloObject) ss = pHelloObject->SayHello(sStages);
|
||||
EXPECT_FALSE(ss.empty());
|
||||
EXPECT_FALSE(sStages.bDevice);
|
||||
EXPECT_FALSE(sStages.bBasicService);
|
||||
EXPECT_FALSE(sStages.bComplexService);
|
||||
EXPECT_TRUE(sStages.bSystemService);
|
||||
EXPECT_FALSE(sStages.bUtility);
|
||||
std::cout << "System service reports:" << std::endl << ss;
|
||||
|
||||
// Test device object - executes SayHello on Utility and System Service
|
||||
sStages = {};
|
||||
ss.clear();
|
||||
pHelloObject = sdv::core::GetObject<IHello>("TestObject_HelloDevice");
|
||||
EXPECT_TRUE(pHelloObject);
|
||||
if (pHelloObject) ss = pHelloObject->SayHello(sStages);
|
||||
EXPECT_FALSE(ss.empty());
|
||||
EXPECT_TRUE(sStages.bDevice);
|
||||
EXPECT_FALSE(sStages.bBasicService);
|
||||
EXPECT_FALSE(sStages.bComplexService);
|
||||
EXPECT_TRUE(sStages.bSystemService);
|
||||
EXPECT_TRUE(sStages.bUtility);
|
||||
std::cout << "Device reports:" << std::endl << ss;
|
||||
|
||||
// Test basic service object - executes SayHello on Device, Utility and System Service
|
||||
sStages = {};
|
||||
ss.clear();
|
||||
pHelloObject = sdv::core::GetObject<IHello>("TestObject_BasicHelloService");
|
||||
EXPECT_TRUE(pHelloObject);
|
||||
if (pHelloObject) ss = pHelloObject->SayHello(sStages);
|
||||
EXPECT_FALSE(ss.empty());
|
||||
EXPECT_TRUE(sStages.bDevice);
|
||||
EXPECT_TRUE(sStages.bBasicService);
|
||||
EXPECT_FALSE(sStages.bComplexService);
|
||||
EXPECT_TRUE(sStages.bSystemService);
|
||||
EXPECT_TRUE(sStages.bUtility);
|
||||
std::cout << "Basic service reports:" << std::endl << ss;
|
||||
|
||||
//// Test complex service object - executes SayHello on Complex Service, Device, Utility and System Service
|
||||
//sStages = {};
|
||||
//ss.clear();
|
||||
//pHelloObject = sdv::core::GetObject<IHello>("TestObject_ComplexHelloService");
|
||||
//EXPECT_TRUE(pHelloObject);
|
||||
//if (pHelloObject) ss = pHelloObject->SayHello(sStages);
|
||||
//EXPECT_FALSE(ss.empty());
|
||||
//EXPECT_TRUE(sStages.bDevice);
|
||||
//EXPECT_TRUE(sStages.bBasicService);
|
||||
//EXPECT_TRUE(sStages.bComplexService);
|
||||
//EXPECT_TRUE(sStages.bSystemService);
|
||||
//EXPECT_TRUE(sStages.bUtility);
|
||||
//std::cout << "Basic service reports:" << std::endl << ss;
|
||||
|
||||
control.Shutdown();
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(AppConnect, ServerStart_PrivateSharedMemory)
|
||||
{
|
||||
// The default instance
|
||||
sdv::app::CAppControl control;
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = control.Startup(R"toml([Application]
|
||||
Mode = "Main"
|
||||
Instance = 196
|
||||
[Console]
|
||||
RedirectMon = true
|
||||
)toml");
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_TRUE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::main);
|
||||
EXPECT_EQ(control.GetInstanceID(), 196u);
|
||||
|
||||
// Test utility
|
||||
SStages sStages{};
|
||||
std::string ss;
|
||||
auto ptrUtilityHelloObject = sdv::core::CreateUtility("TestObject_HelloUtility");
|
||||
EXPECT_TRUE(ptrUtilityHelloObject);
|
||||
auto pHelloObject = ptrUtilityHelloObject.GetInterface<IHello>();
|
||||
EXPECT_TRUE(pHelloObject);
|
||||
if (pHelloObject)
|
||||
ss = pHelloObject->SayHello(sStages);
|
||||
EXPECT_FALSE(ss.empty());
|
||||
EXPECT_FALSE(sStages.bDevice);
|
||||
EXPECT_FALSE(sStages.bBasicService);
|
||||
EXPECT_FALSE(sStages.bComplexService);
|
||||
EXPECT_FALSE(sStages.bSystemService);
|
||||
EXPECT_TRUE(sStages.bUtility);
|
||||
std::cout << "Utility reports:" << std::endl << ss;
|
||||
|
||||
// Test system object
|
||||
sStages = {};
|
||||
ss.clear();
|
||||
pHelloObject = sdv::core::GetObject<IHello>("TestObject_SystemHelloService");
|
||||
EXPECT_TRUE(pHelloObject);
|
||||
if (pHelloObject)
|
||||
ss = pHelloObject->SayHello(sStages);
|
||||
EXPECT_FALSE(ss.empty());
|
||||
EXPECT_FALSE(sStages.bDevice);
|
||||
EXPECT_FALSE(sStages.bBasicService);
|
||||
EXPECT_FALSE(sStages.bComplexService);
|
||||
EXPECT_TRUE(sStages.bSystemService);
|
||||
EXPECT_FALSE(sStages.bUtility);
|
||||
std::cout << "System service reports:" << std::endl << ss;
|
||||
|
||||
// Test device object - executes SayHello on Utility and System Service
|
||||
sStages = {};
|
||||
ss.clear();
|
||||
pHelloObject = sdv::core::GetObject<IHello>("TestObject_HelloDevice");
|
||||
EXPECT_TRUE(pHelloObject);
|
||||
if (pHelloObject)
|
||||
ss = pHelloObject->SayHello(sStages);
|
||||
EXPECT_FALSE(ss.empty());
|
||||
EXPECT_TRUE(sStages.bDevice);
|
||||
EXPECT_FALSE(sStages.bBasicService);
|
||||
EXPECT_FALSE(sStages.bComplexService);
|
||||
EXPECT_TRUE(sStages.bSystemService);
|
||||
EXPECT_TRUE(sStages.bUtility);
|
||||
std::cout << "Device reports:" << std::endl << ss;
|
||||
|
||||
// Test basic service object - executes SayHello on Device, Utility and System Service
|
||||
sStages = {};
|
||||
ss.clear();
|
||||
pHelloObject = sdv::core::GetObject<IHello>("TestObject_BasicHelloService");
|
||||
EXPECT_TRUE(pHelloObject);
|
||||
if (pHelloObject)
|
||||
ss = pHelloObject->SayHello(sStages);
|
||||
EXPECT_FALSE(ss.empty());
|
||||
EXPECT_TRUE(sStages.bDevice);
|
||||
EXPECT_TRUE(sStages.bBasicService);
|
||||
EXPECT_FALSE(sStages.bComplexService);
|
||||
EXPECT_TRUE(sStages.bSystemService);
|
||||
EXPECT_TRUE(sStages.bUtility);
|
||||
std::cout << "Basic service reports:" << std::endl << ss;
|
||||
|
||||
//// Test complex service object - executes SayHello on Complex Service, Device, Utility and System Service
|
||||
// sStages = {};
|
||||
// ss.clear();
|
||||
// pHelloObject = sdv::core::GetObject<IHello>("TestObject_ComplexHelloService");
|
||||
// EXPECT_TRUE(pHelloObject);
|
||||
// if (pHelloObject) ss = pHelloObject->SayHello(sStages);
|
||||
// EXPECT_FALSE(ss.empty());
|
||||
// EXPECT_TRUE(sStages.bDevice);
|
||||
// EXPECT_TRUE(sStages.bBasicService);
|
||||
// EXPECT_TRUE(sStages.bComplexService);
|
||||
// EXPECT_TRUE(sStages.bSystemService);
|
||||
// EXPECT_TRUE(sStages.bUtility);
|
||||
// std::cout << "Basic service reports:" << std::endl << ss;
|
||||
|
||||
control.Shutdown();
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(AppConnect, ServerApp_Control_SharedMem)
|
||||
{
|
||||
// The lifetime of the server app is managed through a named mutex being available for locking. Lock the mutex
|
||||
ipc::named_mutex mtx("app_connect_test_mutex");
|
||||
std::unique_lock<ipc::named_mutex> lock(mtx);
|
||||
|
||||
// Use the process control class to manage the server process
|
||||
// Enable access bypass to allow its usage.
|
||||
CProcessControl procctrl;
|
||||
procctrl.EnableProcessControlAccessBypass();
|
||||
procctrl.Initialize(sdv::SObjectInfo());
|
||||
EXPECT_EQ(procctrl.GetObjectState(), sdv::EObjectState::initialized);
|
||||
|
||||
// Execute the server process
|
||||
sdv::process::TProcessID tServerID = procctrl.Execute(
|
||||
(GetExecDirectory() / "AppConnect_Server").generic_u8string(), {"195"}, sdv::process::EProcessRights::default_rights);
|
||||
EXPECT_NE(tServerID, 0u);
|
||||
|
||||
// Wait for 1 second
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||
|
||||
// Test for the running server
|
||||
EXPECT_FALSE(procctrl.WaitForTerminate(tServerID, 1));
|
||||
|
||||
// Release the mutex; this should shutdown the server
|
||||
lock.unlock();
|
||||
|
||||
// Wait for 1 second
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||
|
||||
// Test for the running server - should be terminated
|
||||
EXPECT_TRUE(procctrl.WaitForTerminate(tServerID, 10000));
|
||||
|
||||
// Just in case termination
|
||||
procctrl.Terminate(tServerID);
|
||||
|
||||
// End process control
|
||||
procctrl.Shutdown();
|
||||
}
|
||||
|
||||
TEST(AppConnect, ClientConnect_DefaultSharedMem)
|
||||
{
|
||||
// The lifetime of the server app is managed through a named mutex being available for locking. Lock the mutex
|
||||
ipc::named_mutex mtx("app_connect_test_mutex");
|
||||
std::unique_lock<ipc::named_mutex> lock(mtx);
|
||||
|
||||
// Use the process control class to manage the server process
|
||||
// Enable access bypass to allow its usage.
|
||||
CProcessControl procctrl;
|
||||
procctrl.EnableProcessControlAccessBypass();
|
||||
procctrl.Initialize(sdv::SObjectInfo());
|
||||
EXPECT_EQ(procctrl.GetObjectState(), sdv::EObjectState::initialized);
|
||||
|
||||
// Execute the server process
|
||||
sdv::process::TProcessID tServerID = procctrl.Execute(
|
||||
(GetExecDirectory() / "AppConnect_Server").generic_u8string(), {"195"}, sdv::process::EProcessRights::default_rights);
|
||||
EXPECT_NE(tServerID, 0u);
|
||||
|
||||
// Wait for 1 second
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||
|
||||
// Test for the running server
|
||||
EXPECT_FALSE(procctrl.WaitForTerminate(tServerID, 1));
|
||||
|
||||
// Start the second system using the default instance. This simulates a client
|
||||
sdv::app::CAppControl control;
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
// When startup succeeds an automatic connection to the server 195 should have been made.
|
||||
bool bResult = control.Startup(R"toml([Application]
|
||||
Mode = "Main"
|
||||
Instance = 197
|
||||
[Console]
|
||||
RedirectMon = true
|
||||
)toml");
|
||||
EXPECT_TRUE(bResult);
|
||||
|
||||
// Test utility - not allowed
|
||||
SStages sStages{};
|
||||
std::string ss;
|
||||
auto ptrUtilityHelloObject = sdv::core::CreateUtility("TestObject_HelloUtility");
|
||||
EXPECT_FALSE(ptrUtilityHelloObject);
|
||||
|
||||
// Test system object - not allowed BUT CURRENTLY WORKING
|
||||
sStages = {};
|
||||
ss.clear();
|
||||
auto pHelloObject = sdv::core::GetObject<IHello>("TestObject_SystemHelloService");
|
||||
EXPECT_TRUE(pHelloObject);
|
||||
if (pHelloObject)
|
||||
ss = pHelloObject->SayHello(sStages);
|
||||
EXPECT_FALSE(ss.empty());
|
||||
EXPECT_FALSE(sStages.bDevice);
|
||||
EXPECT_FALSE(sStages.bBasicService);
|
||||
EXPECT_FALSE(sStages.bComplexService);
|
||||
EXPECT_TRUE(sStages.bSystemService);
|
||||
EXPECT_FALSE(sStages.bUtility);
|
||||
std::cout << "System service reports:" << std::endl << ss;
|
||||
|
||||
//// Test device object - not allowed BUT CURRENTLY WORKING
|
||||
//sStages = {};
|
||||
//ss.clear();
|
||||
//pHelloObject = sdv::core::GetObject<IHello>("TestObject_HelloDevice");
|
||||
//EXPECT_TRUE(pHelloObject);
|
||||
//if (pHelloObject)
|
||||
// ss = pHelloObject->SayHello(sStages);
|
||||
//EXPECT_FALSE(ss.empty());
|
||||
//EXPECT_TRUE(sStages.bDevice);
|
||||
//EXPECT_FALSE(sStages.bBasicService);
|
||||
//EXPECT_FALSE(sStages.bComplexService);
|
||||
//EXPECT_TRUE(sStages.bSystemService);
|
||||
//EXPECT_TRUE(sStages.bUtility);
|
||||
//std::cout << "Device reports:" << std::endl << ss;
|
||||
|
||||
// Test basic service object - tries to executes SayHello on Device, Utility and System Service, but not allowed
|
||||
sStages = {};
|
||||
ss.clear();
|
||||
pHelloObject = sdv::core::GetObject<IHello>("TestObject_BasicHelloService");
|
||||
EXPECT_TRUE(pHelloObject);
|
||||
if (pHelloObject)
|
||||
ss = pHelloObject->SayHello(sStages);
|
||||
EXPECT_FALSE(ss.empty());
|
||||
EXPECT_FALSE(sStages.bDevice);
|
||||
EXPECT_TRUE(sStages.bBasicService);
|
||||
EXPECT_FALSE(sStages.bComplexService);
|
||||
EXPECT_FALSE(sStages.bSystemService);
|
||||
EXPECT_FALSE(sStages.bUtility);
|
||||
std::cout << "Basic service reports:" << std::endl << ss;
|
||||
|
||||
//// Test complex service object - executes SayHello on Complex Service, Device, Utility and System Service
|
||||
// sStages = {};
|
||||
// ss.clear();
|
||||
// pHelloObject = sdv::core::GetObject<IHello>("TestObject_ComplexHelloService");
|
||||
// EXPECT_TRUE(pHelloObject);
|
||||
// if (pHelloObject) ss = pHelloObject->SayHello(sStages);
|
||||
// EXPECT_FALSE(ss.empty());
|
||||
// EXPECT_TRUE(sStages.bDevice);
|
||||
// EXPECT_TRUE(sStages.bBasicService);
|
||||
// EXPECT_TRUE(sStages.bComplexService);
|
||||
// EXPECT_TRUE(sStages.bSystemService);
|
||||
// EXPECT_TRUE(sStages.bUtility);
|
||||
// std::cout << "Basic service reports:" << std::endl << ss;
|
||||
|
||||
control.Shutdown();
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
// Release the mutex; this should shutdown the server
|
||||
lock.unlock();
|
||||
|
||||
// Wait for 1 second
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||
|
||||
// Test for the running server - should be terminated
|
||||
EXPECT_TRUE(procctrl.WaitForTerminate(tServerID, 10000));
|
||||
|
||||
// Just in case termination
|
||||
procctrl.Terminate(tServerID);
|
||||
|
||||
// End process control
|
||||
procctrl.Shutdown();
|
||||
}
|
||||
|
||||
TEST(AppConnect, ClientConnect_PrivateSharedMem)
|
||||
{
|
||||
// The lifetime of the server app is managed through a named mutex being available for locking. Lock the mutex
|
||||
ipc::named_mutex mtx("app_connect_test_mutex");
|
||||
std::unique_lock<ipc::named_mutex> lock(mtx);
|
||||
|
||||
// Use the process control class to manage the server process
|
||||
// Enable access bypass to allow its usage.
|
||||
CProcessControl procctrl;
|
||||
procctrl.EnableProcessControlAccessBypass();
|
||||
procctrl.Initialize(sdv::SObjectInfo());
|
||||
EXPECT_EQ(procctrl.GetObjectState(), sdv::EObjectState::initialized);
|
||||
|
||||
// Execute the server process
|
||||
sdv::process::TProcessID tServerID = procctrl.Execute(
|
||||
(GetExecDirectory() / "AppConnect_Server").generic_u8string(), {"196"}, sdv::process::EProcessRights::default_rights);
|
||||
EXPECT_NE(tServerID, 0u);
|
||||
|
||||
// Wait for 1 second
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||
|
||||
// Test for the running server
|
||||
EXPECT_FALSE(procctrl.WaitForTerminate(tServerID, 1));
|
||||
|
||||
// Start the second system using the default instance. This simulates a client
|
||||
sdv::app::CAppControl control;
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
// When startup succeeds an automatic connection to the server 196 should have been made.
|
||||
bool bResult = control.Startup(R"toml([Application]
|
||||
Mode = "Main"
|
||||
Instance = 198
|
||||
[Console]
|
||||
RedirectMon = true
|
||||
)toml");
|
||||
EXPECT_TRUE(bResult);
|
||||
|
||||
// Test utility - not allowed
|
||||
SStages sStages{};
|
||||
std::string ss;
|
||||
auto ptrUtilityHelloObject = sdv::core::CreateUtility("TestObject_HelloUtility");
|
||||
EXPECT_FALSE(ptrUtilityHelloObject);
|
||||
|
||||
// Test system object - not allowed BUT CURRENTLY WORKING
|
||||
sStages = {};
|
||||
ss.clear();
|
||||
auto pHelloObject = sdv::core::GetObject<IHello>("TestObject_SystemHelloService");
|
||||
EXPECT_TRUE(pHelloObject);
|
||||
if (pHelloObject)
|
||||
ss = pHelloObject->SayHello(sStages);
|
||||
EXPECT_FALSE(ss.empty());
|
||||
EXPECT_FALSE(sStages.bDevice);
|
||||
EXPECT_FALSE(sStages.bBasicService);
|
||||
EXPECT_FALSE(sStages.bComplexService);
|
||||
EXPECT_TRUE(sStages.bSystemService);
|
||||
EXPECT_FALSE(sStages.bUtility);
|
||||
std::cout << "System service reports:" << std::endl << ss;
|
||||
|
||||
// Test device object - not allowed BUT CURRENTLY WORKING
|
||||
//sStages = {};
|
||||
//ss.clear();
|
||||
//pHelloObject = sdv::core::GetObject<IHello>("TestObject_HelloDevice");
|
||||
//EXPECT_TRUE(pHelloObject);
|
||||
//if (pHelloObject)
|
||||
// ss = pHelloObject->SayHello(sStages);
|
||||
//EXPECT_FALSE(ss.empty());
|
||||
//EXPECT_TRUE(sStages.bDevice);
|
||||
//EXPECT_FALSE(sStages.bBasicService);
|
||||
//EXPECT_FALSE(sStages.bComplexService);
|
||||
//EXPECT_TRUE(sStages.bSystemService);
|
||||
//EXPECT_TRUE(sStages.bUtility);
|
||||
//std::cout << "Device reports:" << std::endl << ss;
|
||||
|
||||
// Test basic service object - executes SayHello on Device, Utility and System Service
|
||||
sStages = {};
|
||||
ss.clear();
|
||||
pHelloObject = sdv::core::GetObject<IHello>("TestObject_BasicHelloService");
|
||||
EXPECT_TRUE(pHelloObject);
|
||||
if (pHelloObject)
|
||||
ss = pHelloObject->SayHello(sStages);
|
||||
EXPECT_FALSE(ss.empty());
|
||||
EXPECT_FALSE(sStages.bDevice);
|
||||
EXPECT_TRUE(sStages.bBasicService);
|
||||
EXPECT_FALSE(sStages.bComplexService);
|
||||
EXPECT_FALSE(sStages.bSystemService);
|
||||
EXPECT_FALSE(sStages.bUtility);
|
||||
std::cout << "Basic service reports:" << std::endl << ss;
|
||||
|
||||
//// Test complex service object - executes SayHello on Complex Service, Device, Utility and System Service
|
||||
//sStages = {};
|
||||
//ss.clear();
|
||||
//pHelloObject = sdv::core::GetObject<IHello>("TestObject_ComplexHelloService");
|
||||
//EXPECT_TRUE(pHelloObject);
|
||||
//if (pHelloObject) ss = pHelloObject->SayHello(sStages);
|
||||
//EXPECT_FALSE(ss.empty());
|
||||
//EXPECT_TRUE(sStages.bDevice);
|
||||
//EXPECT_TRUE(sStages.bBasicService);
|
||||
//EXPECT_TRUE(sStages.bComplexService);
|
||||
//EXPECT_TRUE(sStages.bSystemService);
|
||||
//EXPECT_TRUE(sStages.bUtility);
|
||||
//std::cout << "Basic service reports:" << std::endl << ss;
|
||||
|
||||
control.Shutdown();
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
// Release the mutex; this should shutdown the server
|
||||
lock.unlock();
|
||||
|
||||
// Wait for 1 second
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||
|
||||
// Test for the running server - should be terminated
|
||||
EXPECT_TRUE(procctrl.WaitForTerminate(tServerID, 10000));
|
||||
|
||||
// Just in case termination
|
||||
procctrl.Terminate(tServerID);
|
||||
|
||||
// End process control
|
||||
procctrl.Shutdown();
|
||||
}
|
||||
519
tests/component_tests/app_connect/app_connect_tests_uds.cpp
Normal file
519
tests/component_tests/app_connect/app_connect_tests_uds.cpp
Normal file
@@ -0,0 +1,519 @@
|
||||
/********************************************************************************
|
||||
* Copyright (c) 2025-2026 ZF Friedrichshafen AG
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Apache License Version 2.0 which is available at
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Erik Verhoeven - initial API and implementation
|
||||
********************************************************************************/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include "../../../sdv_services/process_control/process_control.h"
|
||||
#include "../../../global/ipc_named_mutex.h"
|
||||
#include "../../../global/exec_dir_helper.h"
|
||||
#include "generated/test_component.h"
|
||||
#include <interfaces/app.h>
|
||||
#include <support/app_control.h>
|
||||
#include <support/mem_access.h>
|
||||
#include <support/sdv_core.h>
|
||||
|
||||
// The test use the following instance numbers (all configured as main application):
|
||||
// - instance 199 server without additional listener configured (channel: DEFAULT_CHANNEL_199)
|
||||
// - instance 200 server with additional listener configured (channels: DEFAULT_CHANNEL_200 and private_channel_200_202)
|
||||
// - instance 201 client with 199-default connection configured (channel: DEFAULT_CHANNEL_199)
|
||||
// - instance 202 client with 200-special connection configured (channel: private_channel_200_202)
|
||||
|
||||
TEST(AppConnect_UDS, ServerStart_DefaultUnixDomainSockets)
|
||||
{
|
||||
// The default instance
|
||||
sdv::app::CAppControl control;
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = control.Startup(R"toml([Application]
|
||||
Mode = "Main"
|
||||
Instance = 199
|
||||
[Console]
|
||||
RedirectMon = true
|
||||
)toml");
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_TRUE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::main);
|
||||
EXPECT_EQ(control.GetInstanceID(), 199u);
|
||||
|
||||
// Within the server instance all objects should be accessible.
|
||||
// NOTE: The complex service is running isolated.
|
||||
|
||||
// Test utility
|
||||
SStages sStages{};
|
||||
std::string ss;
|
||||
auto ptrUtilityHelloObject = sdv::core::CreateUtility("TestObject_HelloUtility");
|
||||
EXPECT_TRUE(ptrUtilityHelloObject);
|
||||
auto pHelloObject = ptrUtilityHelloObject.GetInterface<IHello>();
|
||||
EXPECT_TRUE(pHelloObject);
|
||||
if (pHelloObject) ss = pHelloObject->SayHello(sStages);
|
||||
EXPECT_FALSE(ss.empty());
|
||||
EXPECT_FALSE(sStages.bDevice);
|
||||
EXPECT_FALSE(sStages.bBasicService);
|
||||
EXPECT_FALSE(sStages.bComplexService);
|
||||
EXPECT_FALSE(sStages.bSystemService);
|
||||
EXPECT_TRUE(sStages.bUtility);
|
||||
std::cout << "Utility reports:" << std::endl << ss;
|
||||
|
||||
// Test system object
|
||||
sStages = {};
|
||||
ss.clear();
|
||||
pHelloObject = sdv::core::GetObject<IHello>("TestObject_SystemHelloService");
|
||||
EXPECT_TRUE(pHelloObject);
|
||||
if (pHelloObject) ss = pHelloObject->SayHello(sStages);
|
||||
EXPECT_FALSE(ss.empty());
|
||||
EXPECT_FALSE(sStages.bDevice);
|
||||
EXPECT_FALSE(sStages.bBasicService);
|
||||
EXPECT_FALSE(sStages.bComplexService);
|
||||
EXPECT_TRUE(sStages.bSystemService);
|
||||
EXPECT_FALSE(sStages.bUtility);
|
||||
std::cout << "System service reports:" << std::endl << ss;
|
||||
|
||||
// Test device object - executes SayHello on Utility and System Service
|
||||
sStages = {};
|
||||
ss.clear();
|
||||
pHelloObject = sdv::core::GetObject<IHello>("TestObject_HelloDevice");
|
||||
EXPECT_TRUE(pHelloObject);
|
||||
if (pHelloObject) ss = pHelloObject->SayHello(sStages);
|
||||
EXPECT_FALSE(ss.empty());
|
||||
EXPECT_TRUE(sStages.bDevice);
|
||||
EXPECT_FALSE(sStages.bBasicService);
|
||||
EXPECT_FALSE(sStages.bComplexService);
|
||||
EXPECT_TRUE(sStages.bSystemService);
|
||||
EXPECT_TRUE(sStages.bUtility);
|
||||
std::cout << "Device reports:" << std::endl << ss;
|
||||
|
||||
// Test basic service object - executes SayHello on Device, Utility and System Service
|
||||
sStages = {};
|
||||
ss.clear();
|
||||
pHelloObject = sdv::core::GetObject<IHello>("TestObject_BasicHelloService");
|
||||
EXPECT_TRUE(pHelloObject);
|
||||
if (pHelloObject) ss = pHelloObject->SayHello(sStages);
|
||||
EXPECT_FALSE(ss.empty());
|
||||
EXPECT_TRUE(sStages.bDevice);
|
||||
EXPECT_TRUE(sStages.bBasicService);
|
||||
EXPECT_FALSE(sStages.bComplexService);
|
||||
EXPECT_TRUE(sStages.bSystemService);
|
||||
EXPECT_TRUE(sStages.bUtility);
|
||||
std::cout << "Basic service reports:" << std::endl << ss;
|
||||
|
||||
//// Test complex service object - executes SayHello on Complex Service, Device, Utility and System Service
|
||||
//sStages = {};
|
||||
//ss.clear();
|
||||
//pHelloObject = sdv::core::GetObject<IHello>("TestObject_ComplexHelloService");
|
||||
//EXPECT_TRUE(pHelloObject);
|
||||
//if (pHelloObject) ss = pHelloObject->SayHello(sStages);
|
||||
//EXPECT_FALSE(ss.empty());
|
||||
//EXPECT_TRUE(sStages.bDevice);
|
||||
//EXPECT_TRUE(sStages.bBasicService);
|
||||
//EXPECT_TRUE(sStages.bComplexService);
|
||||
//EXPECT_TRUE(sStages.bSystemService);
|
||||
//EXPECT_TRUE(sStages.bUtility);
|
||||
//std::cout << "Basic service reports:" << std::endl << ss;
|
||||
|
||||
control.Shutdown();
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(AppConnect_UDS, ServerStart_PrivateUnixDomainSockets)
|
||||
{
|
||||
// The default instance
|
||||
sdv::app::CAppControl control;
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = control.Startup(R"toml([Application]
|
||||
Mode = "Main"
|
||||
Instance = 200
|
||||
[Console]
|
||||
RedirectMon = true
|
||||
)toml");
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_TRUE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::main);
|
||||
EXPECT_EQ(control.GetInstanceID(), 200u);
|
||||
|
||||
// Test utility
|
||||
SStages sStages{};
|
||||
std::string ss;
|
||||
auto ptrUtilityHelloObject = sdv::core::CreateUtility("TestObject_HelloUtility");
|
||||
EXPECT_TRUE(ptrUtilityHelloObject);
|
||||
auto pHelloObject = ptrUtilityHelloObject.GetInterface<IHello>();
|
||||
EXPECT_TRUE(pHelloObject);
|
||||
if (pHelloObject)
|
||||
ss = pHelloObject->SayHello(sStages);
|
||||
EXPECT_FALSE(ss.empty());
|
||||
EXPECT_FALSE(sStages.bDevice);
|
||||
EXPECT_FALSE(sStages.bBasicService);
|
||||
EXPECT_FALSE(sStages.bComplexService);
|
||||
EXPECT_FALSE(sStages.bSystemService);
|
||||
EXPECT_TRUE(sStages.bUtility);
|
||||
std::cout << "Utility reports:" << std::endl << ss;
|
||||
|
||||
// Test system object
|
||||
sStages = {};
|
||||
ss.clear();
|
||||
pHelloObject = sdv::core::GetObject<IHello>("TestObject_SystemHelloService");
|
||||
EXPECT_TRUE(pHelloObject);
|
||||
if (pHelloObject)
|
||||
ss = pHelloObject->SayHello(sStages);
|
||||
EXPECT_FALSE(ss.empty());
|
||||
EXPECT_FALSE(sStages.bDevice);
|
||||
EXPECT_FALSE(sStages.bBasicService);
|
||||
EXPECT_FALSE(sStages.bComplexService);
|
||||
EXPECT_TRUE(sStages.bSystemService);
|
||||
EXPECT_FALSE(sStages.bUtility);
|
||||
std::cout << "System service reports:" << std::endl << ss;
|
||||
|
||||
// Test device object - executes SayHello on Utility and System Service
|
||||
sStages = {};
|
||||
ss.clear();
|
||||
pHelloObject = sdv::core::GetObject<IHello>("TestObject_HelloDevice");
|
||||
EXPECT_TRUE(pHelloObject);
|
||||
if (pHelloObject)
|
||||
ss = pHelloObject->SayHello(sStages);
|
||||
EXPECT_FALSE(ss.empty());
|
||||
EXPECT_TRUE(sStages.bDevice);
|
||||
EXPECT_FALSE(sStages.bBasicService);
|
||||
EXPECT_FALSE(sStages.bComplexService);
|
||||
EXPECT_TRUE(sStages.bSystemService);
|
||||
EXPECT_TRUE(sStages.bUtility);
|
||||
std::cout << "Device reports:" << std::endl << ss;
|
||||
|
||||
// Test basic service object - executes SayHello on Device, Utility and System Service
|
||||
sStages = {};
|
||||
ss.clear();
|
||||
pHelloObject = sdv::core::GetObject<IHello>("TestObject_BasicHelloService");
|
||||
EXPECT_TRUE(pHelloObject);
|
||||
if (pHelloObject)
|
||||
ss = pHelloObject->SayHello(sStages);
|
||||
EXPECT_FALSE(ss.empty());
|
||||
EXPECT_TRUE(sStages.bDevice);
|
||||
EXPECT_TRUE(sStages.bBasicService);
|
||||
EXPECT_FALSE(sStages.bComplexService);
|
||||
EXPECT_TRUE(sStages.bSystemService);
|
||||
EXPECT_TRUE(sStages.bUtility);
|
||||
std::cout << "Basic service reports:" << std::endl << ss;
|
||||
|
||||
//// Test complex service object - executes SayHello on Complex Service, Device, Utility and System Service
|
||||
// sStages = {};
|
||||
// ss.clear();
|
||||
// pHelloObject = sdv::core::GetObject<IHello>("TestObject_ComplexHelloService");
|
||||
// EXPECT_TRUE(pHelloObject);
|
||||
// if (pHelloObject) ss = pHelloObject->SayHello(sStages);
|
||||
// EXPECT_FALSE(ss.empty());
|
||||
// EXPECT_TRUE(sStages.bDevice);
|
||||
// EXPECT_TRUE(sStages.bBasicService);
|
||||
// EXPECT_TRUE(sStages.bComplexService);
|
||||
// EXPECT_TRUE(sStages.bSystemService);
|
||||
// EXPECT_TRUE(sStages.bUtility);
|
||||
// std::cout << "Basic service reports:" << std::endl << ss;
|
||||
|
||||
control.Shutdown();
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(AppConnect_UDS, ServerApp_Control_UnixDomainSockets)
|
||||
{
|
||||
// The lifetime of the server app is managed through a named mutex being available for locking. Lock the mutex
|
||||
ipc::named_mutex mtx("app_connect_test_mutex");
|
||||
std::unique_lock<ipc::named_mutex> lock(mtx);
|
||||
|
||||
// Use the process control class to manage the server process
|
||||
// Enable access bypass to allow its usage.
|
||||
CProcessControl procctrl;
|
||||
procctrl.EnableProcessControlAccessBypass();
|
||||
procctrl.Initialize(sdv::SObjectInfo());
|
||||
EXPECT_EQ(procctrl.GetObjectState(), sdv::EObjectState::initialized);
|
||||
|
||||
// Execute the server process
|
||||
sdv::process::TProcessID tServerID = procctrl.Execute(
|
||||
(GetExecDirectory() / "AppConnect_Server").generic_u8string(), {"199"}, sdv::process::EProcessRights::default_rights);
|
||||
EXPECT_NE(tServerID, 0u);
|
||||
|
||||
// Wait for 1 second
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||
|
||||
// Test for the running server
|
||||
EXPECT_FALSE(procctrl.WaitForTerminate(tServerID, 1));
|
||||
|
||||
// Release the mutex; this should shutdown the server
|
||||
lock.unlock();
|
||||
|
||||
// Wait for 1 second
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||
|
||||
// Test for the running server - should be terminated
|
||||
EXPECT_TRUE(procctrl.WaitForTerminate(tServerID, 10000));
|
||||
|
||||
// Just in case termination
|
||||
procctrl.Terminate(tServerID);
|
||||
|
||||
// End process control
|
||||
procctrl.Shutdown();
|
||||
}
|
||||
|
||||
TEST(AppConnect_UDS, ClientConnect_DefaultUnixDomainSockets)
|
||||
{
|
||||
// The lifetime of the server app is managed through a named mutex being available for locking. Lock the mutex
|
||||
ipc::named_mutex mtx("app_connect_test_mutex");
|
||||
std::unique_lock<ipc::named_mutex> lock(mtx);
|
||||
|
||||
// Use the process control class to manage the server process
|
||||
// Enable access bypass to allow its usage.
|
||||
CProcessControl procctrl;
|
||||
procctrl.EnableProcessControlAccessBypass();
|
||||
procctrl.Initialize(sdv::SObjectInfo());
|
||||
EXPECT_EQ(procctrl.GetObjectState(), sdv::EObjectState::initialized);
|
||||
|
||||
// Execute the server process
|
||||
sdv::process::TProcessID tServerID = procctrl.Execute(
|
||||
(GetExecDirectory() / "AppConnect_Server").generic_u8string(), {"199"}, sdv::process::EProcessRights::default_rights);
|
||||
EXPECT_NE(tServerID, 0u);
|
||||
|
||||
// Wait for 1 second
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||
|
||||
// Test for the running server
|
||||
EXPECT_FALSE(procctrl.WaitForTerminate(tServerID, 1));
|
||||
|
||||
// Start the second system using the default instance. This simulates a client
|
||||
sdv::app::CAppControl control;
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
// When startup succeeds an automatic connection to the server 199 should have been made.
|
||||
bool bResult = control.Startup(R"toml([Application]
|
||||
Mode = "Main"
|
||||
Instance = 201
|
||||
[Console]
|
||||
RedirectMon = true
|
||||
)toml");
|
||||
EXPECT_TRUE(bResult);
|
||||
|
||||
// Test utility - not allowed
|
||||
SStages sStages{};
|
||||
std::string ss;
|
||||
auto ptrUtilityHelloObject = sdv::core::CreateUtility("TestObject_HelloUtility");
|
||||
EXPECT_FALSE(ptrUtilityHelloObject);
|
||||
|
||||
// Test system object - not allowed BUT CURRENTLY WORKING
|
||||
sStages = {};
|
||||
ss.clear();
|
||||
auto pHelloObject = sdv::core::GetObject<IHello>("TestObject_SystemHelloService");
|
||||
EXPECT_TRUE(pHelloObject);
|
||||
if (pHelloObject)
|
||||
ss = pHelloObject->SayHello(sStages);
|
||||
EXPECT_FALSE(ss.empty());
|
||||
EXPECT_FALSE(sStages.bDevice);
|
||||
EXPECT_FALSE(sStages.bBasicService);
|
||||
EXPECT_FALSE(sStages.bComplexService);
|
||||
EXPECT_TRUE(sStages.bSystemService);
|
||||
EXPECT_FALSE(sStages.bUtility);
|
||||
std::cout << "System service reports:" << std::endl << ss;
|
||||
|
||||
//// Test device object - not allowed BUT CURRENTLY WORKING
|
||||
//sStages = {};
|
||||
//ss.clear();
|
||||
//pHelloObject = sdv::core::GetObject<IHello>("TestObject_HelloDevice");
|
||||
//EXPECT_TRUE(pHelloObject);
|
||||
//if (pHelloObject)
|
||||
// ss = pHelloObject->SayHello(sStages);
|
||||
//EXPECT_FALSE(ss.empty());
|
||||
//EXPECT_TRUE(sStages.bDevice);
|
||||
//EXPECT_FALSE(sStages.bBasicService);
|
||||
//EXPECT_FALSE(sStages.bComplexService);
|
||||
//EXPECT_TRUE(sStages.bSystemService);
|
||||
//EXPECT_TRUE(sStages.bUtility);
|
||||
//std::cout << "Device reports:" << std::endl << ss;
|
||||
|
||||
// Test basic service object - tries to executes SayHello on Device, Utility and System Service, but not allowed
|
||||
sStages = {};
|
||||
ss.clear();
|
||||
pHelloObject = sdv::core::GetObject<IHello>("TestObject_BasicHelloService");
|
||||
EXPECT_TRUE(pHelloObject);
|
||||
if (pHelloObject)
|
||||
ss = pHelloObject->SayHello(sStages);
|
||||
EXPECT_FALSE(ss.empty());
|
||||
EXPECT_FALSE(sStages.bDevice);
|
||||
EXPECT_TRUE(sStages.bBasicService);
|
||||
EXPECT_FALSE(sStages.bComplexService);
|
||||
EXPECT_FALSE(sStages.bSystemService);
|
||||
EXPECT_FALSE(sStages.bUtility);
|
||||
std::cout << "Basic service reports:" << std::endl << ss;
|
||||
|
||||
//// Test complex service object - executes SayHello on Complex Service, Device, Utility and System Service
|
||||
// sStages = {};
|
||||
// ss.clear();
|
||||
// pHelloObject = sdv::core::GetObject<IHello>("TestObject_ComplexHelloService");
|
||||
// EXPECT_TRUE(pHelloObject);
|
||||
// if (pHelloObject) ss = pHelloObject->SayHello(sStages);
|
||||
// EXPECT_FALSE(ss.empty());
|
||||
// EXPECT_TRUE(sStages.bDevice);
|
||||
// EXPECT_TRUE(sStages.bBasicService);
|
||||
// EXPECT_TRUE(sStages.bComplexService);
|
||||
// EXPECT_TRUE(sStages.bSystemService);
|
||||
// EXPECT_TRUE(sStages.bUtility);
|
||||
// std::cout << "Basic service reports:" << std::endl << ss;
|
||||
|
||||
control.Shutdown();
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
// Release the mutex; this should shutdown the server
|
||||
lock.unlock();
|
||||
|
||||
// Wait for 1 second
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||
|
||||
// Test for the running server - should be terminated
|
||||
EXPECT_TRUE(procctrl.WaitForTerminate(tServerID, 10000));
|
||||
|
||||
// Just in case termination
|
||||
procctrl.Terminate(tServerID);
|
||||
|
||||
// End process control
|
||||
procctrl.Shutdown();
|
||||
}
|
||||
|
||||
TEST(AppConnect_UDS, ClientConnect_PrivateUnixDomainSockets)
|
||||
{
|
||||
// The lifetime of the server app is managed through a named mutex being available for locking. Lock the mutex
|
||||
ipc::named_mutex mtx("app_connect_test_mutex");
|
||||
std::unique_lock<ipc::named_mutex> lock(mtx);
|
||||
|
||||
// Use the process control class to manage the server process
|
||||
// Enable access bypass to allow its usage.
|
||||
CProcessControl procctrl;
|
||||
procctrl.EnableProcessControlAccessBypass();
|
||||
procctrl.Initialize(sdv::SObjectInfo());
|
||||
EXPECT_EQ(procctrl.GetObjectState(), sdv::EObjectState::initialized);
|
||||
|
||||
// Execute the server process
|
||||
sdv::process::TProcessID tServerID = procctrl.Execute(
|
||||
(GetExecDirectory() / "AppConnect_Server").generic_u8string(), {"200"}, sdv::process::EProcessRights::default_rights);
|
||||
EXPECT_NE(tServerID, 0u);
|
||||
|
||||
// Wait for 1 second
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||
|
||||
// Test for the running server
|
||||
EXPECT_FALSE(procctrl.WaitForTerminate(tServerID, 1));
|
||||
|
||||
// Start the second system using the default instance. This simulates a client
|
||||
sdv::app::CAppControl control;
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
// When startup succeeds an automatic connection to the server 200 should have been made.
|
||||
bool bResult = control.Startup(R"toml([Application]
|
||||
Mode = "Main"
|
||||
Instance = 202
|
||||
[Console]
|
||||
RedirectMon = true
|
||||
)toml");
|
||||
EXPECT_TRUE(bResult);
|
||||
|
||||
// Test utility - not allowed
|
||||
SStages sStages{};
|
||||
std::string ss;
|
||||
auto ptrUtilityHelloObject = sdv::core::CreateUtility("TestObject_HelloUtility");
|
||||
EXPECT_FALSE(ptrUtilityHelloObject);
|
||||
|
||||
// Test system object - not allowed BUT CURRENTLY WORKING
|
||||
sStages = {};
|
||||
ss.clear();
|
||||
auto pHelloObject = sdv::core::GetObject<IHello>("TestObject_SystemHelloService");
|
||||
EXPECT_TRUE(pHelloObject);
|
||||
if (pHelloObject)
|
||||
ss = pHelloObject->SayHello(sStages);
|
||||
EXPECT_FALSE(ss.empty());
|
||||
EXPECT_FALSE(sStages.bDevice);
|
||||
EXPECT_FALSE(sStages.bBasicService);
|
||||
EXPECT_FALSE(sStages.bComplexService);
|
||||
EXPECT_TRUE(sStages.bSystemService);
|
||||
EXPECT_FALSE(sStages.bUtility);
|
||||
std::cout << "System service reports:" << std::endl << ss;
|
||||
|
||||
//// Test device object - not allowed BUT CURRENTLY WORKING
|
||||
//sStages = {};
|
||||
//ss.clear();
|
||||
//pHelloObject = sdv::core::GetObject<IHello>("TestObject_HelloDevice");
|
||||
//EXPECT_TRUE(pHelloObject);
|
||||
//if (pHelloObject)
|
||||
// ss = pHelloObject->SayHello(sStages);
|
||||
//EXPECT_FALSE(ss.empty());
|
||||
//EXPECT_TRUE(sStages.bDevice);
|
||||
//EXPECT_FALSE(sStages.bBasicService);
|
||||
//EXPECT_FALSE(sStages.bComplexService);
|
||||
//EXPECT_TRUE(sStages.bSystemService);
|
||||
//EXPECT_TRUE(sStages.bUtility);
|
||||
//std::cout << "Device reports:" << std::endl << ss;
|
||||
|
||||
// Test basic service object - tries to executes SayHello on Device, Utility and System Service, but not allowed
|
||||
sStages = {};
|
||||
ss.clear();
|
||||
pHelloObject = sdv::core::GetObject<IHello>("TestObject_BasicHelloService");
|
||||
EXPECT_TRUE(pHelloObject);
|
||||
if (pHelloObject)
|
||||
ss = pHelloObject->SayHello(sStages);
|
||||
EXPECT_FALSE(ss.empty());
|
||||
EXPECT_FALSE(sStages.bDevice);
|
||||
EXPECT_TRUE(sStages.bBasicService);
|
||||
EXPECT_FALSE(sStages.bComplexService);
|
||||
EXPECT_FALSE(sStages.bSystemService);
|
||||
EXPECT_FALSE(sStages.bUtility);
|
||||
std::cout << "Basic service reports:" << std::endl << ss;
|
||||
|
||||
//// Test complex service object - executes SayHello on Complex Service, Device, Utility and System Service
|
||||
// sStages = {};
|
||||
// ss.clear();
|
||||
// pHelloObject = sdv::core::GetObject<IHello>("TestObject_ComplexHelloService");
|
||||
// EXPECT_TRUE(pHelloObject);
|
||||
// if (pHelloObject) ss = pHelloObject->SayHello(sStages);
|
||||
// EXPECT_FALSE(ss.empty());
|
||||
// EXPECT_TRUE(sStages.bDevice);
|
||||
// EXPECT_TRUE(sStages.bBasicService);
|
||||
// EXPECT_TRUE(sStages.bComplexService);
|
||||
// EXPECT_TRUE(sStages.bSystemService);
|
||||
// EXPECT_TRUE(sStages.bUtility);
|
||||
// std::cout << "Basic service reports:" << std::endl << ss;
|
||||
|
||||
control.Shutdown();
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
// Release the mutex; this should shutdown the server
|
||||
lock.unlock();
|
||||
|
||||
// Wait for 1 second
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||
|
||||
// Test for the running server - should be terminated
|
||||
EXPECT_TRUE(procctrl.WaitForTerminate(tServerID, 10000));
|
||||
|
||||
// Just in case termination
|
||||
procctrl.Terminate(tServerID);
|
||||
|
||||
// End process control
|
||||
procctrl.Shutdown();
|
||||
}
|
||||
@@ -0,0 +1,557 @@
|
||||
/********************************************************************************
|
||||
* Copyright (c) 2065-2066 ZF Friedrichshafen AG
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Apache License Version 2.0 which is available at
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Denisa Ros - initial API and implementation
|
||||
********************************************************************************/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include "../../../sdv_services/process_control/process_control.h"
|
||||
#include "../../../global/ipc_named_mutex.h"
|
||||
#include "../../../global/exec_dir_helper.h"
|
||||
#include "generated/test_component.h"
|
||||
#include <interfaces/app.h>
|
||||
#include <support/app_control.h>
|
||||
#include <support/mem_access.h>
|
||||
#include <support/sdv_core.h>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
namespace
|
||||
{
|
||||
void ExpectConfiguredProvider(uint32_t instanceId, const std::string& configName, bool isListener, const std::string& expectedProvider)
|
||||
{
|
||||
auto* pConnections = sdv::core::GetObject<sdv::app::IAppConnections>("AppSettingsService");
|
||||
if (pConnections)
|
||||
{
|
||||
const sdv::u8string cfg = isListener ? pConnections->GetListenerConfig(configName)
|
||||
: pConnections->GetConnectionConfig(configName);
|
||||
ASSERT_FALSE(cfg.empty()) << "Missing IPC config '" << configName << "'";
|
||||
|
||||
const std::string cfgStr = cfg;
|
||||
EXPECT_NE(cfgStr.find("Name = \"" + expectedProvider + "\""), std::string::npos)
|
||||
<< "Unexpected provider config for '" << configName << "':\n" << cfgStr;
|
||||
return;
|
||||
}
|
||||
|
||||
// In main app mode this service is not guaranteed to be directly accessible via repository object lookup.
|
||||
// Fallback: validate the installed instance settings file where listener/connection definitions are persisted.
|
||||
std::filesystem::path installDir;
|
||||
if (const char* pInstall = std::getenv("SDV_COMPONENT_INSTALL"))
|
||||
installDir = pInstall;
|
||||
else
|
||||
installDir = (GetExecDirectory() / ".." / ".." / "bin").lexically_normal();
|
||||
|
||||
const auto settingsPath = installDir / std::to_string(instanceId) / "settings.toml";
|
||||
std::ifstream settingsStream(settingsPath);
|
||||
ASSERT_TRUE(settingsStream.is_open()) << "Cannot open settings file: " << settingsPath.generic_u8string();
|
||||
|
||||
std::stringstream buffer;
|
||||
buffer << settingsStream.rdbuf();
|
||||
const std::string content = buffer.str();
|
||||
|
||||
const std::string blockStart = isListener ? "[[Settings.Listener]]" : "[[Settings.Connection]]";
|
||||
const std::string providerSection = isListener ? "[Settings.Listener.Provider]" : "[Settings.Connection.Provider]";
|
||||
const std::string expectedName = "Name = \"" + configName + "\"";
|
||||
const std::string expectedProviderName = "Name = \"" + expectedProvider + "\"";
|
||||
|
||||
size_t pos = content.find(blockStart);
|
||||
while (pos != std::string::npos)
|
||||
{
|
||||
const size_t nextPos = content.find(blockStart, pos + blockStart.size());
|
||||
const std::string block = content.substr(pos, (nextPos == std::string::npos) ? std::string::npos : nextPos - pos);
|
||||
if (block.find(expectedName) != std::string::npos)
|
||||
{
|
||||
EXPECT_NE(block.find(providerSection), std::string::npos)
|
||||
<< "Missing provider section in config block for '" << configName << "'";
|
||||
EXPECT_NE(block.find(expectedProviderName), std::string::npos)
|
||||
<< "Unexpected provider in settings block for '" << configName << "':\n" << block;
|
||||
return;
|
||||
}
|
||||
pos = nextPos;
|
||||
}
|
||||
|
||||
FAIL() << "Missing IPC config block '" << configName << "' in " << settingsPath.generic_u8string();
|
||||
}
|
||||
} // namespace
|
||||
|
||||
|
||||
// The test use the following instance numbers (all configured as main application):
|
||||
// - instance 203 server without additional listener configured (channel: DEFAULT_CHANNEL_203)
|
||||
// - instance 204 server with additional listener configured (channels: private_channel_204_206)
|
||||
// - instance 205 client with 203-default connection configured (channel: DEFAULT_CHANNEL_203)
|
||||
// - instance 206 client with 204-special connection configured (channel: private_channel_204_206)
|
||||
TEST(AppConnect_UDS_Tunnel, ServerStart_DefaultUDS_Tunnel)
|
||||
{
|
||||
// The default instance
|
||||
sdv::app::CAppControl control;
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = control.Startup(R"toml([Application]
|
||||
Mode = "Main"
|
||||
Instance = 203
|
||||
[Console]
|
||||
RedirectMon = true
|
||||
)toml");
|
||||
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_TRUE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::main);
|
||||
EXPECT_EQ(control.GetInstanceID(), 203u);
|
||||
|
||||
// Test utility
|
||||
SStages sStages{};
|
||||
std::string ss;
|
||||
auto ptrUtilityHelloObject = sdv::core::CreateUtility("TestObject_HelloUtility");
|
||||
EXPECT_TRUE(ptrUtilityHelloObject);
|
||||
auto pHelloObject = ptrUtilityHelloObject.GetInterface<IHello>();
|
||||
EXPECT_TRUE(pHelloObject);
|
||||
if (pHelloObject)
|
||||
ss = pHelloObject->SayHello(sStages);
|
||||
EXPECT_FALSE(ss.empty());
|
||||
EXPECT_FALSE(sStages.bDevice);
|
||||
EXPECT_FALSE(sStages.bBasicService);
|
||||
EXPECT_FALSE(sStages.bComplexService);
|
||||
EXPECT_FALSE(sStages.bSystemService);
|
||||
EXPECT_TRUE(sStages.bUtility);
|
||||
std::cout << "Utility reports:" << std::endl << ss;
|
||||
|
||||
// Test system object
|
||||
sStages = {};
|
||||
ss.clear();
|
||||
pHelloObject = sdv::core::GetObject<IHello>("TestObject_SystemHelloService");
|
||||
EXPECT_TRUE(pHelloObject);
|
||||
if (pHelloObject)
|
||||
ss = pHelloObject->SayHello(sStages);
|
||||
EXPECT_FALSE(ss.empty());
|
||||
EXPECT_FALSE(sStages.bDevice);
|
||||
EXPECT_FALSE(sStages.bBasicService);
|
||||
EXPECT_FALSE(sStages.bComplexService);
|
||||
EXPECT_TRUE(sStages.bSystemService);
|
||||
EXPECT_FALSE(sStages.bUtility);
|
||||
std::cout << "System service reports:" << std::endl << ss;
|
||||
|
||||
// Test device object - executes SayHello on Utility and System Service
|
||||
sStages = {};
|
||||
ss.clear();
|
||||
pHelloObject = sdv::core::GetObject<IHello>("TestObject_HelloDevice");
|
||||
EXPECT_TRUE(pHelloObject);
|
||||
if (pHelloObject)
|
||||
ss = pHelloObject->SayHello(sStages);
|
||||
EXPECT_FALSE(ss.empty());
|
||||
EXPECT_TRUE(sStages.bDevice);
|
||||
EXPECT_FALSE(sStages.bBasicService);
|
||||
EXPECT_FALSE(sStages.bComplexService);
|
||||
EXPECT_TRUE(sStages.bSystemService);
|
||||
EXPECT_TRUE(sStages.bUtility);
|
||||
std::cout << "Device reports:" << std::endl << ss;
|
||||
|
||||
// Test basic service object - executes SayHello on Device, Utility and System Service
|
||||
sStages = {};
|
||||
ss.clear();
|
||||
pHelloObject = sdv::core::GetObject<IHello>("TestObject_BasicHelloService");
|
||||
EXPECT_TRUE(pHelloObject);
|
||||
if (pHelloObject)
|
||||
ss = pHelloObject->SayHello(sStages);
|
||||
EXPECT_FALSE(ss.empty());
|
||||
EXPECT_TRUE(sStages.bDevice);
|
||||
EXPECT_TRUE(sStages.bBasicService);
|
||||
EXPECT_FALSE(sStages.bComplexService);
|
||||
EXPECT_TRUE(sStages.bSystemService);
|
||||
EXPECT_TRUE(sStages.bUtility);
|
||||
std::cout << "Basic service reports:" << std::endl << ss;
|
||||
|
||||
control.Shutdown();
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(AppConnect_UDS_Tunnel, ServerStart_PrivateUDS_Tunnel)
|
||||
{
|
||||
// The default instance
|
||||
sdv::app::CAppControl control;
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = control.Startup(R"toml([Application]
|
||||
Mode = "Main"
|
||||
Instance = 204
|
||||
[Console]
|
||||
RedirectMon = true
|
||||
)toml");
|
||||
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_TRUE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::main);
|
||||
EXPECT_EQ(control.GetInstanceID(), 204u);
|
||||
ExpectConfiguredProvider(204u, "MySpecialListener", true, "unix_domain_sockets_tunnel");
|
||||
|
||||
// Test utility
|
||||
SStages sStages{};
|
||||
std::string ss;
|
||||
auto ptrUtilityHelloObject = sdv::core::CreateUtility("TestObject_HelloUtility");
|
||||
EXPECT_TRUE(ptrUtilityHelloObject);
|
||||
auto pHelloObject = ptrUtilityHelloObject.GetInterface<IHello>();
|
||||
EXPECT_TRUE(pHelloObject);
|
||||
if (pHelloObject)
|
||||
ss = pHelloObject->SayHello(sStages);
|
||||
EXPECT_FALSE(ss.empty());
|
||||
EXPECT_FALSE(sStages.bDevice);
|
||||
EXPECT_FALSE(sStages.bBasicService);
|
||||
EXPECT_FALSE(sStages.bComplexService);
|
||||
EXPECT_FALSE(sStages.bSystemService);
|
||||
EXPECT_TRUE(sStages.bUtility);
|
||||
std::cout << "Utility reports:" << std::endl << ss;
|
||||
|
||||
// Test system object
|
||||
sStages = {};
|
||||
ss.clear();
|
||||
pHelloObject = sdv::core::GetObject<IHello>("TestObject_SystemHelloService");
|
||||
EXPECT_TRUE(pHelloObject);
|
||||
if (pHelloObject)
|
||||
ss = pHelloObject->SayHello(sStages);
|
||||
EXPECT_FALSE(ss.empty());
|
||||
EXPECT_FALSE(sStages.bDevice);
|
||||
EXPECT_FALSE(sStages.bBasicService);
|
||||
EXPECT_FALSE(sStages.bComplexService);
|
||||
EXPECT_TRUE(sStages.bSystemService);
|
||||
EXPECT_FALSE(sStages.bUtility);
|
||||
std::cout << "System service reports:" << std::endl << ss;
|
||||
|
||||
// Test device object - executes SayHello on Utility and System Service
|
||||
sStages = {};
|
||||
ss.clear();
|
||||
pHelloObject = sdv::core::GetObject<IHello>("TestObject_HelloDevice");
|
||||
EXPECT_TRUE(pHelloObject);
|
||||
if (pHelloObject)
|
||||
ss = pHelloObject->SayHello(sStages);
|
||||
EXPECT_FALSE(ss.empty());
|
||||
EXPECT_TRUE(sStages.bDevice);
|
||||
EXPECT_FALSE(sStages.bBasicService);
|
||||
EXPECT_FALSE(sStages.bComplexService);
|
||||
EXPECT_TRUE(sStages.bSystemService);
|
||||
EXPECT_TRUE(sStages.bUtility);
|
||||
std::cout << "Device reports:" << std::endl << ss;
|
||||
|
||||
// Test basic service object - executes SayHello on Device, Utility and System Service
|
||||
sStages = {};
|
||||
ss.clear();
|
||||
pHelloObject = sdv::core::GetObject<IHello>("TestObject_BasicHelloService");
|
||||
EXPECT_TRUE(pHelloObject);
|
||||
if (pHelloObject)
|
||||
ss = pHelloObject->SayHello(sStages);
|
||||
EXPECT_FALSE(ss.empty());
|
||||
EXPECT_TRUE(sStages.bDevice);
|
||||
EXPECT_TRUE(sStages.bBasicService);
|
||||
EXPECT_FALSE(sStages.bComplexService);
|
||||
EXPECT_TRUE(sStages.bSystemService);
|
||||
EXPECT_TRUE(sStages.bUtility);
|
||||
std::cout << "Basic service reports:" << std::endl << ss;
|
||||
|
||||
//// Test complex service object - executes SayHello on Complex Service, Device, Utility and System Service
|
||||
// sStages = {};
|
||||
// ss.clear();
|
||||
// pHelloObject = sdv::core::GetObject<IHello>("TestObject_ComplexHelloService");
|
||||
// EXPECT_TRUE(pHelloObject);
|
||||
// if (pHelloObject) ss = pHelloObject->SayHello(sStages);
|
||||
// EXPECT_FALSE(ss.empty());
|
||||
// EXPECT_TRUE(sStages.bDevice);
|
||||
// EXPECT_TRUE(sStages.bBasicService);
|
||||
// EXPECT_TRUE(sStages.bComplexService);
|
||||
// EXPECT_TRUE(sStages.bSystemService);
|
||||
// EXPECT_TRUE(sStages.bUtility);
|
||||
// std::cout << "Basic service reports:" << std::endl << ss;
|
||||
|
||||
control.Shutdown();
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(AppConnect_UDS_Tunnel, ServerApp_Control_UDS_Tunnel)
|
||||
{
|
||||
// The lifetime of the server app is managed through a named mutex being available for locking. Lock the mutex
|
||||
ipc::named_mutex mtx("app_connect_tunnel_test_mutex");
|
||||
std::unique_lock<ipc::named_mutex> lock(mtx);
|
||||
|
||||
// Use the process control class to manage the server process
|
||||
// Enable access bypass to allow its usage.
|
||||
CProcessControl procctrl;
|
||||
procctrl.EnableProcessControlAccessBypass();
|
||||
procctrl.Initialize(sdv::SObjectInfo());
|
||||
EXPECT_EQ(procctrl.GetObjectState(), sdv::EObjectState::initialized);
|
||||
|
||||
// Execute the server process
|
||||
sdv::process::TProcessID tServerID = procctrl.Execute(
|
||||
(GetExecDirectory() / "AppConnect_Server").generic_u8string(), {"203"}, sdv::process::EProcessRights::default_rights);
|
||||
EXPECT_NE(tServerID, 0u);
|
||||
|
||||
// Wait for 1 second
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||
|
||||
// Test for the running server
|
||||
EXPECT_FALSE(procctrl.WaitForTerminate(tServerID, 1));
|
||||
|
||||
// Release the mutex; this should shutdown the server
|
||||
lock.unlock();
|
||||
|
||||
// Wait for 1 second
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||
|
||||
// Test for the running server - should be terminated
|
||||
EXPECT_TRUE(procctrl.WaitForTerminate(tServerID, 10000));
|
||||
|
||||
// Just in case termination
|
||||
procctrl.Terminate(tServerID);
|
||||
|
||||
// End process control
|
||||
procctrl.Shutdown();
|
||||
}
|
||||
|
||||
TEST(AppConnect_UDS_Tunnel, ClientConnect_DefaultUDS_Tunnel)
|
||||
{
|
||||
// The lifetime of the server app is managed through a named mutex being available for locking. Lock the mutex
|
||||
ipc::named_mutex mtx("app_connect_tunnel_test_mutex");
|
||||
std::unique_lock<ipc::named_mutex> lock(mtx);
|
||||
|
||||
// Use the process control class to manage the server process
|
||||
// Enable access bypass to allow its usage.
|
||||
CProcessControl procctrl;
|
||||
procctrl.EnableProcessControlAccessBypass();
|
||||
procctrl.Initialize(sdv::SObjectInfo());
|
||||
EXPECT_EQ(procctrl.GetObjectState(), sdv::EObjectState::initialized);
|
||||
|
||||
// Execute the server process
|
||||
sdv::process::TProcessID tServerID = procctrl.Execute(
|
||||
(GetExecDirectory() / "AppConnect_Server").generic_u8string(), {"203"}, sdv::process::EProcessRights::default_rights);
|
||||
EXPECT_NE(tServerID, 0u);
|
||||
|
||||
// Wait for 1 second
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||
|
||||
// Test for the running server
|
||||
EXPECT_FALSE(procctrl.WaitForTerminate(tServerID, 1));
|
||||
|
||||
// Start the second system using the default instance. This simulates a client
|
||||
sdv::app::CAppControl control;
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
// When startup succeeds an automatic connection to the server 203 should have been made.
|
||||
bool bResult = control.Startup(R"toml([Application]
|
||||
Mode = "Main"
|
||||
Instance = 205
|
||||
[Console]
|
||||
RedirectMon = true
|
||||
)toml");
|
||||
EXPECT_TRUE(bResult);
|
||||
ExpectConfiguredProvider(205u, "DefaultChannelTo203", false, "unix_domain_sockets_tunnel");
|
||||
|
||||
// Test utility - not allowed
|
||||
SStages sStages{};
|
||||
std::string ss;
|
||||
auto ptrUtilityHelloObject = sdv::core::CreateUtility("TestObject_HelloUtility");
|
||||
EXPECT_FALSE(ptrUtilityHelloObject);
|
||||
|
||||
// Test system object - not allowed BUT CURRENTLY WORKING
|
||||
sStages = {};
|
||||
ss.clear();
|
||||
auto pHelloObject = sdv::core::GetObject<IHello>("TestObject_SystemHelloService");
|
||||
EXPECT_TRUE(pHelloObject);
|
||||
if (pHelloObject)
|
||||
ss = pHelloObject->SayHello(sStages);
|
||||
EXPECT_FALSE(ss.empty());
|
||||
EXPECT_FALSE(sStages.bDevice);
|
||||
EXPECT_FALSE(sStages.bBasicService);
|
||||
EXPECT_FALSE(sStages.bComplexService);
|
||||
EXPECT_TRUE(sStages.bSystemService);
|
||||
EXPECT_FALSE(sStages.bUtility);
|
||||
std::cout << "System service reports:" << std::endl << ss;
|
||||
|
||||
//// Test device object - not allowed BUT CURRENTLY WORKING
|
||||
//sStages = {};
|
||||
//ss.clear();
|
||||
//pHelloObject = sdv::core::GetObject<IHello>("TestObject_HelloDevice");
|
||||
//EXPECT_TRUE(pHelloObject);
|
||||
//if (pHelloObject)
|
||||
// ss = pHelloObject->SayHello(sStages);
|
||||
//EXPECT_FALSE(ss.empty());
|
||||
//EXPECT_TRUE(sStages.bDevice);
|
||||
//EXPECT_FALSE(sStages.bBasicService);
|
||||
//EXPECT_FALSE(sStages.bComplexService);
|
||||
//EXPECT_TRUE(sStages.bSystemService);
|
||||
//EXPECT_TRUE(sStages.bUtility);
|
||||
//std::cout << "Device reports:" << std::endl << ss;
|
||||
|
||||
// Test basic service object - tries to executes SayHello on Device, Utility and System Service, but not allowed
|
||||
sStages = {};
|
||||
ss.clear();
|
||||
pHelloObject = sdv::core::GetObject<IHello>("TestObject_BasicHelloService");
|
||||
EXPECT_TRUE(pHelloObject);
|
||||
if (pHelloObject)
|
||||
ss = pHelloObject->SayHello(sStages);
|
||||
EXPECT_FALSE(ss.empty());
|
||||
EXPECT_FALSE(sStages.bDevice);
|
||||
EXPECT_TRUE(sStages.bBasicService);
|
||||
EXPECT_FALSE(sStages.bComplexService);
|
||||
EXPECT_FALSE(sStages.bSystemService);
|
||||
EXPECT_FALSE(sStages.bUtility);
|
||||
std::cout << "Basic service reports:" << std::endl << ss;
|
||||
|
||||
control.Shutdown();
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
// Release the mutex; this should shutdown the server
|
||||
lock.unlock();
|
||||
|
||||
// Wait for 1 second
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||
|
||||
// Test for the running server - should be terminated
|
||||
EXPECT_TRUE(procctrl.WaitForTerminate(tServerID, 10000));
|
||||
|
||||
// Just in case termination
|
||||
procctrl.Terminate(tServerID);
|
||||
|
||||
// End process control
|
||||
procctrl.Shutdown();
|
||||
}
|
||||
|
||||
TEST(AppConnect_UDS_Tunnel, ClientConnect_PrivateUDS_Tunnel)
|
||||
{
|
||||
// The lifetime of the server app is managed through a named mutex being available for locking. Lock the mutex
|
||||
ipc::named_mutex mtx("app_connect_tunnel_test_mutex");
|
||||
std::unique_lock<ipc::named_mutex> lock(mtx);
|
||||
|
||||
// Use the process control class to manage the server process
|
||||
// Enable access bypass to allow its usage.
|
||||
CProcessControl procctrl;
|
||||
procctrl.EnableProcessControlAccessBypass();
|
||||
procctrl.Initialize(sdv::SObjectInfo());
|
||||
EXPECT_EQ(procctrl.GetObjectState(), sdv::EObjectState::initialized);
|
||||
|
||||
// Execute the server process
|
||||
sdv::process::TProcessID tServerID = procctrl.Execute(
|
||||
(GetExecDirectory() / "AppConnect_Server").generic_u8string(), {"204"}, sdv::process::EProcessRights::default_rights);
|
||||
EXPECT_NE(tServerID, 0u);
|
||||
|
||||
// Wait for 1 second
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||
|
||||
// Test for the running server
|
||||
EXPECT_FALSE(procctrl.WaitForTerminate(tServerID, 1));
|
||||
|
||||
// Start the second system using the default instance. This simulates a client
|
||||
sdv::app::CAppControl control;
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
// When startup succeeds an automatic connection to the server 204 should have been made.
|
||||
bool bResult = control.Startup(R"toml([Application]
|
||||
Mode = "Main"
|
||||
Instance = 206
|
||||
[Console]
|
||||
RedirectMon = true
|
||||
)toml");
|
||||
EXPECT_TRUE(bResult);
|
||||
ExpectConfiguredProvider(206u, "MySpecialConnection", false, "unix_domain_sockets_tunnel");
|
||||
|
||||
// Test utility - not allowed
|
||||
SStages sStages{};
|
||||
std::string ss;
|
||||
auto ptrUtilityHelloObject = sdv::core::CreateUtility("TestObject_HelloUtility");
|
||||
EXPECT_FALSE(ptrUtilityHelloObject);
|
||||
|
||||
// Test system object - not allowed BUT CURRENTLY WORKING
|
||||
sStages = {};
|
||||
ss.clear();
|
||||
auto pHelloObject = sdv::core::GetObject<IHello>("TestObject_SystemHelloService");
|
||||
EXPECT_TRUE(pHelloObject);
|
||||
if (pHelloObject)
|
||||
ss = pHelloObject->SayHello(sStages);
|
||||
EXPECT_FALSE(ss.empty());
|
||||
EXPECT_FALSE(sStages.bDevice);
|
||||
EXPECT_FALSE(sStages.bBasicService);
|
||||
EXPECT_FALSE(sStages.bComplexService);
|
||||
EXPECT_TRUE(sStages.bSystemService);
|
||||
EXPECT_FALSE(sStages.bUtility);
|
||||
std::cout << "System service reports:" << std::endl << ss;
|
||||
|
||||
//// Test device object - not allowed BUT CURRENTLY WORKING
|
||||
//sStages = {};
|
||||
//ss.clear();
|
||||
//pHelloObject = sdv::core::GetObject<IHello>("TestObject_HelloDevice");
|
||||
//EXPECT_TRUE(pHelloObject);
|
||||
//if (pHelloObject)
|
||||
// ss = pHelloObject->SayHello(sStages);
|
||||
//EXPECT_FALSE(ss.empty());
|
||||
//EXPECT_TRUE(sStages.bDevice);
|
||||
//EXPECT_FALSE(sStages.bBasicService);
|
||||
//EXPECT_FALSE(sStages.bComplexService);
|
||||
//EXPECT_TRUE(sStages.bSystemService);
|
||||
//EXPECT_TRUE(sStages.bUtility);
|
||||
//std::cout << "Device reports:" << std::endl << ss;
|
||||
|
||||
// Test basic service object - tries to executes SayHello on Device, Utility and System Service, but not allowed
|
||||
sStages = {};
|
||||
ss.clear();
|
||||
pHelloObject = sdv::core::GetObject<IHello>("TestObject_BasicHelloService");
|
||||
EXPECT_TRUE(pHelloObject);
|
||||
if (pHelloObject)
|
||||
ss = pHelloObject->SayHello(sStages);
|
||||
EXPECT_FALSE(ss.empty());
|
||||
EXPECT_FALSE(sStages.bDevice);
|
||||
EXPECT_TRUE(sStages.bBasicService);
|
||||
EXPECT_FALSE(sStages.bComplexService);
|
||||
EXPECT_FALSE(sStages.bSystemService);
|
||||
EXPECT_FALSE(sStages.bUtility);
|
||||
std::cout << "Basic service reports:" << std::endl << ss;
|
||||
|
||||
//// Test complex service object - executes SayHello on Complex Service, Device, Utility and System Service
|
||||
// sStages = {};
|
||||
// ss.clear();
|
||||
// pHelloObject = sdv::core::GetObject<IHello>("TestObject_ComplexHelloService");
|
||||
// EXPECT_TRUE(pHelloObject);
|
||||
// if (pHelloObject) ss = pHelloObject->SayHello(sStages);
|
||||
// EXPECT_FALSE(ss.empty());
|
||||
// EXPECT_TRUE(sStages.bDevice);
|
||||
// EXPECT_TRUE(sStages.bBasicService);
|
||||
// EXPECT_TRUE(sStages.bComplexService);
|
||||
// EXPECT_TRUE(sStages.bSystemService);
|
||||
// EXPECT_TRUE(sStages.bUtility);
|
||||
// std::cout << "Basic service reports:" << std::endl << ss;
|
||||
|
||||
control.Shutdown();
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
// Release the mutex; this should shutdown the server
|
||||
lock.unlock();
|
||||
|
||||
// Wait for 1 second
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||
|
||||
// Test for the running server - should be terminated
|
||||
EXPECT_TRUE(procctrl.WaitForTerminate(tServerID, 10000));
|
||||
|
||||
// Just in case termination
|
||||
procctrl.Terminate(tServerID);
|
||||
|
||||
// End process control
|
||||
procctrl.Shutdown();
|
||||
}
|
||||
31
tests/component_tests/app_connect/main.cpp
Normal file
31
tests/component_tests/app_connect/main.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
/********************************************************************************
|
||||
* Copyright (c) 2025-2026 ZF Friedrichshafen AG
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Apache License Version 2.0 which is available at
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Erik Verhoeven - initial API and implementation
|
||||
********************************************************************************/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include "../../../global/process_watchdog.h"
|
||||
#include "../../../sdv_services/process_control/process_control.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();
|
||||
}
|
||||
99
tests/component_tests/app_connect/main_server.cpp
Normal file
99
tests/component_tests/app_connect/main_server.cpp
Normal file
@@ -0,0 +1,99 @@
|
||||
/********************************************************************************
|
||||
* Copyright (c) 2025-2026 ZF Friedrichshafen AG
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Apache License Version 2.0 which is available at
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Erik Verhoeven - initial API and implementation
|
||||
********************************************************************************/
|
||||
|
||||
#include "../../../global/process_watchdog.h"
|
||||
#include "../../../global/ipc_named_mutex.h"
|
||||
#include <atomic>
|
||||
#include <interfaces/ipc.h>
|
||||
#include <support/sdv_core.h>
|
||||
#include <support/app_control.h>
|
||||
|
||||
/**
|
||||
* @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;
|
||||
|
||||
// Workaround for GCC to make certain that POSIX thread library is loaded before the components are loaded.
|
||||
// REASON: If the first call to a thread is done in a dynamic library, the application is already classified as single
|
||||
// threaded and a termination is initiated.
|
||||
// See: https://stackoverflow.com/questions/51209268/using-stdthread-in-a-library-loaded-with-dlopen-leads-to-a-sigsev
|
||||
// NOTE EVE 27.05.2025: in release builds, starting and ending the thread right after each other causes incorrect behavior and
|
||||
// leads in some cases to create a deadlock in the join-function. The solution is to add delays in the thread processing.
|
||||
std::atomic_bool bThreadStarted = false;
|
||||
std::thread thread = std::thread(
|
||||
[&]()
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
bThreadStarted = true;
|
||||
});
|
||||
while (!bThreadStarted)
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
}
|
||||
if (thread.joinable())
|
||||
thread.join();
|
||||
|
||||
std::cout << "RuntimeDirectory = " << sdv::app::CAppControl::GetFrameworkRuntimeDirectory().generic_u8string() << std::endl;
|
||||
std::cout << "InstallDirectory = " << sdv::app::CAppControl::GetComponentInstallDirectory().generic_u8string() << std::endl;
|
||||
|
||||
std::cout << "Connect test application" << std::endl;
|
||||
std::cout << "Copyright (C): 2026 ZF Friedrichshafen AG" << std::endl;
|
||||
std::cout << "Author: Erik Verhoeven" << std::endl << std::endl;
|
||||
|
||||
// Get the instance number from the command line.
|
||||
if (argc != 2)
|
||||
{
|
||||
std::cout << "Missing argument; usage: AppConnect_Client <instance_number>" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
#if defined(_WIN32) && defined(_UNICODE)
|
||||
size_t nInstance = wcstoul(argv[1], nullptr, 10);
|
||||
#else
|
||||
size_t nInstance = atoi(argv[1]);
|
||||
#endif
|
||||
std::cout << "Listening for connections on instance #" << nInstance << std::endl;
|
||||
|
||||
sdv::app::CAppControl control;
|
||||
bool bResult = control.Startup(R"toml([Application]
|
||||
Mode = "Main"
|
||||
Instance = )toml" + std::to_string(nInstance));
|
||||
if (!bResult)
|
||||
{
|
||||
std::cout << "Failed to start system..." << std::endl;
|
||||
return -2;
|
||||
}
|
||||
|
||||
// Lifetime of the server is managed by the locking of a named mutex. As long as locking doesn't work, the server should run.
|
||||
// Test every 250ms
|
||||
ipc::named_mutex mtx("app_connect_test_mutex");
|
||||
bool bRunning = true;
|
||||
while (bRunning)
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||
if (mtx.try_lock())
|
||||
{
|
||||
bRunning = false;
|
||||
mtx.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
control.Shutdown();
|
||||
std::cout << "Connect test application terminated... (instance #" << nInstance << ")" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
46
tests/component_tests/app_connect/test_component.idl
Normal file
46
tests/component_tests/app_connect/test_component.idl
Normal file
@@ -0,0 +1,46 @@
|
||||
/********************************************************************************
|
||||
* Copyright (c) 2025-2026 ZF Friedrichshafen AG
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Apache License Version 2.0 which is available at
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Erik Verhoeven - initial API and implementation
|
||||
********************************************************************************/
|
||||
|
||||
#include <interfaces/core.idl>
|
||||
#include <interfaces/process.idl>
|
||||
|
||||
/**
|
||||
* @brief Stages the call might go through.
|
||||
*/
|
||||
struct SStages
|
||||
{
|
||||
boolean bDevice;
|
||||
boolean bBasicService;
|
||||
boolean bComplexService;
|
||||
boolean bSystemService;
|
||||
boolean bUtility;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Hello interface
|
||||
*/
|
||||
interface IHello
|
||||
{
|
||||
/**
|
||||
* @brief Say hello
|
||||
* @param[in, out] sStages The struct stages will be filled by the components. The complex service calls the basic service. The
|
||||
* basic service calls the device. The device calls the system service and the utility.
|
||||
* @return The greetings string.
|
||||
*/
|
||||
u8string SayHello(inout SStages sStages) const;
|
||||
|
||||
/**
|
||||
* @brief Get the PID of the process the component is running in...
|
||||
*/
|
||||
sdv::process::TProcessID GetPID() const;
|
||||
};
|
||||
@@ -0,0 +1,72 @@
|
||||
/********************************************************************************
|
||||
* Copyright (c) 2025-2026 ZF Friedrichshafen AG
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Apache License Version 2.0 which is available at
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Erik Verhoeven - initial API and implementation
|
||||
********************************************************************************/
|
||||
|
||||
#include <mutex>
|
||||
#include <iostream>
|
||||
#include <functional>
|
||||
#include <thread>
|
||||
#include <support/component_impl.h>
|
||||
#include <support/local_service_access.h>
|
||||
#include "generated/test_component.h"
|
||||
|
||||
inline sdv::process::TProcessID GetProcessID()
|
||||
{
|
||||
static sdv::process::TProcessID tProcessID = 0;
|
||||
if (!tProcessID)
|
||||
{
|
||||
sdv::process::IProcessInfo* pProcessInfo = sdv::core::GetObject<sdv::process::IProcessInfo>("ProcessControlService");
|
||||
if (!pProcessInfo) return 0;
|
||||
tProcessID = pProcessInfo->GetProcessID();
|
||||
}
|
||||
return tProcessID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Basic hello service
|
||||
*/
|
||||
class CBasicHelloService : public sdv::CSdvObject, public IHello
|
||||
{
|
||||
public:
|
||||
|
||||
BEGIN_SDV_INTERFACE_MAP()
|
||||
SDV_INTERFACE_ENTRY(IHello)
|
||||
END_SDV_INTERFACE_MAP()
|
||||
|
||||
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::basic_service)
|
||||
DECLARE_OBJECT_CLASS_NAME("TestObject_BasicHelloService")
|
||||
|
||||
/**
|
||||
* @brief Say hello. Overload of IHello::SayHello.
|
||||
* @param[in, out] sStages The struct stages will be filled by the components. The complex service calls the basic service. The
|
||||
* basic service calls the device. The device calls the system service and the utility.
|
||||
* @return The greetings string.
|
||||
*/
|
||||
virtual sdv::u8string SayHello(/*inout*/ SStages& sStages) const override
|
||||
{
|
||||
sStages.bBasicService = true;
|
||||
|
||||
// Request for the device
|
||||
auto pHelloObject = sdv::core::GetObject<IHello>("TestObject_HelloDevice");
|
||||
return "PID#" + std::to_string(GetPID()) + " Hello from basic service\n"
|
||||
+ std::string(pHelloObject ? pHelloObject->SayHello(sStages) : "");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the PID of the process the component is running in... Overload of IHello::GetPID.
|
||||
*/
|
||||
sdv::process::TProcessID GetPID() const
|
||||
{
|
||||
return GetProcessID();
|
||||
}
|
||||
};
|
||||
DEFINE_SDV_OBJECT(CBasicHelloService)
|
||||
@@ -0,0 +1,81 @@
|
||||
/********************************************************************************
|
||||
* Copyright (c) 2025-2026 ZF Friedrichshafen AG
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Apache License Version 2.0 which is available at
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Erik Verhoeven - initial API and implementation
|
||||
********************************************************************************/
|
||||
|
||||
#include <mutex>
|
||||
#include <iostream>
|
||||
#include <functional>
|
||||
#include <thread>
|
||||
#include <support/component_impl.h>
|
||||
#include <support/local_service_access.h>
|
||||
#include "generated/test_component.h"
|
||||
|
||||
inline sdv::process::TProcessID GetProcessID()
|
||||
{
|
||||
static sdv::process::TProcessID tProcessID = 0;
|
||||
if (!tProcessID)
|
||||
{
|
||||
sdv::process::IProcessInfo* pProcessInfo = sdv::core::GetObject<sdv::process::IProcessInfo>("ProcessControlService");
|
||||
if (!pProcessInfo) return 0;
|
||||
tProcessID = pProcessInfo->GetProcessID();
|
||||
}
|
||||
return tProcessID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Complex hello service
|
||||
*/
|
||||
class CComplexHelloService : public sdv::CSdvObject, public IHello
|
||||
{
|
||||
public:
|
||||
CComplexHelloService()
|
||||
{
|
||||
std::cout << "CComplexHelloService constructor" << std::endl;
|
||||
}
|
||||
~CComplexHelloService()
|
||||
{
|
||||
std::cout << "CComplexHelloService destructor" << std::endl;
|
||||
}
|
||||
|
||||
BEGIN_SDV_INTERFACE_MAP()
|
||||
SDV_INTERFACE_ENTRY(IHello)
|
||||
END_SDV_INTERFACE_MAP()
|
||||
|
||||
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::complex_service)
|
||||
DECLARE_OBJECT_CLASS_NAME("TestObject_ComplexHelloService")
|
||||
|
||||
/**
|
||||
* @brief Say hello. Overload of IHello::SayHello.
|
||||
* @param[in, out] sStages The struct stages will be filled by the components. The complex service calls the basic service. The
|
||||
* basic service calls the device. The device calls the system service and the utility.
|
||||
* @return The greetings string.
|
||||
*/
|
||||
virtual sdv::u8string SayHello(/*inout*/ SStages& sStages) const override
|
||||
{
|
||||
sStages.bComplexService = true;
|
||||
|
||||
// Request for the basic server
|
||||
auto pHelloObject = sdv::core::GetObject<IHello>("TestObject_BasicHelloService");
|
||||
return "PID#" + std::to_string(GetPID()) + " Hello from complex service\n" +
|
||||
std::string(pHelloObject ? pHelloObject->SayHello(sStages) : "");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the PID of the process the component is running in... Overload of IHello::GetPID.
|
||||
*/
|
||||
sdv::process::TProcessID GetPID() const
|
||||
{
|
||||
return GetProcessID();
|
||||
}
|
||||
};
|
||||
DEFINE_SDV_OBJECT(CComplexHelloService)
|
||||
|
||||
76
tests/component_tests/app_connect/test_component_device.cpp
Normal file
76
tests/component_tests/app_connect/test_component_device.cpp
Normal file
@@ -0,0 +1,76 @@
|
||||
/********************************************************************************
|
||||
* Copyright (c) 2025-2026 ZF Friedrichshafen AG
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Apache License Version 2.0 which is available at
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Erik Verhoeven - initial API and implementation
|
||||
********************************************************************************/
|
||||
|
||||
#include <mutex>
|
||||
#include <iostream>
|
||||
#include <functional>
|
||||
#include <thread>
|
||||
#include <support/component_impl.h>
|
||||
#include <support/local_service_access.h>
|
||||
#include "generated/test_component.h"
|
||||
|
||||
inline sdv::process::TProcessID GetProcessID()
|
||||
{
|
||||
static sdv::process::TProcessID tProcessID = 0;
|
||||
if (!tProcessID)
|
||||
{
|
||||
sdv::process::IProcessInfo* pProcessInfo = sdv::core::GetObject<sdv::process::IProcessInfo>("ProcessControlService");
|
||||
if (!pProcessInfo) return 0;
|
||||
tProcessID = pProcessInfo->GetProcessID();
|
||||
}
|
||||
return tProcessID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Hello device
|
||||
*/
|
||||
class CHelloDevice : public sdv::CSdvObject, public IHello
|
||||
{
|
||||
public:
|
||||
|
||||
BEGIN_SDV_INTERFACE_MAP()
|
||||
SDV_INTERFACE_ENTRY(IHello)
|
||||
END_SDV_INTERFACE_MAP()
|
||||
|
||||
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::device)
|
||||
DECLARE_OBJECT_CLASS_NAME("TestObject_HelloDevice")
|
||||
|
||||
/**
|
||||
* @brief Say hello. Overload of IHello::SayHello.
|
||||
* @param[in, out] sStages The struct stages will be filled by the components. The complex service calls the basic service. The
|
||||
* basic service calls the device. The device calls the system service and the utility.
|
||||
* @return The greetings string.
|
||||
*/
|
||||
virtual sdv::u8string SayHello(/*inout*/ SStages& sStages) const override
|
||||
{
|
||||
sStages.bDevice = true;
|
||||
|
||||
// Request for the system service
|
||||
auto pSystemHelloObject = sdv::core::GetObject<IHello>("TestObject_SystemHelloService");
|
||||
auto ptrUtilityHelloObject = sdv::core::CreateUtility("TestObject_HelloUtility");
|
||||
auto pUtilityHelloObject = ptrUtilityHelloObject.GetInterface<IHello>();
|
||||
return "PID#" + std::to_string(GetPID()) + " Hello from device\n" +
|
||||
std::string(pSystemHelloObject ? pSystemHelloObject->SayHello(sStages) : "") +
|
||||
std::string(pUtilityHelloObject ? pUtilityHelloObject->SayHello(sStages) : "");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the PID of the process the component is running in... Overload of IHello::GetPID.
|
||||
*/
|
||||
sdv::process::TProcessID GetPID() const
|
||||
{
|
||||
return GetProcessID();
|
||||
}
|
||||
};
|
||||
DEFINE_SDV_OBJECT(CHelloDevice)
|
||||
|
||||
14
tests/component_tests/app_connect/test_component_ps.cpp
Normal file
14
tests/component_tests/app_connect/test_component_ps.cpp
Normal file
@@ -0,0 +1,14 @@
|
||||
/********************************************************************************
|
||||
* Copyright (c) 2025-2026 ZF Friedrichshafen AG
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Apache License Version 2.0 which is available at
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Erik Verhoeven - initial API and implementation
|
||||
********************************************************************************/
|
||||
|
||||
#include "generated/ps/proxystub.cpp"
|
||||
@@ -0,0 +1,69 @@
|
||||
/********************************************************************************
|
||||
* Copyright (c) 2025-2026 ZF Friedrichshafen AG
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Apache License Version 2.0 which is available at
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Erik Verhoeven - initial API and implementation
|
||||
********************************************************************************/
|
||||
|
||||
#include <mutex>
|
||||
#include <iostream>
|
||||
#include <functional>
|
||||
#include <thread>
|
||||
#include <support/component_impl.h>
|
||||
#include <support/local_service_access.h>
|
||||
#include "generated/test_component.h"
|
||||
|
||||
inline sdv::process::TProcessID GetProcessID()
|
||||
{
|
||||
static sdv::process::TProcessID tProcessID = 0;
|
||||
if (!tProcessID)
|
||||
{
|
||||
sdv::process::IProcessInfo* pProcessInfo = sdv::core::GetObject<sdv::process::IProcessInfo>("ProcessControlService");
|
||||
if (!pProcessInfo) return 0;
|
||||
tProcessID = pProcessInfo->GetProcessID();
|
||||
}
|
||||
return tProcessID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Hello utlity
|
||||
*/
|
||||
class CSystemHelloService : public sdv::CSdvObject, public IHello
|
||||
{
|
||||
public:
|
||||
|
||||
BEGIN_SDV_INTERFACE_MAP()
|
||||
SDV_INTERFACE_ENTRY(IHello)
|
||||
END_SDV_INTERFACE_MAP()
|
||||
|
||||
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::system_object)
|
||||
DECLARE_OBJECT_CLASS_NAME("TestObject_SystemHelloService")
|
||||
|
||||
/**
|
||||
* @brief Say hello. Overload of IHello::SayHello.
|
||||
* @param[in, out] sStages The struct stages will be filled by the components. The complex service calls the basic service. The
|
||||
* basic service calls the device. The device calls the system service and the utility.
|
||||
* @return The greetings string.
|
||||
*/
|
||||
virtual sdv::u8string SayHello(/*inout*/ SStages& sStages) const override
|
||||
{
|
||||
sStages.bSystemService = true;
|
||||
|
||||
return "PID#" + std::to_string(GetPID()) + " Hello from system service\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the PID of the process the component is running in... Overload of IHello::GetPID.
|
||||
*/
|
||||
sdv::process::TProcessID GetPID() const
|
||||
{
|
||||
return GetProcessID();
|
||||
}
|
||||
};
|
||||
DEFINE_SDV_OBJECT(CSystemHelloService)
|
||||
70
tests/component_tests/app_connect/test_component_utility.cpp
Normal file
70
tests/component_tests/app_connect/test_component_utility.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
/********************************************************************************
|
||||
* Copyright (c) 2025-2026 ZF Friedrichshafen AG
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Apache License Version 2.0 which is available at
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Erik Verhoeven - initial API and implementation
|
||||
********************************************************************************/
|
||||
|
||||
#include <mutex>
|
||||
#include <iostream>
|
||||
#include <functional>
|
||||
#include <thread>
|
||||
#include <support/component_impl.h>
|
||||
#include <support/local_service_access.h>
|
||||
#include "generated/test_component.h"
|
||||
|
||||
inline sdv::process::TProcessID GetProcessID()
|
||||
{
|
||||
static sdv::process::TProcessID tProcessID = 0;
|
||||
if (!tProcessID)
|
||||
{
|
||||
sdv::process::IProcessInfo* pProcessInfo = sdv::core::GetObject<sdv::process::IProcessInfo>("ProcessControlService");
|
||||
if (!pProcessInfo) return 0;
|
||||
tProcessID = pProcessInfo->GetProcessID();
|
||||
}
|
||||
return tProcessID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Hello utlity
|
||||
*/
|
||||
class CHelloUtility : public sdv::CSdvObject, public IHello
|
||||
{
|
||||
public:
|
||||
|
||||
BEGIN_SDV_INTERFACE_MAP()
|
||||
SDV_INTERFACE_ENTRY(IHello)
|
||||
END_SDV_INTERFACE_MAP()
|
||||
|
||||
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::utility)
|
||||
DECLARE_OBJECT_CLASS_NAME("TestObject_HelloUtility")
|
||||
|
||||
/**
|
||||
* @brief Say hello. Overload of IHello::SayHello.
|
||||
* @param[in, out] sStages The struct stages will be filled by the components. The complex service calls the basic service. The
|
||||
* basic service calls the device. The device calls the system service and the utility.
|
||||
* @return The greetings string.
|
||||
*/
|
||||
virtual sdv::u8string SayHello(/*inout*/ SStages& sStages) const override
|
||||
{
|
||||
sStages.bUtility = true;
|
||||
|
||||
return "PID#" + std::to_string(GetPID()) + " Hello from basic service\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the PID of the process the component is running in... Overload of IHello::GetPID.
|
||||
*/
|
||||
sdv::process::TProcessID GetPID() const
|
||||
{
|
||||
return GetProcessID();
|
||||
}
|
||||
};
|
||||
DEFINE_SDV_OBJECT(CHelloUtility)
|
||||
|
||||
@@ -25,9 +25,16 @@ add_executable(ComponentTest_AppControl
|
||||
|
||||
target_link_libraries(ComponentTest_AppControl ${CMAKE_DL_LIBS} GTest::GTest)
|
||||
|
||||
# Add the Data Dispatch Service unittest
|
||||
# Add the AppControl component test
|
||||
add_test(NAME ComponentTest_AppControl COMMAND ComponentTest_AppControl WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
|
||||
|
||||
# Execute the installation helper utility to create an installation manifest for the core files.
|
||||
add_custom_target(ComponentTest_AppControl_install_manifest
|
||||
COMMAND "$<TARGET_FILE:sdv_packager>" DIRECT_INSTALL ComponentTest_Repository --instance2009 "$<TARGET_FILE:ComponentTest_Repository_test_module>" "$<TARGET_FILE:ComponentTest_Repository_ps>" "-I$<TARGET_FILE_DIR:ComponentTest_Repository_test_module>" --overwrite --user_config+TestObject_ComplexHelloService+TestObject_HelloUtility --interface_config+Example_Object+Example_Object_2+TestObject_HelloDevice+TestObject_BasicHelloService+TestObject_SystemHelloService
|
||||
DEPENDS ComponentTest_Repository_test_module ComponentTest_Repository_ps
|
||||
WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
|
||||
)
|
||||
|
||||
# Execute the test
|
||||
# Currently disabled due to issues with MINGW causing the application to sporadically crash. A bug ticket has been filed:
|
||||
# https://dev.azure.com/SW4ZF/AZP-074_DivDI_SofDCarResearch/_workitems/edit/608132
|
||||
@@ -39,3 +46,4 @@ add_custom_command(TARGET ComponentTest_AppControl POST_BUILD
|
||||
# Build dependencies
|
||||
add_dependencies(ComponentTest_AppControl dependency_sdv_components)
|
||||
add_dependencies(ComponentTest_AppControl ComponentTest_Repository) # Use the repository components for this test
|
||||
add_dependencies(ComponentTest_AppControl ComponentTest_AppControl_install_manifest) # Use the repository components for this test
|
||||
|
||||
@@ -254,7 +254,9 @@ TEST(CoreLibrary_AppControl_EventHandler, Startup_Standalone_NoConfig)
|
||||
}
|
||||
}
|
||||
|
||||
TEST(CoreLibrary_AppControl_EventHandler, Startup_External_NoConfig)
|
||||
// Currently disabled due to absence of server accepting connections.
|
||||
// https://dev.azure.com/SW4ZF/AZP-431_DivDI_Vehicle_API/_workitems/edit/800643
|
||||
TEST(CoreLibrary_AppControl_EventHandler, DISABLED_Startup_External_NoConfig)
|
||||
{
|
||||
CAppEventHandler handler;
|
||||
sdv::app::IAppControl* pControl = sdv::core::GetCore<sdv::app::IAppControl>();
|
||||
@@ -331,13 +333,13 @@ TEST(CoreLibrary_AppControl_EventHandler, Startup_Isolated_NoConfig)
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = pControl->Startup(R"code(
|
||||
bool bResult = pControl->Startup(R"toml(
|
||||
[Application]
|
||||
Mode = "Isolated"
|
||||
|
||||
[Console]
|
||||
Report = "Silent"
|
||||
)code", &handler);
|
||||
)toml", &handler);
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::running);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::isolated);
|
||||
@@ -589,11 +591,11 @@ TEST(CoreLibrary_AppControl_EventHandler, Startup_Default_DefineInstance)
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = pControl->Startup("[Application]\nInstance=2005", &handler);
|
||||
bool bResult = pControl->Startup("[Application]\nInstance=2009", &handler);
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::running);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::standalone);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2005u);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2009u);
|
||||
|
||||
sdv::app::EAppOperationState rgeStartupStates[] = {
|
||||
sdv::app::EAppOperationState::initializing,
|
||||
@@ -652,11 +654,11 @@ TEST(CoreLibrary_AppControl_EventHandler, Startup_Standalone_DefineInstance)
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = pControl->Startup("[Application]\nMode=\"Standalone\"\nInstance=2005", &handler);
|
||||
bool bResult = pControl->Startup("[Application]\nMode=\"Standalone\"\nInstance=2009", &handler);
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::running);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::standalone);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2005u);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2009u);
|
||||
|
||||
sdv::app::EAppOperationState rgeStartupStates[] = {
|
||||
sdv::app::EAppOperationState::initializing,
|
||||
@@ -701,7 +703,9 @@ TEST(CoreLibrary_AppControl_EventHandler, Startup_Standalone_DefineInstance)
|
||||
}
|
||||
}
|
||||
|
||||
TEST(CoreLibrary_AppControl_EventHandler, Startup_External_DefineInstance)
|
||||
// Currently disabled due to absence of server accepting connections.
|
||||
// https://dev.azure.com/SW4ZF/AZP-431_DivDI_Vehicle_API/_workitems/edit/800643
|
||||
TEST(CoreLibrary_AppControl_EventHandler, DISABLED_Startup_External_DefineInstance)
|
||||
{
|
||||
CAppEventHandler handler;
|
||||
sdv::app::IAppControl* pControl = sdv::core::GetCore<sdv::app::IAppControl>();
|
||||
@@ -715,11 +719,11 @@ TEST(CoreLibrary_AppControl_EventHandler, Startup_External_DefineInstance)
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = pControl->Startup("[Application]\nMode=\"External\"\nInstance=2005", &handler);
|
||||
bool bResult = pControl->Startup("[Application]\nMode=\"External\"\nInstance=2009", &handler);
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::running);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::external);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2005u);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2009u);
|
||||
|
||||
sdv::app::EAppOperationState rgeStartupStates[] = {
|
||||
sdv::app::EAppOperationState::initializing,
|
||||
@@ -778,16 +782,16 @@ TEST(CoreLibrary_AppControl_EventHandler, Startup_Isolated_DefineInstance)
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
|
||||
std::string ssConfig = R"code([Application]
|
||||
std::string ssConfig = R"toml([Application]
|
||||
Mode = "Isolated"
|
||||
Instance = 2005
|
||||
Connection = ")code";
|
||||
Instance = 2009
|
||||
Connection = ")toml";
|
||||
ssConfig += Base64EncodePlainText("test") + "\"";
|
||||
bool bResult = pControl->Startup(ssConfig, &handler);
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::running);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::isolated);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2005u);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2009u);
|
||||
|
||||
sdv::app::EAppOperationState rgeStartupStates[] = {
|
||||
sdv::app::EAppOperationState::initializing,
|
||||
@@ -846,11 +850,11 @@ TEST(CoreLibrary_AppControl_EventHandler, Startup_Main_DefineInstance)
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = pControl->Startup("[Application]\nMode=\"Main\"\nInstance=2005", &handler);
|
||||
bool bResult = pControl->Startup("[Application]\nMode=\"Main\"\nInstance=2009", &handler);
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::running);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::main);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2005u);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2009u);
|
||||
|
||||
sdv::app::EAppOperationState rgeStartupStates[] = {
|
||||
sdv::app::EAppOperationState::initializing,
|
||||
@@ -909,11 +913,11 @@ TEST(CoreLibrary_AppControl_EventHandler, Startup_Essential_DefineInstance)
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = pControl->Startup("[Application]\nMode=\"Essential\"\nInstance=2005", &handler);
|
||||
bool bResult = pControl->Startup("[Application]\nMode=\"Essential\"\nInstance=2009", &handler);
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::running);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::essential);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2005u);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2009u);
|
||||
|
||||
sdv::app::EAppOperationState rgeStartupStates[] = {
|
||||
sdv::app::EAppOperationState::initializing,
|
||||
@@ -972,11 +976,11 @@ TEST(CoreLibrary_AppControl_EventHandler, Startup_Maintenance_DefineInstance)
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = pControl->Startup("[Application]\nMode=\"Maintenance\"\nInstance=2005", &handler);
|
||||
bool bResult = pControl->Startup("[Application]\nMode=\"Maintenance\"\nInstance=2009", &handler);
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::running);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::maintenance);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2005u);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2009u);
|
||||
|
||||
sdv::app::EAppOperationState rgeStartupStates[] = {
|
||||
sdv::app::EAppOperationState::initializing,
|
||||
@@ -1042,8 +1046,10 @@ TEST(CoreLibrary_AppControl_EventHandler, RunLoop_Default)
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2007u);
|
||||
|
||||
auto tpStart = std::chrono::high_resolution_clock::now();
|
||||
std::thread threadShutdownRequest([]()
|
||||
sdv::core::secure_thread threadShutdownRequest([&]()
|
||||
{
|
||||
while (pOperation->GetOperationState() != sdv::app::EAppOperationState::running)
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||
RequestShutdown(2007u);
|
||||
});
|
||||
@@ -1080,8 +1086,10 @@ TEST(CoreLibrary_AppControl_EventHandler, RunLoop_Standalone)
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2007u);
|
||||
|
||||
auto tpStart = std::chrono::high_resolution_clock::now();
|
||||
std::thread threadShutdownRequest([]()
|
||||
sdv::core::secure_thread threadShutdownRequest([&]()
|
||||
{
|
||||
while (pOperation->GetOperationState() != sdv::app::EAppOperationState::running)
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||
RequestShutdown(2007u);
|
||||
});
|
||||
@@ -1097,7 +1105,9 @@ TEST(CoreLibrary_AppControl_EventHandler, RunLoop_Standalone)
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(CoreLibrary_AppControl_EventHandler, RunLoop_External)
|
||||
// Currently disabled due to absence of server accepting connections.
|
||||
// https://dev.azure.com/SW4ZF/AZP-431_DivDI_Vehicle_API/_workitems/edit/800643
|
||||
TEST(CoreLibrary_AppControl_EventHandler, DISABLED_RunLoop_External)
|
||||
{
|
||||
CAppEventHandler handler;
|
||||
sdv::app::IAppControl* pControl = sdv::core::GetCore<sdv::app::IAppControl>();
|
||||
@@ -1118,8 +1128,10 @@ TEST(CoreLibrary_AppControl_EventHandler, RunLoop_External)
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2007u);
|
||||
|
||||
auto tpStart = std::chrono::high_resolution_clock::now();
|
||||
std::thread threadShutdownRequest([]()
|
||||
sdv::core::secure_thread threadShutdownRequest([&]()
|
||||
{
|
||||
while (pOperation->GetOperationState() != sdv::app::EAppOperationState::running)
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||
RequestShutdown(2007u);
|
||||
});
|
||||
@@ -1149,10 +1161,10 @@ TEST(CoreLibrary_AppControl_EventHandler, RunLoop_Isolated)
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
|
||||
std::string ssConfig = R"code([Application]
|
||||
std::string ssConfig = R"toml([Application]
|
||||
Mode = "Isolated"
|
||||
Instance = 2007
|
||||
Connection = ")code";
|
||||
Connection = ")toml";
|
||||
ssConfig += Base64EncodePlainText("test") + "\"";
|
||||
bool bResult = pControl->Startup(ssConfig, &handler);
|
||||
EXPECT_TRUE(bResult);
|
||||
@@ -1161,8 +1173,10 @@ Connection = ")code";
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2007u);
|
||||
|
||||
auto tpStart = std::chrono::high_resolution_clock::now();
|
||||
std::thread threadShutdownRequest([]()
|
||||
sdv::core::secure_thread threadShutdownRequest([&]()
|
||||
{
|
||||
while (pOperation->GetOperationState() != sdv::app::EAppOperationState::running)
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||
sdv::app::IAppShutdownRequest* pShutdownRequest = sdv::core::GetObject<sdv::app::IAppShutdownRequest>("AppControlService");
|
||||
ASSERT_NE(pShutdownRequest, nullptr);
|
||||
@@ -1201,8 +1215,10 @@ TEST(CoreLibrary_AppControl_EventHandler, RunLoop_Main)
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2007u);
|
||||
|
||||
auto tpStart = std::chrono::high_resolution_clock::now();
|
||||
std::thread threadShutdownRequest([]()
|
||||
sdv::core::secure_thread threadShutdownRequest([&]()
|
||||
{
|
||||
while (pOperation->GetOperationState() != sdv::app::EAppOperationState::running)
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||
sdv::app::IAppShutdownRequest* pShutdownRequest = sdv::core::GetObject<sdv::app::IAppShutdownRequest>("AppControlService");
|
||||
ASSERT_NE(pShutdownRequest, nullptr);
|
||||
@@ -1241,8 +1257,10 @@ TEST(CoreLibrary_AppControl_EventHandler, RunLoop_Essential)
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2007u);
|
||||
|
||||
auto tpStart = std::chrono::high_resolution_clock::now();
|
||||
std::thread threadShutdownRequest([]()
|
||||
sdv::core::secure_thread threadShutdownRequest([&]()
|
||||
{
|
||||
while (pOperation->GetOperationState() != sdv::app::EAppOperationState::running)
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||
RequestShutdown(2007u);
|
||||
});
|
||||
|
||||
@@ -77,8 +77,8 @@ TEST(AppControl, Startup_Standalone_NoConfig)
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
// Testing the external application requires a process running that was initialized as main with the same instance ID. This process
|
||||
// needs to be started before and shutdown after the execution of this test.
|
||||
// Currently disabled due to absence of server accepting connections.
|
||||
// https://dev.azure.com/SW4ZF/AZP-431_DivDI_Vehicle_API/_workitems/edit/800643
|
||||
TEST(AppControl, DISABLED_Startup_External_NoConfig)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
@@ -105,13 +105,13 @@ TEST(AppControl, Startup_Isolated_NoConfig)
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = control.Startup(R"code(
|
||||
bool bResult = control.Startup(R"toml(
|
||||
[Application]
|
||||
Mode = "Isolated"
|
||||
|
||||
[Console]
|
||||
Report = "Silent"
|
||||
)code");
|
||||
)toml");
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_TRUE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::isolated);
|
||||
@@ -187,11 +187,11 @@ TEST(AppControl, Startup_Default_DefineInstance)
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = control.Startup("[Application]\nInstance=2005");
|
||||
bool bResult = control.Startup("[Application]\nInstance=2009");
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_TRUE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::standalone);
|
||||
EXPECT_EQ(control.GetInstanceID(), 2005u);
|
||||
EXPECT_EQ(control.GetInstanceID(), 2009u);
|
||||
|
||||
control.Shutdown();
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
@@ -206,11 +206,11 @@ TEST(AppControl, Startup_Standalone_DefineInstance)
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = control.Startup("[Application]\nMode=\"Standalone\"\nInstance=2005");
|
||||
bool bResult = control.Startup("[Application]\nMode=\"Standalone\"\nInstance=2009");
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_TRUE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::standalone);
|
||||
EXPECT_EQ(control.GetInstanceID(), 2005u);
|
||||
EXPECT_EQ(control.GetInstanceID(), 2009u);
|
||||
|
||||
control.Shutdown();
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
@@ -218,8 +218,8 @@ TEST(AppControl, Startup_Standalone_DefineInstance)
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
// Testing the external application requires a process running that was initialized as main with the same instance ID. This process
|
||||
// needs to be started before and shutdown after the execution of this test.
|
||||
// Currently disabled due to absence of server accepting connections.
|
||||
// https://dev.azure.com/SW4ZF/AZP-431_DivDI_Vehicle_API/_workitems/edit/800643
|
||||
TEST(AppControl, DISABLED_Startup_External_DefineInstance)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
@@ -227,11 +227,11 @@ TEST(AppControl, DISABLED_Startup_External_DefineInstance)
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = control.Startup("[Application]\nMode=\"External\"\nInstance=2005");
|
||||
bool bResult = control.Startup("[Application]\nMode=\"External\"\nInstance=2009");
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_TRUE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::external);
|
||||
EXPECT_EQ(control.GetInstanceID(), 2005u);
|
||||
EXPECT_EQ(control.GetInstanceID(), 2009u);
|
||||
|
||||
control.Shutdown();
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
@@ -246,16 +246,16 @@ TEST(AppControl, Startup_Isolated_DefineInstance)
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
std::string ssConfig = R"code([Application]
|
||||
std::string ssConfig = R"toml([Application]
|
||||
Mode = "Isolated"
|
||||
Instance = 2005
|
||||
Connection = ")code";
|
||||
Instance = 2009
|
||||
Connection = ")toml";
|
||||
ssConfig += Base64EncodePlainText("test") + "\"";
|
||||
bool bResult = control.Startup(ssConfig);
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_TRUE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::isolated);
|
||||
EXPECT_EQ(control.GetInstanceID(), 2005u);
|
||||
EXPECT_EQ(control.GetInstanceID(), 2009u);
|
||||
|
||||
control.Shutdown();
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
@@ -270,11 +270,11 @@ TEST(AppControl, Startup_Main_DefineInstance)
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = control.Startup("[Application]\nMode=\"Main\"\nInstance=2005");
|
||||
bool bResult = control.Startup("[Application]\nMode=\"Main\"\nInstance=2009");
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_TRUE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::main);
|
||||
EXPECT_EQ(control.GetInstanceID(), 2005u);
|
||||
EXPECT_EQ(control.GetInstanceID(), 2009u);
|
||||
|
||||
control.Shutdown();
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
@@ -289,11 +289,11 @@ TEST(AppControl, Startup_Essential_DefineInstance)
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = control.Startup("[Application]\nMode=\"Essential\"\nInstance=2005");
|
||||
bool bResult = control.Startup("[Application]\nMode=\"Essential\"\nInstance=2009");
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_TRUE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::essential);
|
||||
EXPECT_EQ(control.GetInstanceID(), 2005u);
|
||||
EXPECT_EQ(control.GetInstanceID(), 2009u);
|
||||
|
||||
control.Shutdown();
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
@@ -308,11 +308,11 @@ TEST(AppControl, Startup_Maintenance_DefineInstance)
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = control.Startup("[Application]\nMode=\"Maintenance\"\nInstance=2005");
|
||||
bool bResult = control.Startup("[Application]\nMode=\"Maintenance\"\nInstance=2009");
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_TRUE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::maintenance);
|
||||
EXPECT_EQ(control.GetInstanceID(), 2005u);
|
||||
EXPECT_EQ(control.GetInstanceID(), 2009u);
|
||||
|
||||
control.Shutdown();
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
@@ -334,8 +334,10 @@ TEST(AppControl, RunLoop_Default)
|
||||
EXPECT_EQ(control.GetInstanceID(), 2007u);
|
||||
|
||||
auto tpStart = std::chrono::high_resolution_clock::now();
|
||||
std::thread threadShutdownRequest([]()
|
||||
sdv::core::secure_thread threadShutdownRequest([&]()
|
||||
{
|
||||
while (!control.IsRunning())
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||
RequestShutdown(2007u);
|
||||
});
|
||||
@@ -363,8 +365,10 @@ TEST(AppControl, RunLoop_Standalone)
|
||||
EXPECT_EQ(control.GetInstanceID(), 2007u);
|
||||
|
||||
auto tpStart = std::chrono::high_resolution_clock::now();
|
||||
std::thread threadShutdownRequest([]()
|
||||
sdv::core::secure_thread threadShutdownRequest([&]()
|
||||
{
|
||||
while (!control.IsRunning())
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||
RequestShutdown(2007u);
|
||||
});
|
||||
@@ -378,8 +382,8 @@ TEST(AppControl, RunLoop_Standalone)
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
// Testing the external application requires a process running that was initialized as main with the same instance ID. This process
|
||||
// needs to be started before and shutdown after the execution of this test.
|
||||
// Currently disabled due to absence of server accepting connections.
|
||||
// https://dev.azure.com/SW4ZF/AZP-431_DivDI_Vehicle_API/_workitems/edit/800643
|
||||
TEST(AppControl, DISABLED_RunLoop_External)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
@@ -394,8 +398,10 @@ TEST(AppControl, DISABLED_RunLoop_External)
|
||||
EXPECT_EQ(control.GetInstanceID(), 2007u);
|
||||
|
||||
auto tpStart = std::chrono::high_resolution_clock::now();
|
||||
std::thread threadShutdownRequest([]()
|
||||
sdv::core::secure_thread threadShutdownRequest([&]()
|
||||
{
|
||||
while (!control.IsRunning())
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||
RequestShutdown(2007u);
|
||||
});
|
||||
@@ -416,10 +422,10 @@ TEST(AppControl, RunLoop_Isolated)
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
std::string ssConfig = R"code([Application]
|
||||
std::string ssConfig = R"toml([Application]
|
||||
Mode = "Isolated"
|
||||
Instance = 2007
|
||||
Connection = ")code";
|
||||
Connection = ")toml";
|
||||
ssConfig += Base64EncodePlainText("test") + "\"";
|
||||
bool bResult = control.Startup(ssConfig);
|
||||
EXPECT_TRUE(bResult);
|
||||
@@ -428,8 +434,10 @@ Connection = ")code";
|
||||
EXPECT_EQ(control.GetInstanceID(), 2007u);
|
||||
|
||||
auto tpStart = std::chrono::high_resolution_clock::now();
|
||||
std::thread threadShutdownRequest([]()
|
||||
sdv::core::secure_thread threadShutdownRequest([&]()
|
||||
{
|
||||
while (!control.IsRunning())
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||
sdv::app::IAppShutdownRequest* pShutdownRequest = sdv::core::GetObject<sdv::app::IAppShutdownRequest>("AppControlService");
|
||||
ASSERT_NE(pShutdownRequest, nullptr);
|
||||
@@ -459,8 +467,10 @@ TEST(AppControl, RunLoop_Main)
|
||||
EXPECT_EQ(control.GetInstanceID(), 2007u);
|
||||
|
||||
auto tpStart = std::chrono::high_resolution_clock::now();
|
||||
std::thread threadShutdownRequest([]()
|
||||
sdv::core::secure_thread threadShutdownRequest([&]()
|
||||
{
|
||||
while (!control.IsRunning())
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||
sdv::app::IAppShutdownRequest* pShutdownRequest = sdv::core::GetObject<sdv::app::IAppShutdownRequest>("AppControlService");
|
||||
ASSERT_NE(pShutdownRequest, nullptr);
|
||||
@@ -490,8 +500,10 @@ TEST(AppControl, RunLoop_Essential)
|
||||
EXPECT_EQ(control.GetInstanceID(), 2007u);
|
||||
|
||||
auto tpStart = std::chrono::high_resolution_clock::now();
|
||||
std::thread threadShutdownRequest([]()
|
||||
sdv::core::secure_thread threadShutdownRequest([&]()
|
||||
{
|
||||
while (!control.IsRunning())
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||
RequestShutdown(2007u);
|
||||
});
|
||||
@@ -526,4 +538,3 @@ TEST(AppControl, RunLoop_Maintenance)
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ TEST(CoreLibrary_AppControl_NoEventHandler, Startup_Default_NoConfig)
|
||||
sdv::app::IAppControl* pControl = sdv::core::GetCore<sdv::app::IAppControl>();
|
||||
ASSERT_NE(pControl, nullptr);
|
||||
sdv::app::IAppContext* pContext = sdv::core::GetCore<sdv::app::IAppContext>();
|
||||
ASSERT_NE(pContext, nullptr);
|
||||
ASSERT_NE(pContext, nullptr);
|
||||
sdv::app::IAppOperation* pOperation = sdv::core::GetCore<sdv::app::IAppOperation>();
|
||||
ASSERT_NE(pOperation, nullptr);
|
||||
|
||||
@@ -96,7 +96,9 @@ TEST(CoreLibrary_AppControl_NoEventHandler, Startup_Standalone_NoConfig)
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(CoreLibrary_AppControl_NoEventHandler, Startup_External_NoConfig)
|
||||
// Currently disabled due to absence of server accepting connections.
|
||||
// https://dev.azure.com/SW4ZF/AZP-431_DivDI_Vehicle_API/_workitems/edit/800643
|
||||
TEST(CoreLibrary_AppControl_NoEventHandler, DISABLED_Startup_External_NoConfig)
|
||||
{
|
||||
sdv::app::IAppControl* pControl = sdv::core::GetCore<sdv::app::IAppControl>();
|
||||
ASSERT_NE(pControl, nullptr);
|
||||
@@ -134,13 +136,13 @@ TEST(CoreLibrary_AppControl_NoEventHandler, Startup_Isolated_NoConfig)
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = pControl->Startup(R"code(
|
||||
bool bResult = pControl->Startup(R"toml(
|
||||
[Application]
|
||||
Mode = "Isolated"
|
||||
|
||||
[Console]
|
||||
Report = "Silent"
|
||||
)code", nullptr);
|
||||
)toml", nullptr);
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::running);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::isolated);
|
||||
@@ -240,11 +242,11 @@ TEST(CoreLibrary_AppControl_NoEventHandler, Startup_Default_DefineInstance)
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = pControl->Startup("[Application]\nInstance=2005", nullptr);
|
||||
bool bResult = pControl->Startup("[Application]\nInstance=2009", nullptr);
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::running);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::standalone);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2005u);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2009u);
|
||||
|
||||
pControl->Shutdown(true);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
@@ -265,11 +267,11 @@ TEST(CoreLibrary_AppControl_NoEventHandler, Startup_Standalone_DefineInstance)
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = pControl->Startup("[Application]\nMode=\"Standalone\"\nInstance=2005", nullptr);
|
||||
bool bResult = pControl->Startup("[Application]\nMode=\"Standalone\"\nInstance=2009", nullptr);
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::running);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::standalone);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2005u);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2009u);
|
||||
|
||||
pControl->Shutdown(true);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
@@ -277,7 +279,9 @@ TEST(CoreLibrary_AppControl_NoEventHandler, Startup_Standalone_DefineInstance)
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(CoreLibrary_AppControl_NoEventHandler, Startup_External_DefineInstance)
|
||||
// Currently disabled due to absence of server accepting connections.
|
||||
// https://dev.azure.com/SW4ZF/AZP-431_DivDI_Vehicle_API/_workitems/edit/800643
|
||||
TEST(CoreLibrary_AppControl_NoEventHandler, DISABLED_Startup_External_DefineInstance)
|
||||
{
|
||||
sdv::app::IAppControl* pControl = sdv::core::GetCore<sdv::app::IAppControl>();
|
||||
ASSERT_NE(pControl, nullptr);
|
||||
@@ -290,11 +294,11 @@ TEST(CoreLibrary_AppControl_NoEventHandler, Startup_External_DefineInstance)
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = pControl->Startup("[Application]\nMode=\"External\"\nInstance=2005", nullptr);
|
||||
bool bResult = pControl->Startup("[Application]\nMode=\"External\"\nInstance=2009", nullptr);
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::running);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::external);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2005u);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2009u);
|
||||
|
||||
pControl->Shutdown(true);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
@@ -315,16 +319,16 @@ TEST(CoreLibrary_AppControl_NoEventHandler, Startup_Isolated_DefineInstance)
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
|
||||
std::string ssConfig = R"code([Application]
|
||||
std::string ssConfig = R"toml([Application]
|
||||
Mode = "Isolated"
|
||||
Instance = 2005
|
||||
Connection = ")code";
|
||||
Instance = 2009
|
||||
Connection = ")toml";
|
||||
ssConfig += Base64EncodePlainText("test") + "\"";
|
||||
bool bResult = pControl->Startup(ssConfig, nullptr);
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::running);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::isolated);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2005u);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2009u);
|
||||
|
||||
pControl->Shutdown(true);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
@@ -345,11 +349,11 @@ TEST(CoreLibrary_AppControl_NoEventHandler, Startup_Main_DefineInstance)
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = pControl->Startup("[Application]\nMode=\"Main\"\nInstance=2005", nullptr);
|
||||
bool bResult = pControl->Startup("[Application]\nMode=\"Main\"\nInstance=2009", nullptr);
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::running);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::main);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2005u);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2009u);
|
||||
|
||||
pControl->Shutdown(true);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
@@ -370,11 +374,11 @@ TEST(CoreLibrary_AppControl_NoEventHandler, Startup_Essential_DefineInstance)
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = pControl->Startup("[Application]\nMode=\"Essential\"\nInstance=2005", nullptr);
|
||||
bool bResult = pControl->Startup("[Application]\nMode=\"Essential\"\nInstance=2009", nullptr);
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::running);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::essential);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2005u);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2009u);
|
||||
|
||||
pControl->Shutdown(true);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
@@ -395,11 +399,11 @@ TEST(CoreLibrary_AppControl_NoEventHandler, Startup_Maintenance_DefineInstance)
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = pControl->Startup("[Application]\nMode=\"Maintenance\"\nInstance=2005", nullptr);
|
||||
bool bResult = pControl->Startup("[Application]\nMode=\"Maintenance\"\nInstance=2009", nullptr);
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::running);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::maintenance);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2005u);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2009u);
|
||||
|
||||
pControl->Shutdown(true);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
@@ -427,8 +431,10 @@ TEST(CoreLibrary_AppControl_NoEventHandler, RunLoop_Default)
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2007u);
|
||||
|
||||
auto tpStart = std::chrono::high_resolution_clock::now();
|
||||
std::thread threadShutdownRequest([]()
|
||||
sdv::core::secure_thread threadShutdownRequest([&]()
|
||||
{
|
||||
while (pOperation->GetOperationState() != sdv::app::EAppOperationState::running)
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||
RequestShutdown(2007u);
|
||||
});
|
||||
@@ -462,8 +468,10 @@ TEST(CoreLibrary_AppControl_NoEventHandler, RunLoop_Standalone)
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2007u);
|
||||
|
||||
auto tpStart = std::chrono::high_resolution_clock::now();
|
||||
std::thread threadShutdownRequest([]()
|
||||
sdv::core::secure_thread threadShutdownRequest([&]()
|
||||
{
|
||||
while (pOperation->GetOperationState() != sdv::app::EAppOperationState::running)
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||
RequestShutdown(2007u);
|
||||
});
|
||||
@@ -477,7 +485,9 @@ TEST(CoreLibrary_AppControl_NoEventHandler, RunLoop_Standalone)
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(CoreLibrary_AppControl_NoEventHandler, RunLoop_External)
|
||||
// Currently disabled due to absence of server accepting connections.
|
||||
// https://dev.azure.com/SW4ZF/AZP-431_DivDI_Vehicle_API/_workitems/edit/800643
|
||||
TEST(CoreLibrary_AppControl_NoEventHandler, DISABLED_RunLoop_External)
|
||||
{
|
||||
sdv::app::IAppControl* pControl = sdv::core::GetCore<sdv::app::IAppControl>();
|
||||
ASSERT_NE(pControl, nullptr);
|
||||
@@ -497,8 +507,10 @@ TEST(CoreLibrary_AppControl_NoEventHandler, RunLoop_External)
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2007u);
|
||||
|
||||
auto tpStart = std::chrono::high_resolution_clock::now();
|
||||
std::thread threadShutdownRequest([]()
|
||||
sdv::core::secure_thread threadShutdownRequest([&]()
|
||||
{
|
||||
while (pOperation->GetOperationState() != sdv::app::EAppOperationState::running)
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||
RequestShutdown(2007u);
|
||||
});
|
||||
@@ -525,10 +537,10 @@ TEST(CoreLibrary_AppControl_NoEventHandler, RunLoop_Isolated)
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
|
||||
std::string ssConfig = R"code([Application]
|
||||
std::string ssConfig = R"toml([Application]
|
||||
Mode = "Isolated"
|
||||
Instance = 2007
|
||||
Connection = ")code";
|
||||
Connection = ")toml";
|
||||
ssConfig += Base64EncodePlainText("test") + "\"";
|
||||
bool bResult = pControl->Startup(ssConfig, nullptr);
|
||||
EXPECT_TRUE(bResult);
|
||||
@@ -537,8 +549,10 @@ Connection = ")code";
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2007u);
|
||||
|
||||
auto tpStart = std::chrono::high_resolution_clock::now();
|
||||
std::thread threadShutdownRequest([]()
|
||||
sdv::core::secure_thread threadShutdownRequest([&]()
|
||||
{
|
||||
while (pOperation->GetOperationState() != sdv::app::EAppOperationState::running)
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||
sdv::app::IAppShutdownRequest* pShutdownRequest = sdv::core::GetObject<sdv::app::IAppShutdownRequest>("AppControlService");
|
||||
ASSERT_NE(pShutdownRequest, nullptr);
|
||||
@@ -574,8 +588,10 @@ TEST(CoreLibrary_AppControl_NoEventHandler, RunLoop_Main)
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2007u);
|
||||
|
||||
auto tpStart = std::chrono::high_resolution_clock::now();
|
||||
std::thread threadShutdownRequest([]()
|
||||
sdv::core::secure_thread threadShutdownRequest([&]()
|
||||
{
|
||||
while (pOperation->GetOperationState() != sdv::app::EAppOperationState::running)
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||
sdv::app::IAppShutdownRequest* pShutdownRequest = sdv::core::GetObject<sdv::app::IAppShutdownRequest>("AppControlService");
|
||||
ASSERT_NE(pShutdownRequest, nullptr);
|
||||
@@ -611,8 +627,10 @@ TEST(CoreLibrary_AppControl_NoEventHandler, RunLoop_Essential)
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2007u);
|
||||
|
||||
auto tpStart = std::chrono::high_resolution_clock::now();
|
||||
std::thread threadShutdownRequest([]()
|
||||
sdv::core::secure_thread threadShutdownRequest([&]()
|
||||
{
|
||||
while (pOperation->GetOperationState() != sdv::app::EAppOperationState::running)
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||
RequestShutdown(2007u);
|
||||
});
|
||||
|
||||
@@ -69,35 +69,26 @@ public:
|
||||
std::filesystem::path GetDefaultInstallDir();
|
||||
};
|
||||
|
||||
inline std::filesystem::path CModuleControl_Install::GetDefaultInstallDir()
|
||||
std::filesystem::path CModuleControl_Install::GetDefaultInstallDir()
|
||||
{
|
||||
// // The default directory for Windows is located at $ProgramData/ and for Posix at the executable.
|
||||
std::filesystem::path pathInstallDir;
|
||||
//#ifdef _WIN32
|
||||
// wchar_t* szPath = nullptr;
|
||||
// HRESULT hr = SHGetKnownFolderPath(FOLDERID_LocalAppData, KF_FLAG_DEFAULT, 0, &szPath);
|
||||
// if (SUCCEEDED(hr) && szPath)
|
||||
// pathInstallDir = szPath;
|
||||
// if (szPath) CoTaskMemFree(szPath);
|
||||
//#elif defined __unix__
|
||||
pathInstallDir = GetExecDirectory();
|
||||
//#else
|
||||
//#error OS is not supported!
|
||||
//#endif
|
||||
// Append the installation directory with /<instance_ID>/.
|
||||
pathInstallDir /= "2006";
|
||||
|
||||
return pathInstallDir;
|
||||
return (GetExecDirectory() / "../../bin/2006").lexically_normal();
|
||||
}
|
||||
|
||||
TEST_F(CModuleControl_Install, MainApp_DefaultInstallDir)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
bool bResult = control.Startup("[Application]\nMode=\"Main\"\nInstance=2006");
|
||||
bool bResult = control.Startup(R"toml([Application]
|
||||
Mode = "Main"
|
||||
Instance = 2006
|
||||
|
||||
[Console]
|
||||
RedirectMon = true
|
||||
)toml");
|
||||
EXPECT_TRUE(bResult);
|
||||
|
||||
// The default installation directory should be created.
|
||||
EXPECT_TRUE(std::filesystem::exists(GetDefaultInstallDir()));
|
||||
EXPECT_TRUE(std::filesystem::exists(control.GetComponentInstallDirectory()));
|
||||
|
||||
control.Shutdown();
|
||||
}
|
||||
@@ -106,10 +97,10 @@ TEST_F(CModuleControl_Install, IsolatedApp_DefaultInstallDir)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
std::string ssConnectionString = Base64EncodePlainText("");
|
||||
std::string ssConfig = R"code([Application]
|
||||
std::string ssConfig = R"toml([Application]
|
||||
Mode = "Isolated"
|
||||
Instance = 2006
|
||||
Connection = ")code";
|
||||
Connection = ")toml";
|
||||
ssConfig += Base64EncodePlainText("test") + "\"";
|
||||
bool bResult = control.Startup(ssConfig);
|
||||
EXPECT_TRUE(bResult);
|
||||
@@ -146,7 +137,13 @@ TEST_F(CModuleControl_Install, MainApp_BlockDefaultInstallDir)
|
||||
fstream.close();
|
||||
|
||||
sdv::app::CAppControl control;
|
||||
bool bResult = control.Startup("[Application]\nMode=\"Main\"\nInstance=2006");
|
||||
bool bResult = control.Startup(R"toml([Application]
|
||||
Mode = "Main"
|
||||
Instance = 2006
|
||||
|
||||
[Console]
|
||||
RedirectMon = true
|
||||
)toml");
|
||||
EXPECT_FALSE(bResult);
|
||||
|
||||
// The default installation directory should be created.
|
||||
@@ -168,7 +165,9 @@ TEST_F(CModuleControl_Install, IsolatedApp_BlockDefaultInstallDir)
|
||||
fstream.close();
|
||||
|
||||
sdv::app::CAppControl control;
|
||||
bool bResult = control.Startup("[Application]\nMode=\"Isolated\"\nInstance=2006");
|
||||
bool bResult = control.Startup(R"toml([Application]
|
||||
Mode = "Isolated"
|
||||
Instance = 2006)toml");
|
||||
EXPECT_FALSE(bResult);
|
||||
|
||||
// The default installation directory should be created.
|
||||
@@ -197,12 +196,12 @@ TEST_F(CModuleControl_Install, OtherApp_BlockDefaultInstallDir)
|
||||
TEST_F(CModuleControl_Install, MainApp_CustomInstallDirRelative)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
bool bResult = control.Startup(R"code(
|
||||
bool bResult = control.Startup(R"toml(
|
||||
[Application]
|
||||
Mode="Main"
|
||||
Instance=2006
|
||||
InstallDir = "module_test1"
|
||||
)code");
|
||||
)toml");
|
||||
EXPECT_TRUE(bResult);
|
||||
|
||||
// The default installation directory should be created.
|
||||
@@ -214,12 +213,12 @@ InstallDir = "module_test1"
|
||||
TEST_F(CModuleControl_Install, IsolatedApp_CustomInstallDirRelative)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
bool bResult = control.Startup(std::string(R"code(
|
||||
bool bResult = control.Startup(std::string(R"toml(
|
||||
[Application]
|
||||
Mode="Isolated"
|
||||
Instance=2006
|
||||
InstallDir = "module_test1"
|
||||
Connection = ")code") + Base64EncodePlainText("test") + "\"");
|
||||
Connection = ")toml") + Base64EncodePlainText("test") + "\"");
|
||||
EXPECT_TRUE(bResult);
|
||||
|
||||
// The default installation directory should be created.
|
||||
@@ -231,9 +230,9 @@ Connection = ")code") + Base64EncodePlainText("test") + "\"");
|
||||
TEST_F(CModuleControl_Install, OtherApp_CustomInstallDirRelative)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
bool bResult = control.Startup(R"code([Application]
|
||||
bool bResult = control.Startup(R"toml([Application]
|
||||
Install.Dir = "module_test1"
|
||||
)code");
|
||||
)toml");
|
||||
EXPECT_TRUE(bResult);
|
||||
|
||||
// The default installation directory should be created.
|
||||
@@ -245,11 +244,11 @@ Install.Dir = "module_test1"
|
||||
TEST_F(CModuleControl_Install, MainApp_CustomInstallDirAbsolute)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
bool bResult = control.Startup(std::string(R"code(
|
||||
bool bResult = control.Startup(std::string(R"toml(
|
||||
[Application]
|
||||
Mode="Main"
|
||||
Instance=2006
|
||||
InstallDir = ")code") + (GetExecDirectory() / "module_test2").generic_u8string() + "\"");
|
||||
InstallDir = ")toml") + (GetExecDirectory() / "module_test2").generic_u8string() + "\"");
|
||||
EXPECT_TRUE(bResult);
|
||||
|
||||
// The default installation directory should be created.
|
||||
@@ -261,12 +260,12 @@ InstallDir = ")code") + (GetExecDirectory() / "module_test2").generic_u8string()
|
||||
TEST_F(CModuleControl_Install, IsolatedApp_CustomInstallDirAbsolute)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
bool bResult = control.Startup(std::string(R"code(
|
||||
bool bResult = control.Startup(std::string(R"toml(
|
||||
[Application]
|
||||
Mode="Isolated"
|
||||
Instance=2006
|
||||
InstallDir = ")code") + (GetExecDirectory() / "module_test2").generic_u8string() + "\"" + R"code(
|
||||
Connection = ")code" + Base64EncodePlainText("test") + "\"");
|
||||
InstallDir = ")toml") + (GetExecDirectory() / "module_test2").generic_u8string() + "\"" + R"toml(
|
||||
Connection = ")toml" + Base64EncodePlainText("test") + "\"");
|
||||
EXPECT_TRUE(bResult);
|
||||
|
||||
// The default installation directory should be created.
|
||||
@@ -278,8 +277,8 @@ Connection = ")code" + Base64EncodePlainText("test") + "\"");
|
||||
TEST_F(CModuleControl_Install, OtherApp_CustomInstallDirAbsolute)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
bool bResult = control.Startup(std::string(R"code([Application]
|
||||
InstallDir = ")code") + (GetExecDirectory() / "module_test2").generic_u8string() + "\"");
|
||||
bool bResult = control.Startup(std::string(R"toml([Application]
|
||||
InstallDir = ")toml") + (GetExecDirectory() / "module_test2").generic_u8string() + "\"");
|
||||
EXPECT_TRUE(bResult);
|
||||
|
||||
// The default installation directory should be created.
|
||||
|
||||
@@ -997,12 +997,12 @@ TEST(DataDispatchServiceTest, DirectRxTxSignalConcurrency)
|
||||
// Start the threads
|
||||
std::unique_lock<std::shared_mutex> lockStart(mtxStart);
|
||||
uint32_t uiCnt = 0;
|
||||
std::thread rgPublishThreads[16];
|
||||
for (std::thread& rThread : rgPublishThreads)
|
||||
rThread = std::thread(fnPublisher, uiCnt++);
|
||||
std::thread rgConsumeThreads[16];
|
||||
for (std::thread& rThread : rgConsumeThreads)
|
||||
rThread = std::thread(fnConsumer, uiCnt++);
|
||||
sdv::core::secure_thread rgPublishThreads[16];
|
||||
for (sdv::core::secure_thread& rThread : rgPublishThreads)
|
||||
rThread = sdv::core::secure_thread(fnPublisher, uiCnt++);
|
||||
sdv::core::secure_thread rgConsumeThreads[16];
|
||||
for (sdv::core::secure_thread& rThread : rgConsumeThreads)
|
||||
rThread = sdv::core::secure_thread(fnConsumer, uiCnt++);
|
||||
|
||||
// Trigger the "GO"
|
||||
while (uiInitCnt < 32) std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
@@ -1057,9 +1057,9 @@ TEST(DataDispatchServiceTest, DirectRxTxSignalConcurrency)
|
||||
// Wait for all threads to finalize
|
||||
appcontrol.SetConfigMode();
|
||||
bShutdown = true;
|
||||
for (std::thread& rThread : rgPublishThreads)
|
||||
for (sdv::core::secure_thread& rThread : rgPublishThreads)
|
||||
if (rThread.joinable()) rThread.join();
|
||||
for (std::thread& rThread : rgConsumeThreads)
|
||||
for (sdv::core::secure_thread& rThread : rgConsumeThreads)
|
||||
if (rThread.joinable()) rThread.join();
|
||||
|
||||
signalTx1a.Reset();
|
||||
|
||||
@@ -1546,12 +1546,12 @@ TEST(DataDispatchServiceTest, TransactionalRxTxSignalConcurrency)
|
||||
// Start the threads
|
||||
std::unique_lock<std::shared_mutex> lockStart(mtxStart);
|
||||
uint32_t uiCnt = 0;
|
||||
std::thread rgPublishThreads[16];
|
||||
for (std::thread& rThread : rgPublishThreads)
|
||||
rThread = std::thread(fnPublisher, uiCnt++);
|
||||
std::thread rgConsumeThreads[nConsumeThreads];
|
||||
for (std::thread& rThread :rgConsumeThreads)
|
||||
rThread = std::thread(fnConsumer, uiCnt++);
|
||||
sdv::core::secure_thread rgPublishThreads[16];
|
||||
for (sdv::core::secure_thread& rThread : rgPublishThreads)
|
||||
rThread = sdv::core::secure_thread(fnPublisher, uiCnt++);
|
||||
sdv::core::secure_thread rgConsumeThreads[nConsumeThreads];
|
||||
for (sdv::core::secure_thread& rThread :rgConsumeThreads)
|
||||
rThread = sdv::core::secure_thread(fnConsumer, uiCnt++);
|
||||
|
||||
// Trigger the "GO"
|
||||
while (uiInitCnt < 32) std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
@@ -1630,11 +1630,11 @@ TEST(DataDispatchServiceTest, TransactionalRxTxSignalConcurrency)
|
||||
// Wait for all threads to finalize
|
||||
appcontrol.SetConfigMode();
|
||||
bShutdownPublisher = true;
|
||||
for (std::thread& rThread : rgPublishThreads)
|
||||
for (sdv::core::secure_thread& rThread : rgPublishThreads)
|
||||
if (rThread.joinable()) rThread.join();
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||
bShutdownConsumer = true;
|
||||
for (std::thread& rThread : rgConsumeThreads)
|
||||
for (sdv::core::secure_thread& rThread : rgConsumeThreads)
|
||||
if (rThread.joinable()) rThread.join();
|
||||
|
||||
// Check consume ranges
|
||||
|
||||
@@ -107,7 +107,7 @@ TEST(DbcUtilCanDLTest, SpontaneousTransmitBigEndian)
|
||||
// Start the data link
|
||||
CDbcStructDataLink dl;
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::initialization_pending);
|
||||
dl.Initialize("");
|
||||
dl.Initialize(sdv::SObjectInfo());
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::initialized);
|
||||
dl.SetOperationMode(sdv::EOperationMode::running);
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::running);
|
||||
@@ -217,7 +217,7 @@ TEST(DbcUtilCanDLTest, SpontaneousTransmit64BitBigEndian)
|
||||
// Start the data link
|
||||
CDbcStructDataLink dl;
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::initialization_pending);
|
||||
dl.Initialize("");
|
||||
dl.Initialize(sdv::SObjectInfo());
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::initialized);
|
||||
dl.SetOperationMode(sdv::EOperationMode::running);
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::running);
|
||||
@@ -361,7 +361,7 @@ TEST(DbcUtilCanDLTest, ReceiveBigEndian)
|
||||
// Start the data link
|
||||
CDbcStructDataLink dl;
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::initialization_pending);
|
||||
dl.Initialize("");
|
||||
dl.Initialize(sdv::SObjectInfo());
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::initialized);
|
||||
dl.SetOperationMode(sdv::EOperationMode::running);
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::running);
|
||||
@@ -479,7 +479,7 @@ TEST(DbcUtilCanDLTest, Receive64BitBigEndian)
|
||||
// Start the data link
|
||||
CDbcStructDataLink dl;
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::initialization_pending);
|
||||
dl.Initialize("");
|
||||
dl.Initialize(sdv::SObjectInfo());
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::initialized);
|
||||
dl.SetOperationMode(sdv::EOperationMode::running);
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::running);
|
||||
@@ -539,7 +539,7 @@ TEST(DbcUtilCanDLTest, SpontaneousTransmitLittleEndian)
|
||||
// Start the data link
|
||||
CDbcStructDataLink dl;
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::initialization_pending);
|
||||
dl.Initialize("");
|
||||
dl.Initialize(sdv::SObjectInfo());
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::initialized);
|
||||
dl.SetOperationMode(sdv::EOperationMode::running);
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::running);
|
||||
@@ -649,7 +649,7 @@ TEST(DbcUtilCanDLTest, SpontaneousTransmit64BitLittleEndian)
|
||||
// Start the data link
|
||||
CDbcStructDataLink dl;
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::initialization_pending);
|
||||
dl.Initialize("");
|
||||
dl.Initialize(sdv::SObjectInfo());
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::initialized);
|
||||
dl.SetOperationMode(sdv::EOperationMode::running);
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::running);
|
||||
@@ -793,7 +793,7 @@ TEST(DbcUtilCanDLTest, ReceiveLittleEndian)
|
||||
// Start the data link
|
||||
CDbcStructDataLink dl;
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::initialization_pending);
|
||||
dl.Initialize("");
|
||||
dl.Initialize(sdv::SObjectInfo());
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::initialized);
|
||||
dl.SetOperationMode(sdv::EOperationMode::running);
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::running);
|
||||
@@ -911,7 +911,7 @@ TEST(DbcUtilCanDLTest, Receive64BitLittleEndian)
|
||||
// Start the data link
|
||||
CDbcStructDataLink dl;
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::initialization_pending);
|
||||
dl.Initialize("");
|
||||
dl.Initialize(sdv::SObjectInfo());
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::initialized);
|
||||
dl.SetOperationMode(sdv::EOperationMode::running);
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::running);
|
||||
@@ -971,7 +971,7 @@ TEST(DbcUtilCanDLTest, SpontaneousTransactionalTransmitBigEndian)
|
||||
// Start the data link
|
||||
CDbcStructDataLink dl;
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::initialization_pending);
|
||||
dl.Initialize("");
|
||||
dl.Initialize(sdv::SObjectInfo());
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::initialized);
|
||||
dl.SetOperationMode(sdv::EOperationMode::running);
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::running);
|
||||
@@ -1064,7 +1064,7 @@ TEST(DbcUtilCanDLTest, SpontaneousTransactionalTransmitLittleEndian)
|
||||
// Start the data link
|
||||
CDbcStructDataLink dl;
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::initialization_pending);
|
||||
dl.Initialize("");
|
||||
dl.Initialize(sdv::SObjectInfo());
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::initialized);
|
||||
dl.SetOperationMode(sdv::EOperationMode::running);
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::running);
|
||||
@@ -1157,7 +1157,7 @@ TEST(DbcUtilCanDLTest, SpontaneousTransmitBigEndianAllDataTypes)
|
||||
// Start the data link
|
||||
CDbcStructDataLink dl;
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::initialization_pending);
|
||||
dl.Initialize("");
|
||||
dl.Initialize(sdv::SObjectInfo());
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::initialized);
|
||||
dl.SetOperationMode(sdv::EOperationMode::running);
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::running);
|
||||
@@ -1443,7 +1443,7 @@ TEST(DbcUtilCanDLTest, ReceiveBigEndianAllDataTypes)
|
||||
// Start the data link
|
||||
CDbcStructDataLink dl;
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::initialization_pending);
|
||||
dl.Initialize("");
|
||||
dl.Initialize(sdv::SObjectInfo());
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::initialized);
|
||||
dl.SetOperationMode(sdv::EOperationMode::running);
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::running);
|
||||
@@ -1629,7 +1629,7 @@ TEST(DbcUtilCanDLTest, SpontaneousTransmitLittleEndianAllDataTypes)
|
||||
// Start the data link
|
||||
CDbcStructDataLink dl;
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::initialization_pending);
|
||||
dl.Initialize("");
|
||||
dl.Initialize(sdv::SObjectInfo());
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::initialized);
|
||||
dl.SetOperationMode(sdv::EOperationMode::running);
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::running);
|
||||
@@ -1915,7 +1915,7 @@ TEST(DbcUtilCanDLTest, ReceiveLittleEndianAllDataTypes)
|
||||
// Start the data link
|
||||
CDbcStructDataLink dl;
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::initialization_pending);
|
||||
dl.Initialize("");
|
||||
dl.Initialize(sdv::SObjectInfo());
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::initialized);
|
||||
dl.SetOperationMode(sdv::EOperationMode::running);
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::running);
|
||||
@@ -2101,7 +2101,7 @@ TEST(DbcUtilCanDLTest, SpontaneousTransmitBigEndianScaledDataTypes)
|
||||
// Start the data link
|
||||
CDbcStructDataLink dl;
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::initialization_pending);
|
||||
dl.Initialize("");
|
||||
dl.Initialize(sdv::SObjectInfo());
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::initialized);
|
||||
dl.SetOperationMode(sdv::EOperationMode::running);
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::running);
|
||||
@@ -2271,7 +2271,7 @@ TEST(DbcUtilCanDLTest, ReceiveBigEndianScaledDataType)
|
||||
// Start the data link
|
||||
CDbcStructDataLink dl;
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::initialization_pending);
|
||||
dl.Initialize("");
|
||||
dl.Initialize(sdv::SObjectInfo());
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::initialized);
|
||||
dl.SetOperationMode(sdv::EOperationMode::running);
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::running);
|
||||
@@ -2378,7 +2378,7 @@ TEST(DbcUtilCanDLTest, SpontaneousTransmitLittleEndianScaledDataTypes)
|
||||
// Start the data link
|
||||
CDbcStructDataLink dl;
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::initialization_pending);
|
||||
dl.Initialize("");
|
||||
dl.Initialize(sdv::SObjectInfo());
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::initialized);
|
||||
dl.SetOperationMode(sdv::EOperationMode::running);
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::running);
|
||||
@@ -2548,7 +2548,7 @@ TEST(DbcUtilCanDLTest, ReceiveLittleEndianScaledDataType)
|
||||
// Start the data link
|
||||
CDbcStructDataLink dl;
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::initialization_pending);
|
||||
dl.Initialize("");
|
||||
dl.Initialize(sdv::SObjectInfo());
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::initialized);
|
||||
dl.SetOperationMode(sdv::EOperationMode::running);
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::running);
|
||||
@@ -2655,7 +2655,7 @@ TEST(DbcUtilCanDLTest, CyclicTransmit)
|
||||
// Start the data link
|
||||
CDbcStructDataLink dl;
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::initialization_pending);
|
||||
dl.Initialize("");
|
||||
dl.Initialize(sdv::SObjectInfo());
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::initialized);
|
||||
dl.SetOperationMode(sdv::EOperationMode::running);
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::running);
|
||||
@@ -2804,7 +2804,7 @@ TEST(DbcUtilCanDLTest, CyclicIfActiveTransmit)
|
||||
// Start the data link
|
||||
CDbcStructDataLink dl;
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::initialization_pending);
|
||||
dl.Initialize("");
|
||||
dl.Initialize(sdv::SObjectInfo());
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::initialized);
|
||||
dl.SetOperationMode(sdv::EOperationMode::running);
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::running);
|
||||
@@ -2971,7 +2971,7 @@ TEST(DbcUtilCanDLTest, CyclicAndSpontaneousTransmit)
|
||||
// Start the data link
|
||||
CDbcStructDataLink dl;
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::initialization_pending);
|
||||
dl.Initialize("");
|
||||
dl.Initialize(sdv::SObjectInfo());
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::initialized);
|
||||
dl.SetOperationMode(sdv::EOperationMode::running);
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::running);
|
||||
@@ -3112,7 +3112,7 @@ TEST(DbcUtilCanDLTest, SpontaneousDelayTransmit)
|
||||
// Start the data link
|
||||
CDbcStructDataLink dl;
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::initialization_pending);
|
||||
dl.Initialize("");
|
||||
dl.Initialize(sdv::SObjectInfo());
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::initialized);
|
||||
dl.SetOperationMode(sdv::EOperationMode::running);
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::running);
|
||||
@@ -3250,7 +3250,7 @@ TEST(DbcUtilCanDLTest, CyclicAndSpontaneousDelayTransmit)
|
||||
// Start the data link
|
||||
CDbcStructDataLink dl;
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::initialization_pending);
|
||||
dl.Initialize("");
|
||||
dl.Initialize(sdv::SObjectInfo());
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::initialized);
|
||||
dl.SetOperationMode(sdv::EOperationMode::running);
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::running);
|
||||
@@ -3394,7 +3394,7 @@ TEST(DbcUtilCanDLTest, CyclicIfActiveAndSpontaneousTransmit)
|
||||
// Start the data link
|
||||
CDbcStructDataLink dl;
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::initialization_pending);
|
||||
dl.Initialize("");
|
||||
dl.Initialize(sdv::SObjectInfo());
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::initialized);
|
||||
dl.SetOperationMode(sdv::EOperationMode::running);
|
||||
EXPECT_EQ(dl.GetObjectState(), sdv::EObjectState::running);
|
||||
|
||||
36
tests/component_tests/param_utils/CMakeLists.txt
Normal file
36
tests/component_tests/param_utils/CMakeLists.txt
Normal file
@@ -0,0 +1,36 @@
|
||||
#*******************************************************************************
|
||||
# Copyright (c) 2025-2026 ZF Friedrichshafen AG
|
||||
#
|
||||
# This program and the accompanying materials are made available under the
|
||||
# terms of the Apache License Version 2.0 which is available at
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Contributors:
|
||||
# Erik Verhoeven - initial API and implementation
|
||||
#*******************************************************************************
|
||||
|
||||
# Define project
|
||||
project (ComponentTest_ParamUtils VERSION 1.0 LANGUAGES CXX)
|
||||
|
||||
# Data maneger executable
|
||||
add_executable(ComponentTest_ParamUtils
|
||||
"main.cpp"
|
||||
"get_parameter.cpp"
|
||||
"resolve_text.cpp"
|
||||
)
|
||||
|
||||
target_link_libraries(ComponentTest_ParamUtils ${CMAKE_DL_LIBS} GTest::GTest)
|
||||
|
||||
# Add the ParamUtils component test
|
||||
add_test(NAME ComponentTest_ParamUtils COMMAND ComponentTest_ParamUtils WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
|
||||
|
||||
# Execute the test
|
||||
add_custom_command(TARGET ComponentTest_ParamUtils POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E env TEST_EXECUTION_MODE=CMake "$<TARGET_FILE:ComponentTest_ParamUtils>" --gtest_output=xml:${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ComponentTest_ParamUtils.xml
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
# Build dependencies
|
||||
add_dependencies(ComponentTest_ParamUtils dependency_sdv_components)
|
||||
213
tests/component_tests/param_utils/get_parameter.cpp
Normal file
213
tests/component_tests/param_utils/get_parameter.cpp
Normal file
@@ -0,0 +1,213 @@
|
||||
/********************************************************************************
|
||||
* Copyright (c) 2025-2026 ZF Friedrichshafen AG
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Apache License Version 2.0 which is available at
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Erik Verhoeven - initial API and implementation
|
||||
********************************************************************************/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <support/app_control.h>
|
||||
#include <support/local_service_access.h>
|
||||
|
||||
TEST(ParamUtils, GetParameter_FailParamInterface)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
bool bResult = control.Startup("[Application]\nMode=\"Main\"\nInstance=2010");
|
||||
ASSERT_TRUE(bResult);
|
||||
|
||||
// Get the app settings service
|
||||
sdv::TInterfaceAccessPtr ptrSystemSettings = sdv::core::GetObject("AppSettingsService");
|
||||
ASSERT_TRUE(ptrSystemSettings);
|
||||
|
||||
// Request the IParameters interface
|
||||
sdv::IParameters* pParameters = ptrSystemSettings.GetInterface<sdv::IParameters>();
|
||||
ASSERT_NE(pParameters, nullptr);
|
||||
|
||||
// Invalid parameters interface
|
||||
sdv::any_t anyFail = sdv::core::GetParameter(nullptr, "Application.InstallDir");
|
||||
EXPECT_TRUE(anyFail.empty());
|
||||
bool bExcept = false;
|
||||
try
|
||||
{
|
||||
sdv::core::GetParameter(nullptr, "Application.InstallDir", false);
|
||||
}
|
||||
catch (const std::runtime_error&)
|
||||
{
|
||||
bExcept = true;
|
||||
}
|
||||
EXPECT_TRUE(bExcept);
|
||||
|
||||
// Invalid parameters name
|
||||
anyFail = sdv::core::GetParameter(pParameters, "ParamDoesNotExist");
|
||||
EXPECT_TRUE(anyFail.empty());
|
||||
bExcept = false;
|
||||
try
|
||||
{
|
||||
sdv::core::GetParameter(pParameters, "ParamDoesNotExist", false);
|
||||
}
|
||||
catch (const std::runtime_error&)
|
||||
{
|
||||
bExcept = true;
|
||||
}
|
||||
EXPECT_TRUE(bExcept);
|
||||
|
||||
control.Shutdown();
|
||||
}
|
||||
|
||||
TEST(ParamUtils, GetParameter_FailObjectInterface)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
bool bResult = control.Startup("[Application]\nMode=\"Main\"\nInstance=2010");
|
||||
ASSERT_TRUE(bResult);
|
||||
|
||||
// Get the app settings service
|
||||
sdv::TInterfaceAccessPtr ptrSystemSettings = sdv::core::GetObject("AppSettingsService");
|
||||
ASSERT_TRUE(ptrSystemSettings);
|
||||
|
||||
// Invalid object interface
|
||||
sdv::any_t anyFail = sdv::core::GetParameter(sdv::TInterfaceAccessPtr(), "Application.InstallDir");
|
||||
EXPECT_TRUE(anyFail.empty());
|
||||
bool bExcept = false;
|
||||
try
|
||||
{
|
||||
sdv::core::GetParameter(sdv::TInterfaceAccessPtr(), "Application.InstallDir", false);
|
||||
}
|
||||
catch (const std::runtime_error&)
|
||||
{
|
||||
bExcept = true;
|
||||
}
|
||||
EXPECT_TRUE(bExcept);
|
||||
|
||||
// Invalid parameters name
|
||||
anyFail = sdv::core::GetParameter(ptrSystemSettings, "ParamDoesNotExist");
|
||||
EXPECT_TRUE(anyFail.empty());
|
||||
bExcept = false;
|
||||
try
|
||||
{
|
||||
sdv::core::GetParameter(ptrSystemSettings, "ParamDoesNotExist", false);
|
||||
}
|
||||
catch (const std::runtime_error&)
|
||||
{
|
||||
bExcept = true;
|
||||
}
|
||||
EXPECT_TRUE(bExcept);
|
||||
|
||||
control.Shutdown();
|
||||
}
|
||||
|
||||
TEST(ParamUtils, GetParameter_FailObjectName)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
bool bResult = control.Startup("[Application]\nMode=\"Main\"\nInstance=2010");
|
||||
ASSERT_TRUE(bResult);
|
||||
|
||||
// Invalid object name
|
||||
sdv::any_t anyFail = sdv::core::GetParameter("InvalidObject", "Application.InstallDir");
|
||||
EXPECT_TRUE(anyFail.empty());
|
||||
bool bExcept = false;
|
||||
try
|
||||
{
|
||||
sdv::core::GetParameter("InvalidObject", "Application.InstallDir", false);
|
||||
}
|
||||
catch (const std::runtime_error&)
|
||||
{
|
||||
bExcept = true;
|
||||
}
|
||||
EXPECT_TRUE(bExcept);
|
||||
|
||||
// Invalid parameters name
|
||||
anyFail = sdv::core::GetParameter("AppSettingsService", "ParamDoesNotExist");
|
||||
EXPECT_TRUE(anyFail.empty());
|
||||
bExcept = false;
|
||||
try
|
||||
{
|
||||
sdv::core::GetParameter("AppSettingsService", "ParamDoesNotExist", false);
|
||||
}
|
||||
catch (const std::runtime_error&)
|
||||
{
|
||||
bExcept = true;
|
||||
}
|
||||
EXPECT_TRUE(bExcept);
|
||||
|
||||
control.Shutdown();
|
||||
}
|
||||
|
||||
TEST(ParamUtils, GetParameter_ParamInterface)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
bool bResult = control.Startup("[Application]\nMode=\"Main\"\nInstance=2010");
|
||||
ASSERT_TRUE(bResult);
|
||||
|
||||
// Get the app settings service
|
||||
sdv::TInterfaceAccessPtr ptrSystemSettings = sdv::core::GetObject("AppSettingsService");
|
||||
ASSERT_TRUE(ptrSystemSettings);
|
||||
|
||||
// Request the IParameters interface
|
||||
sdv::IParameters* pParameters = ptrSystemSettings.GetInterface<sdv::IParameters>();
|
||||
ASSERT_NE(pParameters, nullptr);
|
||||
|
||||
// Request the install directory through parameters
|
||||
sdv::any_t anyInstall = sdv::core::GetParameter(pParameters, "Application.InstallDir");
|
||||
EXPECT_FALSE(anyInstall.empty());
|
||||
EXPECT_EQ(std::filesystem::relative(anyInstall.get<std::string>(), control.GetAppDirectory()), "../../bin/2010");
|
||||
|
||||
control.Shutdown();
|
||||
}
|
||||
|
||||
TEST(ParamUtils, GetParameter_ObjectInterface)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
bool bResult = control.Startup("[Application]\nMode=\"Main\"\nInstance=2010");
|
||||
ASSERT_TRUE(bResult);
|
||||
|
||||
// Get the app settings service
|
||||
sdv::TInterfaceAccessPtr ptrSystemSettings = sdv::core::GetObject("AppSettingsService");
|
||||
ASSERT_TRUE(ptrSystemSettings);
|
||||
|
||||
// Request the install directory through parameters
|
||||
sdv::any_t anyInstall = sdv::core::GetParameter(ptrSystemSettings, "Application.InstallDir");
|
||||
EXPECT_FALSE(anyInstall.empty());
|
||||
EXPECT_EQ(std::filesystem::relative(anyInstall.get<std::string>(), control.GetAppDirectory()), "../../bin/2010");
|
||||
|
||||
control.Shutdown();
|
||||
}
|
||||
|
||||
TEST(ParamUtils, GetParameter_ObjectName)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
bool bResult = control.Startup("[Application]\nMode=\"Main\"\nInstance=2010");
|
||||
ASSERT_TRUE(bResult);
|
||||
|
||||
// Request the install directory through parameters
|
||||
sdv::any_t anyInstall = sdv::core::GetParameter("AppSettingsService", "Application.InstallDir");
|
||||
EXPECT_FALSE(anyInstall.empty());
|
||||
EXPECT_EQ(std::filesystem::relative(anyInstall.get<std::string>(), control.GetAppDirectory()), "../../bin/2010");
|
||||
|
||||
control.Shutdown();
|
||||
}
|
||||
|
||||
TEST(ParamUtils, GetParameter_EnumExpand)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
bool bResult = control.Startup("[Application]\nMode=\"Main\"\nInstance=2010");
|
||||
ASSERT_TRUE(bResult);
|
||||
|
||||
// Request the mode through parameters
|
||||
sdv::any_t anyMode = sdv::core::GetParameter("AppSettingsService", "Application.Mode");
|
||||
EXPECT_FALSE(anyMode.empty());
|
||||
EXPECT_EQ(static_cast<uint64_t>(anyMode), static_cast<uint64_t>(sdv::app::EAppContext::main));
|
||||
|
||||
// Request the expanded mode through parameters
|
||||
std::string ssMode = sdv::core::GetParameterExpand("AppSettingsService", "Application.Mode");
|
||||
EXPECT_FALSE(ssMode.empty());
|
||||
EXPECT_EQ(ssMode, "Main");
|
||||
|
||||
control.Shutdown();
|
||||
}
|
||||
|
||||
27
tests/component_tests/param_utils/main.cpp
Normal file
27
tests/component_tests/param_utils/main.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
/********************************************************************************
|
||||
* Copyright (c) 2025-2026 ZF Friedrichshafen AG
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Apache License Version 2.0 which is available at
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Erik Verhoeven - initial API and implementation
|
||||
********************************************************************************/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include "../../../global/process_watchdog.h"
|
||||
|
||||
#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();
|
||||
}
|
||||
168
tests/component_tests/param_utils/resolve_text.cpp
Normal file
168
tests/component_tests/param_utils/resolve_text.cpp
Normal file
@@ -0,0 +1,168 @@
|
||||
/********************************************************************************
|
||||
* Copyright (c) 2025-2026 ZF Friedrichshafen AG
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Apache License Version 2.0 which is available at
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Erik Verhoeven - initial API and implementation
|
||||
********************************************************************************/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <support/app_control.h>
|
||||
#include <support/local_service_access.h>
|
||||
|
||||
TEST(ParamUtils, ResolveText_FailObjectName)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
bool bResult = control.Startup("[Application]\nMode=\"Main\"\nInstance=2010");
|
||||
ASSERT_TRUE(bResult);
|
||||
|
||||
// Invalid parameters interface
|
||||
std::string ssText = sdv::core::ResolveText("$(InvalidObject:Application.InstallDir)");
|
||||
EXPECT_TRUE(ssText.empty());
|
||||
bool bExcept = false;
|
||||
try
|
||||
{
|
||||
sdv::core::ResolveText("$(InvalidObject:Application.InstallDir)", true, false);
|
||||
}
|
||||
catch (const std::runtime_error&)
|
||||
{
|
||||
bExcept = true;
|
||||
}
|
||||
EXPECT_TRUE(bExcept);
|
||||
|
||||
// Invalid parameter name
|
||||
ssText = sdv::core::ResolveText("$(AppSettingsService:ParamDoesNotExist)");
|
||||
EXPECT_TRUE(ssText.empty());
|
||||
bExcept = false;
|
||||
try
|
||||
{
|
||||
sdv::core::ResolveText("$(AppSettingsService:ParamDoesNotExist)", true, false);
|
||||
}
|
||||
catch (const std::runtime_error&)
|
||||
{
|
||||
bExcept = true;
|
||||
}
|
||||
EXPECT_TRUE(bExcept);
|
||||
|
||||
control.Shutdown();
|
||||
}
|
||||
|
||||
TEST(ParamUtils, ResolveText_EscapingDollarCharacter)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
bool bResult = control.Startup("[Application]\nMode=\"Main\"\nInstance=2010");
|
||||
ASSERT_TRUE(bResult);
|
||||
|
||||
// Not escaping $ - this is allowed!
|
||||
std::string ssText = sdv::core::ResolveText("There is a $ in this text.");
|
||||
EXPECT_FALSE(ssText.empty());
|
||||
EXPECT_EQ(ssText, "There is a $ in this text.");
|
||||
bool bExcept = false;
|
||||
ssText.clear();
|
||||
try
|
||||
{
|
||||
ssText = sdv::core::ResolveText("There is a $ in this text.", true, false);
|
||||
}
|
||||
catch (const std::runtime_error&)
|
||||
{
|
||||
bExcept = true;
|
||||
}
|
||||
EXPECT_FALSE(bExcept);
|
||||
EXPECT_EQ(ssText, "There is a $ in this text.");
|
||||
|
||||
// Missing (-character - this is the same as not escaping $
|
||||
ssText = sdv::core::ResolveText("$AppSettingsService:Application.InstallDir)");
|
||||
EXPECT_FALSE(ssText.empty());
|
||||
EXPECT_EQ(ssText, "$AppSettingsService:Application.InstallDir)");
|
||||
bExcept = false;
|
||||
ssText.clear();
|
||||
try
|
||||
{
|
||||
ssText = sdv::core::ResolveText("$AppSettingsService:Application.InstallDir)", true, false);
|
||||
}
|
||||
catch (const std::runtime_error&)
|
||||
{
|
||||
bExcept = true;
|
||||
}
|
||||
EXPECT_FALSE(bExcept);
|
||||
EXPECT_EQ(ssText, "$AppSettingsService:Application.InstallDir)");
|
||||
|
||||
// Missing )-character - this is an error
|
||||
ssText = sdv::core::ResolveText("$(AppSettingsService:Application.InstallDir");
|
||||
EXPECT_TRUE(ssText.empty());
|
||||
bExcept = false;
|
||||
try
|
||||
{
|
||||
sdv::core::ResolveText("$(AppSettingsService:Application.InstallDir", true, false);
|
||||
}
|
||||
catch (const std::runtime_error&)
|
||||
{
|
||||
bExcept = true;
|
||||
}
|
||||
EXPECT_TRUE(bExcept);
|
||||
|
||||
// Invalid object-param pair
|
||||
ssText = sdv::core::ResolveText("$(Application.InstallDir)");
|
||||
EXPECT_TRUE(ssText.empty());
|
||||
bExcept = false;
|
||||
try
|
||||
{
|
||||
sdv::core::ResolveText("$(Application.InstallDir)", true, false);
|
||||
}
|
||||
catch (const std::runtime_error&)
|
||||
{
|
||||
bExcept = true;
|
||||
}
|
||||
EXPECT_TRUE(bExcept);
|
||||
|
||||
// Resolvinf during first iteration
|
||||
ssText = sdv::core::ResolveText("$(AppSettingsService:Application.Mode)");
|
||||
EXPECT_EQ(ssText, "Main");
|
||||
|
||||
// Resolving during second iteration
|
||||
ssText = sdv::core::ResolveText("\\$(AppSettingsService:Application.Mode)");
|
||||
EXPECT_EQ(ssText, "Main");
|
||||
|
||||
// No further iteration
|
||||
ssText = sdv::core::ResolveText("\\$(AppSettingsService:Application.Mode)", false);
|
||||
EXPECT_EQ(ssText, "$(AppSettingsService:Application.Mode)");
|
||||
|
||||
control.Shutdown();
|
||||
}
|
||||
|
||||
TEST(ParamUtils, ResolveText_Object)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
bool bResult = control.Startup("[Application]\nMode=\"Main\"\nInstance=2010");
|
||||
ASSERT_TRUE(bResult);
|
||||
|
||||
// Request the install directory through parameters
|
||||
std::string ssText = sdv::core::ResolveText("$(AppSettingsService:Application.InstallDir)/MyPackage");
|
||||
EXPECT_FALSE(ssText.empty());
|
||||
EXPECT_EQ(std::filesystem::relative(ssText, control.GetAppDirectory()), "../../bin/2010/MyPackage");
|
||||
|
||||
// Request the install directory through parameters
|
||||
ssText = sdv::core::ResolveText("The application mode is \"$( AppSettingsService : Application.Mode )\" and the instance numbver is $(AppSettingsService:Application.Instance).");
|
||||
EXPECT_FALSE(ssText.empty());
|
||||
EXPECT_EQ(ssText, "The application mode is \"Main\" and the instance numbver is 2010.");
|
||||
|
||||
ssText = sdv::core::ResolveText("The application mode is \"$(AppSettingsService:Application.Mode)\" and the instance number "
|
||||
"is $(AppSettingsService:Application.Instance).");
|
||||
EXPECT_FALSE(ssText.empty());
|
||||
EXPECT_EQ(ssText, "The application mode is \"Main\" and the instance number is 2010.");
|
||||
|
||||
// Request the install directory through parameters
|
||||
ssText = sdv::core::ResolveText("Valid text with a \\$ in the text...");
|
||||
EXPECT_FALSE(ssText.empty());
|
||||
EXPECT_EQ(ssText, "Valid text with a $ in the text...");
|
||||
|
||||
control.Shutdown();
|
||||
}
|
||||
|
||||
// TODO: Recursive test
|
||||
// e.g. \$($(MyObject1:Name):$(MyObject2:ParamName))
|
||||
@@ -57,7 +57,7 @@ set_target_properties(ComponentTest_Repository_test_module PROPERTIES SUFFIX ".s
|
||||
|
||||
# Execute the installation helper utility to create an installation manifest for the core files.
|
||||
add_custom_target(ComponentTest_Repository_install_manifest
|
||||
COMMAND "$<TARGET_FILE:sdv_packager>" DIRECT_INSTALL ComponentTest_Repository -T. --instance2005 "$<TARGET_FILE:ComponentTest_Repository_test_module>" "$<TARGET_FILE:ComponentTest_Repository_ps>" "-I$<TARGET_FILE_DIR:ComponentTest_Repository_test_module>" --overwrite --user_config+TestObject_ComplexHelloService+TestObject_HelloUtility --interface_config+Example_Object+Example_Object_2+TestObject_HelloDevice+TestObject_BasicHelloService+TestObject_SystemHelloService
|
||||
COMMAND "$<TARGET_FILE:sdv_packager>" DIRECT_INSTALL ComponentTest_Repository --instance2005 "$<TARGET_FILE:ComponentTest_Repository_test_module>" "$<TARGET_FILE:ComponentTest_Repository_ps>" "-I$<TARGET_FILE_DIR:ComponentTest_Repository_test_module>" --overwrite --user_config+TestObject_ComplexHelloService+TestObject_HelloUtility --interface_config+Example_Object+Example_Object_2+TestObject_HelloDevice+TestObject_BasicHelloService+TestObject_SystemHelloService
|
||||
DEPENDS ComponentTest_Repository_test_module ComponentTest_Repository_ps
|
||||
WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
|
||||
)
|
||||
|
||||
@@ -44,14 +44,18 @@ public:
|
||||
*/
|
||||
virtual void SetUp()
|
||||
{
|
||||
bool bRet = Startup(R"code(
|
||||
bool bRet = Startup(R"toml(
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
|
||||
[Application]
|
||||
Mode = "Main"
|
||||
Instance = 2005
|
||||
)code");
|
||||
|
||||
[Console]
|
||||
Report = "Silent"
|
||||
RedirectMon = true
|
||||
)toml");
|
||||
if (!bRet)
|
||||
std::cout << "Failed to start the application for instance 2005." << std::endl;
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ public:
|
||||
SDV_INTERFACE_ENTRY(sdv::IObjectControl)
|
||||
END_SDV_INTERFACE_MAP()
|
||||
|
||||
virtual void Initialize([[maybe_unused]] const sdv::u8string& ssObjectConfig) override
|
||||
virtual void Initialize([[maybe_unused]] const sdv::SObjectInfo& sObjectInfo) override
|
||||
{
|
||||
FAIL() << "Error: Initialize should not be called by Repo Service!";
|
||||
// m_eObjectState = sdv::EObjectState::initialization_failure;
|
||||
@@ -83,13 +83,13 @@ public:
|
||||
|
||||
TEST(RepositoryTest, LoadNonexistentModule)
|
||||
{
|
||||
sdv::app::CAppControl control(R"code(
|
||||
sdv::app::CAppControl control(R"toml(
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
)code");
|
||||
)toml");
|
||||
ASSERT_TRUE(control.IsRunning());
|
||||
control.SetConfigMode();
|
||||
|
||||
@@ -105,13 +105,13 @@ Mode = "Essential"
|
||||
|
||||
TEST(RepositoryTest, CreateNonexistantClass)
|
||||
{
|
||||
sdv::app::CAppControl control(R"code(
|
||||
sdv::app::CAppControl control(R"toml(
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
)code");
|
||||
)toml");
|
||||
ASSERT_TRUE(control.IsRunning());
|
||||
control.SetConfigMode();
|
||||
|
||||
@@ -129,13 +129,13 @@ Mode = "Essential"
|
||||
|
||||
TEST(RepositoryTest, GetNonexistantObject)
|
||||
{
|
||||
sdv::app::CAppControl control(R"code(
|
||||
sdv::app::CAppControl control(R"toml(
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
)code");
|
||||
)toml");
|
||||
ASSERT_TRUE(control.IsRunning());
|
||||
control.SetConfigMode();
|
||||
|
||||
@@ -158,13 +158,13 @@ Mode = "Essential"
|
||||
|
||||
TEST(RepositoryTest, InstantiateAndGet)
|
||||
{
|
||||
sdv::app::CAppControl control(R"code(
|
||||
sdv::app::CAppControl control(R"toml(
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
)code");
|
||||
)toml");
|
||||
ASSERT_TRUE(control.IsRunning());
|
||||
control.SetConfigMode();
|
||||
|
||||
@@ -189,13 +189,13 @@ Mode = "Essential"
|
||||
|
||||
TEST(RepositoryTest, InstantiateInitFail)
|
||||
{
|
||||
sdv::app::CAppControl control(R"code(
|
||||
sdv::app::CAppControl control(R"toml(
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
)code");
|
||||
)toml");
|
||||
ASSERT_TRUE(control.IsRunning());
|
||||
control.SetConfigMode();
|
||||
|
||||
@@ -218,13 +218,13 @@ Mode = "Essential"
|
||||
|
||||
TEST(RepositoryTest, InstantiateDuplicateCreateObjectName)
|
||||
{
|
||||
sdv::app::CAppControl control(R"code(
|
||||
sdv::app::CAppControl control(R"toml(
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
)code");
|
||||
)toml");
|
||||
ASSERT_TRUE(control.IsRunning());
|
||||
control.SetConfigMode();
|
||||
|
||||
@@ -255,13 +255,13 @@ Mode = "Essential"
|
||||
|
||||
TEST(RepositoryTest, InstantiateDuplicateExternalObjectName)
|
||||
{
|
||||
sdv::app::CAppControl control(R"code(
|
||||
sdv::app::CAppControl control(R"toml(
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
)code");
|
||||
)toml");
|
||||
ASSERT_TRUE(control.IsRunning());
|
||||
control.SetConfigMode();
|
||||
|
||||
@@ -290,13 +290,13 @@ Mode = "Essential"
|
||||
|
||||
TEST(RepositoryTest, InstantiateDuplicateObjectNameMixed)
|
||||
{
|
||||
sdv::app::CAppControl control(R"code(
|
||||
sdv::app::CAppControl control(R"toml(
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
)code");
|
||||
)toml");
|
||||
ASSERT_TRUE(control.IsRunning());
|
||||
control.SetConfigMode();
|
||||
|
||||
@@ -327,13 +327,13 @@ Mode = "Essential"
|
||||
|
||||
TEST(RepositoryTest, InstantiateTwoNamedInstances)
|
||||
{
|
||||
sdv::app::CAppControl control(R"code(
|
||||
sdv::app::CAppControl control(R"toml(
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
)code");
|
||||
)toml");
|
||||
ASSERT_TRUE(control.IsRunning());
|
||||
control.SetConfigMode();
|
||||
|
||||
@@ -365,13 +365,13 @@ Mode = "Essential"
|
||||
|
||||
TEST(RepositoryTest, ChainCreateSimple)
|
||||
{
|
||||
sdv::app::CAppControl control(R"code(
|
||||
sdv::app::CAppControl control(R"toml(
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
)code");
|
||||
)toml");
|
||||
ASSERT_TRUE(control.IsRunning());
|
||||
control.SetConfigMode();
|
||||
|
||||
@@ -398,13 +398,13 @@ Mode = "Essential"
|
||||
|
||||
TEST(RepositoryTest, ChainCreateParallel)
|
||||
{
|
||||
sdv::app::CAppControl control(R"code(
|
||||
sdv::app::CAppControl control(R"toml(
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
)code");
|
||||
)toml");
|
||||
ASSERT_TRUE(control.IsRunning());
|
||||
control.SetConfigMode();
|
||||
|
||||
@@ -417,43 +417,47 @@ Mode = "Essential"
|
||||
|
||||
ASSERT_TRUE(pModuleControl->Load((GetExecDirectory() / "ComponentTest_Repository_test_module.sdv").generic_u8string()));
|
||||
|
||||
std::thread testThread([pRepositoryControl, pObjectAccess]()
|
||||
sdv::core::secure_thread testThread(
|
||||
[pRepositoryControl, pObjectAccess]()
|
||||
{
|
||||
for (uint32_t i = 0; i < LoopCount; ++i)
|
||||
{
|
||||
std::string count = std::to_string(i);
|
||||
bool bRes = pRepositoryControl->CreateObject("TestObject_CreateChain", "Bar_" + count,
|
||||
"chained_object = \"BarFoo_" + count + "\"");
|
||||
bool bRes = pRepositoryControl->CreateObject(
|
||||
"TestObject_CreateChain", "Bar_" + count, "chained_object = \"BarFoo_" + count + "\"");
|
||||
EXPECT_TRUE(bRes);
|
||||
EXPECT_NE(nullptr, pObjectAccess->GetObject("BarFoo_" + count));
|
||||
}
|
||||
});
|
||||
|
||||
// TEMP EVE 05.05.2026: The parallel execution of the creation threads causes a sporadic crash.
|
||||
// See: https://dev.azure.com/SW4ZF/AZP-431_DivDI_Vehicle_API/_workitems/edit/799698
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||
|
||||
for (uint32_t i = 0; i < LoopCount; ++i)
|
||||
{
|
||||
std::string count = std::to_string(i);
|
||||
bool bRes =
|
||||
pRepositoryControl->CreateObject("TestObject_CreateChain", "Foo_" + count, "chained_object =\"FooBar_" + count + "\"");
|
||||
bool bRes = pRepositoryControl->CreateObject(
|
||||
"TestObject_CreateChain", "Foo_" + count, "chained_object =\"FooBar_" + count + "\"");
|
||||
EXPECT_TRUE(bRes);
|
||||
EXPECT_NE(nullptr, pObjectAccess->GetObject("FooBar_" + count));
|
||||
}
|
||||
|
||||
testThread.join();
|
||||
|
||||
|
||||
control.SetRunningMode();
|
||||
control.Shutdown();
|
||||
}
|
||||
|
||||
TEST(RepositoryTest, ChainCreateParallelLock)
|
||||
{
|
||||
sdv::app::CAppControl control(R"code(
|
||||
sdv::app::CAppControl control(R"toml(
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
)code");
|
||||
)toml");
|
||||
ASSERT_TRUE(control.IsRunning());
|
||||
control.SetConfigMode();
|
||||
|
||||
@@ -474,7 +478,7 @@ Mode = "Essential"
|
||||
|
||||
//attempt to create deadlock by taking lock during initialize and by taking lock before call to create object
|
||||
|
||||
std::thread testThread([&]()
|
||||
sdv::core::secure_thread testThread([&]()
|
||||
{
|
||||
for (uint32_t i = 0; i < LoopCount; ++i)
|
||||
{
|
||||
@@ -507,13 +511,13 @@ Mode = "Essential"
|
||||
|
||||
TEST(RepositoryTest, ChainCreateParallelThreadLock)
|
||||
{
|
||||
sdv::app::CAppControl control(R"code(
|
||||
sdv::app::CAppControl control(R"toml(
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
)code");
|
||||
)toml");
|
||||
ASSERT_TRUE(control.IsRunning());
|
||||
control.SetConfigMode();
|
||||
|
||||
@@ -534,7 +538,7 @@ Mode = "Essential"
|
||||
|
||||
//attempt to create deadlock by taking lock during initialize and by taking lock before call to create object
|
||||
|
||||
std::thread testThread([&]()
|
||||
sdv::core::secure_thread testThread([&]()
|
||||
{
|
||||
for (uint32_t i = 0; i < LoopCount; ++i)
|
||||
{
|
||||
@@ -567,13 +571,13 @@ Mode = "Essential"
|
||||
|
||||
TEST(RepositoryTest, InstantiateDuringShutdown)
|
||||
{
|
||||
sdv::app::CAppControl control(R"code(
|
||||
sdv::app::CAppControl control(R"toml(
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
)code");
|
||||
)toml");
|
||||
ASSERT_TRUE(control.IsRunning());
|
||||
control.SetConfigMode();
|
||||
|
||||
@@ -598,13 +602,13 @@ Mode = "Essential"
|
||||
|
||||
TEST(RepositoryTest, CreateUtility)
|
||||
{
|
||||
sdv::app::CAppControl control(R"code(
|
||||
sdv::app::CAppControl control(R"toml(
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
)code");
|
||||
)toml");
|
||||
ASSERT_TRUE(control.IsRunning());
|
||||
control.SetConfigMode();
|
||||
|
||||
@@ -621,14 +625,18 @@ TEST(RepositoryTest, MainApplication_GetInstalledAndLoadedComponent)
|
||||
{
|
||||
// Start the app control. The application automatically loads the installation manifests and the application configuration,
|
||||
// starting automatically the objects.
|
||||
sdv::app::CAppControl control(R"code(
|
||||
sdv::app::CAppControl control(R"toml(
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
|
||||
[Application]
|
||||
Mode = "Main"
|
||||
Instance = 2005
|
||||
)code");
|
||||
|
||||
[Console]
|
||||
Report = "Silent"
|
||||
RedirectMon = true
|
||||
)toml");
|
||||
ASSERT_TRUE(control.IsRunning());
|
||||
control.SetConfigMode();
|
||||
|
||||
@@ -644,7 +652,7 @@ TEST(RepositoryTest, MainApplication_GetInstalledComponent)
|
||||
{
|
||||
// Start the app control. The application automatically loads the installation manifests, but since there is no application
|
||||
// configuration, it doesn't load the objects.
|
||||
sdv::app::CAppControl control(R"code(
|
||||
sdv::app::CAppControl control(R"toml(
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
|
||||
@@ -652,7 +660,11 @@ ViewFilter = "Fatal"
|
||||
Mode = "Main"
|
||||
Instance = 2005
|
||||
AppConfig = "" # override application config
|
||||
)code");
|
||||
|
||||
[Console]
|
||||
Report = "Silent"
|
||||
RedirectMon = true
|
||||
)toml");
|
||||
ASSERT_TRUE(control.IsRunning());
|
||||
control.SetConfigMode();
|
||||
|
||||
|
||||
@@ -306,7 +306,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
std::thread testThread(fun);
|
||||
sdv::core::secure_thread testThread(fun);
|
||||
|
||||
testThread.join();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user