connection between 2 systems and bug fixes (#14)

This commit is contained in:
tompzf
2026-07-03 14:53:48 +02:00
committed by GitHub
parent 0fb5660d27
commit 46842200f1
284 changed files with 35200 additions and 8265 deletions

View File

@@ -17,8 +17,10 @@ project (UnitTest_IPC_Connect VERSION 1.0 LANGUAGES CXX)
# Compile the source code
add_executable(UnitTest_IPC_Connect
"main.cpp"
"ipc_connect.cpp"
"ipc_connect_shared_mem.cpp"
"ipc_connect_false_positiv.cpp"
"ipc_connect_uds.cpp"
"ipc_connect_uds_tunnel.cpp"
)
target_link_libraries(UnitTest_IPC_Connect ${CMAKE_DL_LIBS} GTest::GTest)

View File

@@ -1,307 +0,0 @@
/********************************************************************************
* 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 "../../include/gtest_custom.h"
#include <support/sdv_core.h>
#include <support/app_control.h>
#include <support/pssup.h>
#include "../../../sdv_services/ipc_connect/listener.h"
#include "../../../sdv_services/ipc_connect/client.h"
TEST(IPC_Connect_Test, InstantiateLocalDefaultListener)
{
// Initialize system
sdv::app::CAppControl appcontrol;
ASSERT_TRUE(appcontrol.Startup(R"config(
[Application]
Mode = "Essential"
[LogHandler]
ViewFilter = "Fatal"
)config"));
ASSERT_TRUE(appcontrol.IsRunning());
sdv::core::IModuleControl* pModuleControl = sdv::core::GetObject<sdv::core::IModuleControl>("ModuleControlService");
ASSERT_NE(pModuleControl, nullptr);
EXPECT_NE(pModuleControl->Load("ipc_com.sdv"), 0);
EXPECT_NE(pModuleControl->Load("ipc_shared_mem.sdv"), 0);
EXPECT_NE(pModuleControl->Load("core_ps.sdv"), 0);
sdv::core::IRepositoryControl* pRepositoryControl = sdv::core::GetObject<sdv::core::IRepositoryControl>("RepositoryService");
ASSERT_NE(pRepositoryControl, nullptr);
EXPECT_NE(pRepositoryControl->CreateObject("CommunicationControl", {}, {}), 0);
EXPECT_NE(pRepositoryControl->CreateObject("DefaultSharedMemoryChannelControl", {}, {}), 0);
// Start listener
CListener listener;
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::initialization_pending);
listener.Initialize(R"code([Listener]
Type = "Local"
)code");
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::initialized);
// Shutdown
listener.Shutdown();
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::destruction_pending);
appcontrol.Shutdown();
}
TEST(IPC_Connect_Test, InstantiateLocalDedicatedListener)
{
// Initialize system
sdv::app::CAppControl appcontrol;
ASSERT_TRUE(appcontrol.Startup(R"config(
[Application]
Mode = "Essential"
[LogHandler]
ViewFilter = "Fatal"
)config"));
ASSERT_TRUE(appcontrol.IsRunning());
sdv::core::IModuleControl* pModuleControl = sdv::core::GetObject<sdv::core::IModuleControl>("ModuleControlService");
ASSERT_NE(pModuleControl, nullptr);
EXPECT_NE(pModuleControl->Load("ipc_com.sdv"), 0);
EXPECT_NE(pModuleControl->Load("ipc_shared_mem.sdv"), 0);
EXPECT_NE(pModuleControl->Load("core_ps.sdv"), 0);
sdv::core::IRepositoryControl* pRepositoryControl = sdv::core::GetObject<sdv::core::IRepositoryControl>("RepositoryService");
ASSERT_NE(pRepositoryControl, nullptr);
EXPECT_NE(pRepositoryControl->CreateObject("CommunicationControl", {}, {}), 0);
EXPECT_NE(pRepositoryControl->CreateObject("DefaultSharedMemoryChannelControl", {}, {}), 0);
// Start listener
CListener listener;
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::initialization_pending);
listener.Initialize(R"code([Listener]
Type = "Local"
Instance = 1234
)code");
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::initialized);
// Shutdown
listener.Shutdown();
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::destruction_pending);
appcontrol.Shutdown();
}
TEST(IPC_Connect_Test, InstantiateLocalDefaultClientNoListener)
{
// Initialize system
sdv::app::CAppControl appcontrol;
ASSERT_TRUE(appcontrol.Startup(R"config(
[Application]
Mode = "Essential"
[LogHandler]
ViewFilter = "Fatal"
)config"));
ASSERT_TRUE(appcontrol.IsRunning());
sdv::core::IModuleControl* pModuleControl = sdv::core::GetObject<sdv::core::IModuleControl>("ModuleControlService");
ASSERT_NE(pModuleControl, nullptr);
EXPECT_NE(pModuleControl->Load("ipc_com.sdv"), 0);
EXPECT_NE(pModuleControl->Load("ipc_shared_mem.sdv"), 0);
EXPECT_NE(pModuleControl->Load("core_ps.sdv"), 0);
sdv::core::IRepositoryControl* pRepositoryControl = sdv::core::GetObject<sdv::core::IRepositoryControl>("RepositoryService");
ASSERT_NE(pRepositoryControl, nullptr);
EXPECT_NE(pRepositoryControl->CreateObject("CommunicationControl", {}, {}), 0);
EXPECT_NE(pRepositoryControl->CreateObject("DefaultSharedMemoryChannelControl", {}, {}), 0);
// Start client
CClient client;
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::initialization_pending);
client.Initialize("");
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::initialized);
sdv::TObjectPtr ptrClient = client.Connect(R"code([Client]
Type = "local"
)code");
EXPECT_FALSE(ptrClient);
// Shutdown
ptrClient.Clear();
client.Shutdown();
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::destruction_pending);
appcontrol.Shutdown();
}
TEST(IPC_Connect_Test, InstantiateLocalSpecificClientNoListener)
{
// Initialize system
sdv::app::CAppControl appcontrol;
ASSERT_TRUE(appcontrol.Startup(R"config(
[Application]
Mode = "Essential"
[LogHandler]
ViewFilter = "Fatal"
)config"));
ASSERT_TRUE(appcontrol.IsRunning());
sdv::core::IModuleControl* pModuleControl = sdv::core::GetObject<sdv::core::IModuleControl>("ModuleControlService");
ASSERT_NE(pModuleControl, nullptr);
EXPECT_NE(pModuleControl->Load("ipc_com.sdv"), 0);
EXPECT_NE(pModuleControl->Load("ipc_shared_mem.sdv"), 0);
EXPECT_NE(pModuleControl->Load("core_ps.sdv"), 0);
sdv::core::IRepositoryControl* pRepositoryControl = sdv::core::GetObject<sdv::core::IRepositoryControl>("RepositoryService");
ASSERT_NE(pRepositoryControl, nullptr);
EXPECT_NE(pRepositoryControl->CreateObject("CommunicationControl", {}, {}), 0);
EXPECT_NE(pRepositoryControl->CreateObject("DefaultSharedMemoryChannelControl", {}, {}), 0);
// Start client
CClient client;
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::initialization_pending);
client.Initialize("");
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::initialized);
sdv::TObjectPtr ptrClient = client.Connect(R"code([Client]
Type = "local"
Instance = 1234
)code");
EXPECT_FALSE(ptrClient);
// Shutdown
ptrClient.Clear();
client.Shutdown();
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::destruction_pending);
appcontrol.Shutdown();
}
// Disabled the following test due to an unidentified crash/heap corruption occurring with MINGW on the build-server.
// Bug-report #610009 describes this issue: https://dev.azure.com/SW4ZF/AZP-074_DivDI_SofDCarResearch/_workitems/edit/610009
#ifdef _WIN32
TEST(IPC_Connect_Test, DISABLED_InstantiateLocalDefaultClientAndListener)
#else
TEST(IPC_Connect_Test, InstantiateLocalDefaultClientAndListener)
#endif
{
// Initialize system
sdv::app::CAppControl appcontrol;
ASSERT_TRUE(appcontrol.Startup(R"config(
[Application]
Mode = "Essential"
[LogHandler]
ViewFilter = "Fatal"
)config"));
ASSERT_TRUE(appcontrol.IsRunning());
sdv::core::IModuleControl* pModuleControl = sdv::core::GetObject<sdv::core::IModuleControl>("ModuleControlService");
ASSERT_NE(pModuleControl, nullptr);
EXPECT_NE(pModuleControl->Load("ipc_com.sdv"), 0);
EXPECT_NE(pModuleControl->Load("ipc_shared_mem.sdv"), 0);
EXPECT_NE(pModuleControl->Load("core_ps.sdv"), 0);
sdv::core::IRepositoryControl* pRepositoryControl = sdv::core::GetObject<sdv::core::IRepositoryControl>("RepositoryService");
ASSERT_NE(pRepositoryControl, nullptr);
EXPECT_NE(pRepositoryControl->CreateObject("CommunicationControl", {}, {}), 0);
EXPECT_NE(pRepositoryControl->CreateObject("DefaultSharedMemoryChannelControl", {}, {}), 0);
// Start listener
CListener listener;
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::initialization_pending);
listener.Initialize(R"code([Listener]
Type = "Local"
)code");
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::initialized);
// Start client
CClient client;
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::initialization_pending);
client.Initialize("");
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::initialized);
sdv::TObjectPtr ptrClient = client.Connect(R"code([Client]
Type = "Local"
)code");
EXPECT_TRUE(ptrClient);
// The client is a pointer to the repository. Request the module control service
sdv::core::IObjectAccess* pObjectAccess = ptrClient.GetInterface<sdv::core::IObjectAccess>();
EXPECT_NE(pObjectAccess, nullptr);
sdv::core::IModuleInfo* pModuleInfo = nullptr;
if (pObjectAccess)
pModuleInfo = sdv::TInterfaceAccessPtr(pObjectAccess->GetObject("ModuleControlService")).GetInterface<sdv::core::IModuleInfo>();
EXPECT_NE(pModuleInfo, nullptr);
if (pModuleInfo)
{
EXPECT_FALSE(pModuleInfo->GetModuleList().empty());
}
// Shutdown
ptrClient.Clear();
client.Shutdown();
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::destruction_pending);
listener.Shutdown();
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::destruction_pending);
appcontrol.Shutdown();
}
// Disabled the following test due to an unidentified crash/heap corruption occurring with MINGW on the build-server.
// Bug-report #610009 describes this issue: https://dev.azure.com/SW4ZF/AZP-074_DivDI_SofDCarResearch/_workitems/edit/610009
#ifdef _WIN32
TEST(IPC_Connect_Test, DISABLED_InstantiateLocalSpecificClientAndListener)
#else
TEST(IPC_Connect_Test, InstantiateLocalSpecificClientAndListener)
#endif
{
// Initialize system
sdv::app::CAppControl appcontrol;
ASSERT_TRUE(appcontrol.Startup(R"config(
[Application]
Mode = "Essential"
[LogHandler]
ViewFilter = "Fatal"
)config"));
ASSERT_TRUE(appcontrol.IsRunning());
sdv::core::IModuleControl* pModuleControl = sdv::core::GetObject<sdv::core::IModuleControl>("ModuleControlService");
ASSERT_NE(pModuleControl, nullptr);
EXPECT_NE(pModuleControl->Load("ipc_com.sdv"), 0);
EXPECT_NE(pModuleControl->Load("ipc_shared_mem.sdv"), 0);
EXPECT_NE(pModuleControl->Load("core_ps.sdv"), 0);
sdv::core::IRepositoryControl* pRepositoryControl = sdv::core::GetObject<sdv::core::IRepositoryControl>("RepositoryService");
ASSERT_NE(pRepositoryControl, nullptr);
EXPECT_NE(pRepositoryControl->CreateObject("CommunicationControl", {}, {}), 0);
EXPECT_NE(pRepositoryControl->CreateObject("DefaultSharedMemoryChannelControl", {}, {}), 0);
// Start listener
CListener listener;
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::initialization_pending);
listener.Initialize(R"code([Listener]
Type = "Local"
Instance = 1234
)code");
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::initialized);
// Start client
CClient client;
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::initialization_pending);
client.Initialize("");
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::initialized);
sdv::TObjectPtr ptrClient = client.Connect(R"code([Client]
Type = "Local"
Instance = 1234
)code");
EXPECT_TRUE(ptrClient);
// The client is a pointer to the repository. Request the module control service
sdv::core::IObjectAccess* pObjectAccess = ptrClient.GetInterface<sdv::core::IObjectAccess>();
EXPECT_NE(pObjectAccess, nullptr);
sdv::core::IModuleInfo* pModuleInfo = nullptr;
if (pObjectAccess)
pModuleInfo = sdv::TInterfaceAccessPtr(pObjectAccess->GetObject("ModuleControlService")).GetInterface<sdv::core::IModuleInfo>();
EXPECT_NE(pModuleInfo, nullptr);
if (pModuleInfo)
{
EXPECT_FALSE(pModuleInfo->GetModuleList().empty());
}
// Shutdown
ptrClient.Clear();
client.Shutdown();
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::destruction_pending);
listener.Shutdown();
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::destruction_pending);
appcontrol.Shutdown();
}

View File

@@ -0,0 +1,86 @@
/********************************************************************************
* 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 <support/app_control.h>
#include <support/pssup.h>
#include <support/sdv_core.h>
#include "../../../sdv_services/ipc_connect/client.h"
#include "../../../sdv_services/ipc_connect/listener.h"
#include "../../include/gtest_custom.h"
TEST(IPC_Connect_Test, InstantiateListenerWithUnknownProvider)
{
// Initialize system
sdv::app::CAppControl appcontrol;
ASSERT_TRUE(appcontrol.Startup(R"config(
[Application]
Mode = "Essential"
[LogHandler]
ViewFilter = "Fatal"
)config"));
ASSERT_TRUE(appcontrol.IsRunning());
sdv::core::IModuleControl* pModuleControl = sdv::core::GetObject<sdv::core::IModuleControl>("ModuleControlService");
ASSERT_NE(pModuleControl, nullptr);
EXPECT_NE(pModuleControl->Load("ipc_com.sdv"), 0);
EXPECT_NE(pModuleControl->Load("ipc_shared_mem.sdv"), 0);
EXPECT_NE(pModuleControl->Load("core_ps.sdv"), 0);
sdv::core::IRepositoryControl* pRepositoryControl = sdv::core::GetObject<sdv::core::IRepositoryControl>("RepositoryService");
ASSERT_NE(pRepositoryControl, nullptr);
EXPECT_NE(pRepositoryControl->CreateObject("CommunicationControl", {}, {}), 0);
EXPECT_NE(pRepositoryControl->CreateObject("DefaultSharedMemory", {}, {}), 0);
// Start listener
CListener listener;
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::initialization_pending);
listener.Initialize(sdv::SObjectInfo());
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::initialization_failure);
// Shutdown
listener.Shutdown();
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::destruction_pending);
appcontrol.Shutdown();
}
TEST(IPC_Connect_Test_Shared_Mem, InstantiateClientWithoutConfiguration)
{
// Initialize system
sdv::app::CAppControl appcontrol;
ASSERT_TRUE(appcontrol.Startup(R"config(
[Application]
Mode = "Essential"
[LogHandler]
ViewFilter = "Fatal"
)config"));
ASSERT_TRUE(appcontrol.IsRunning());
sdv::core::IModuleControl* pModuleControl = sdv::core::GetObject<sdv::core::IModuleControl>("ModuleControlService");
ASSERT_NE(pModuleControl, nullptr);
EXPECT_NE(pModuleControl->Load("ipc_com.sdv"), 0);
EXPECT_NE(pModuleControl->Load("ipc_shared_mem.sdv"), 0);
EXPECT_NE(pModuleControl->Load("core_ps.sdv"), 0);
sdv::core::IRepositoryControl* pRepositoryControl = sdv::core::GetObject<sdv::core::IRepositoryControl>("RepositoryService");
ASSERT_NE(pRepositoryControl, nullptr);
EXPECT_NE(pRepositoryControl->CreateObject("CommunicationControl", {}, {}), 0);
// Start client without configuration
CClientConnect client;
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::initialization_pending);
client.Initialize(sdv::SObjectInfo());
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::initialization_failure);
client.Shutdown();
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::destruction_pending);
appcontrol.Shutdown();
}

View File

@@ -0,0 +1,181 @@
/********************************************************************************
* 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 "../../include/gtest_custom.h"
#include <support/sdv_core.h>
#include <support/app_control.h>
#include <support/pssup.h>
#include <support/interface_ptr.h>
#include "../../../sdv_services/ipc_connect/listener.h"
#include "../../../sdv_services/ipc_connect/client.h"
TEST(IPC_Connect_Test_Shared_Mem, InstantiateListener)
{
// Initialize system
sdv::app::CAppControl appcontrol;
ASSERT_TRUE(appcontrol.Startup(R"config(
[Application]
Mode = "Essential"
Instance = 1234
[LogHandler]
ViewFilter = "Fatal"
)config"));
ASSERT_TRUE(appcontrol.IsRunning());
sdv::core::IModuleControl* pModuleControl = sdv::core::GetObject<sdv::core::IModuleControl>("ModuleControlService");
ASSERT_NE(pModuleControl, nullptr);
EXPECT_NE(pModuleControl->Load("ipc_com.sdv"), 0);
EXPECT_NE(pModuleControl->Load("ipc_shared_mem.sdv"), 0);
EXPECT_NE(pModuleControl->Load("core_ps.sdv"), 0);
sdv::core::IRepositoryControl* pRepositoryControl = sdv::core::GetObject<sdv::core::IRepositoryControl>("RepositoryService");
ASSERT_NE(pRepositoryControl, nullptr);
EXPECT_NE(pRepositoryControl->CreateObject("CommunicationControl", {}, {}), 0);
EXPECT_NE(pRepositoryControl->CreateObject("DefaultSharedMemory", {}, {}), 0);
sdv::SObjectInfo sListenerInfo{};
sListenerInfo.ssConfig = R"toml(
[Provider]
Name = "DefaultSharedMemory"
[IpcChannel]
Name = "MyPersonalChannelName"
)toml";
// Start listener
CListener listener;
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::initialization_pending);
listener.Initialize(sListenerInfo);
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::initialized);
EXPECT_EQ(listener.GetProviderName(), "DefaultSharedMemory");
// Shutdown
listener.Shutdown();
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::destruction_pending);
appcontrol.Shutdown();
}
TEST(IPC_Connect_Test_Shared_Mem, InstantiateClientNoListener)
{
// Initialize system
sdv::app::CAppControl appcontrol;
ASSERT_TRUE(appcontrol.Startup(R"config(
[Application]
Mode = "Essential"
[LogHandler]
ViewFilter = "Fatal"
)config"));
ASSERT_TRUE(appcontrol.IsRunning());
sdv::core::IModuleControl* pModuleControl = sdv::core::GetObject<sdv::core::IModuleControl>("ModuleControlService");
ASSERT_NE(pModuleControl, nullptr);
EXPECT_NE(pModuleControl->Load("ipc_com.sdv"), 0);
EXPECT_NE(pModuleControl->Load("ipc_shared_mem.sdv"), 0);
EXPECT_NE(pModuleControl->Load("core_ps.sdv"), 0);
sdv::core::IRepositoryControl* pRepositoryControl = sdv::core::GetObject<sdv::core::IRepositoryControl>("RepositoryService");
ASSERT_NE(pRepositoryControl, nullptr);
EXPECT_NE(pRepositoryControl->CreateObject("CommunicationControl", {}, {}), 0);
sdv::SObjectInfo sClientInfo{};
sClientInfo.ssConfig = R"toml(
[Provider]
Name = "DefaultSharedMemory"
[IpcChannel]
Name = "MyPersonalChannelName"
)toml";
// Start client
CClientConnect client;
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::initialization_pending);
client.Initialize(sClientInfo);
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::initialized);
EXPECT_FALSE(client.Connect());
// Shutdown
client.Shutdown();
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::destruction_pending);
appcontrol.Shutdown();
}
TEST(IPC_Connect_Test_Shared_Mem, InstantiateClientAndListener)
{
// Initialize system
sdv::app::CAppControl appcontrol;
ASSERT_TRUE(appcontrol.Startup(R"config(
[Application]
Mode = "Essential"
[LogHandler]
ViewFilter = "Fatal"
)config"));
ASSERT_TRUE(appcontrol.IsRunning());
sdv::core::IModuleControl* pModuleControl = sdv::core::GetObject<sdv::core::IModuleControl>("ModuleControlService");
ASSERT_NE(pModuleControl, nullptr);
EXPECT_NE(pModuleControl->Load("ipc_com.sdv"), 0);
EXPECT_NE(pModuleControl->Load("ipc_shared_mem.sdv"), 0);
EXPECT_NE(pModuleControl->Load("core_ps.sdv"), 0);
sdv::core::IRepositoryControl* pRepositoryControl = sdv::core::GetObject<sdv::core::IRepositoryControl>("RepositoryService");
ASSERT_NE(pRepositoryControl, nullptr);
EXPECT_NE(pRepositoryControl->CreateObject("CommunicationControl", {}, {}), 0);
sdv::SObjectInfo sListenerInfo{};
sListenerInfo.ssConfig = R"toml([Provider]
Name = "DefaultSharedMemory"
[IpcChannel]
Name = "CHANNEL_1234"
)toml";
// Start listener
CListener listener;
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::initialization_pending);
listener.Initialize(sListenerInfo);
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::initialized);
sdv::SObjectInfo sClientInfo{};
sClientInfo.ssConfig = R"toml([Provider]
Name = "DefaultSharedMemory"
[IpcChannel]
Name = "CHANNEL_1234"
)toml";
// Start client
CClientConnect client;
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::initialization_pending);
client.Initialize(sClientInfo);
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::initialized);
EXPECT_TRUE(client.Connect());
EXPECT_TRUE(client.IsConnected());
// The client is a pointer to the repository. Request the module control service
sdv::core::IObjectAccess* pObjectAccess =
sdv::TInterfaceAccessPtr(client.GetRemoteRepository()).GetInterface<sdv::core::IObjectAccess>();
EXPECT_NE(pObjectAccess, nullptr);
sdv::core::IModuleInfo* pModuleInfo = nullptr;
if (pObjectAccess)
pModuleInfo = sdv::TInterfaceAccessPtr(pObjectAccess->GetObject("ModuleControlService")).GetInterface<sdv::core::IModuleInfo>();
EXPECT_NE(pModuleInfo, nullptr);
if (pModuleInfo)
{
EXPECT_FALSE(pModuleInfo->GetModuleList().empty());
}
EXPECT_TRUE(client.Disconnect());
// Shutdown
client.Shutdown();
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::destruction_pending);
listener.Shutdown();
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::destruction_pending);
appcontrol.Shutdown();
}

View File

@@ -0,0 +1,233 @@
/********************************************************************************
* 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:
* Denisa Ros - initial API and implementation
********************************************************************************/
#include "../../include/gtest_custom.h"
#include <support/sdv_core.h>
#include <support/app_control.h>
#include <support/pssup.h>
#include <support/interface_ptr.h>
#include <chrono>
#include <string>
#include <thread>
#include "../../../sdv_services/ipc_connect/listener.h"
#include "../../../sdv_services/ipc_connect/client.h"
namespace
{
const char* GetUdsModuleName()
{
#ifdef _WIN32
return "uds_win_sockets.sdv";
#else
return "uds_unix_sockets.sdv";
#endif
}
const char* GetUdsChannelControlClassName()
{
#ifdef _WIN32
return "WinSocketsChannelControl";
#else
return "UnixSocketsChannelControl";
#endif
}
std::string UniqueSuffix()
{
const auto now = std::chrono::steady_clock::now().time_since_epoch().count();
return std::to_string(static_cast<long long>(now));
}
std::string MakeChannelName(const char* base)
{
return std::string(base) + "_" + UniqueSuffix();
}
std::string MakeUdsConfigByName(const std::string& channelName)
{
return std::string("[Provider]\n")
+ "Name = \"unix_domain_sockets\"\n\n"
+ "[IpcChannel]\n"
+ "Name = \"" + channelName + "\"\n";
}
void LoadRequiredModulesAndObjects(bool createUdsChannelControl = true)
{
auto* pModuleControl =
sdv::core::GetObject<sdv::core::IModuleControl>("ModuleControlService");
ASSERT_NE(pModuleControl, nullptr);
EXPECT_NE(pModuleControl->Load("ipc_com.sdv"), 0);
EXPECT_NE(pModuleControl->Load(GetUdsModuleName()), 0);
EXPECT_NE(pModuleControl->Load("core_ps.sdv"), 0);
auto* pRepositoryControl =
sdv::core::GetObject<sdv::core::IRepositoryControl>("RepositoryService");
ASSERT_NE(pRepositoryControl, nullptr);
EXPECT_NE(pRepositoryControl->CreateObject("CommunicationControl", {}, {}), 0);
if (createUdsChannelControl)
{
EXPECT_NE(
pRepositoryControl->CreateObject(GetUdsChannelControlClassName(), {}, {}),
0);
}
}
} // anonymous namespace
TEST(IPC_Connect_Test_UDS, InstantiateListener)
{
sdv::app::CAppControl appcontrol;
ASSERT_TRUE(appcontrol.Startup(R"config(
[Application]
Mode = "Essential"
Instance = 1234
[LogHandler]
ViewFilter = "Fatal"
)config"));
ASSERT_TRUE(appcontrol.IsRunning());
LoadRequiredModulesAndObjects(true);
const std::string channelName = MakeChannelName("MyPersonalChannelName");
sdv::SObjectInfo sListenerInfo{};
sListenerInfo.ssConfig = MakeUdsConfigByName(channelName);
CListener listener;
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::initialization_pending);
listener.Initialize(sListenerInfo);
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::initialized);
EXPECT_EQ(listener.GetProviderName(), "unix_domain_sockets");
listener.Shutdown();
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::destruction_pending);
appcontrol.Shutdown();
}
TEST(IPC_Connect_Test_UDS, InstantiateClientNoListener)
{
sdv::app::CAppControl appcontrol;
ASSERT_TRUE(appcontrol.Startup(R"config(
[Application]
Mode = "Essential"
[LogHandler]
ViewFilter = "Fatal"
)config"));
ASSERT_TRUE(appcontrol.IsRunning());
LoadRequiredModulesAndObjects(true);
const std::string channelName = MakeChannelName("MyPersonalChannelName");
sdv::SObjectInfo sClientInfo{};
sClientInfo.ssConfig = MakeUdsConfigByName(channelName);
CClientConnect client;
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::initialization_pending);
client.Initialize(sClientInfo);
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::initialized);
std::cout << "Connecting client..." << std::endl;
EXPECT_FALSE(client.Connect());
std::cout << "Client failed to connect." << std::endl;
EXPECT_FALSE(client.IsConnected());
client.Shutdown();
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::destruction_pending);
appcontrol.Shutdown();
}
TEST(IPC_Connect_Test_UDS, InstantiateClientAndListener)
{
sdv::app::CAppControl appcontrol;
ASSERT_TRUE(appcontrol.Startup(R"config(
[Application]
Mode = "Essential"
[LogHandler]
ViewFilter = "Fatal"
)config"));
ASSERT_TRUE(appcontrol.IsRunning());
LoadRequiredModulesAndObjects(true);
const std::string channelName = MakeChannelName("CHANNEL_1234");
sdv::SObjectInfo sListenerInfo{};
sListenerInfo.ssConfig = MakeUdsConfigByName(channelName);
CListener listener;
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::initialization_pending);
listener.Initialize(sListenerInfo);
EXPECT_EQ(listener.GetProviderName(), "unix_domain_sockets");
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::initialized);
// Small delay to avoid startup races between listener init and client connect.
std::this_thread::sleep_for(std::chrono::milliseconds(100));
sdv::SObjectInfo sClientInfo{};
sClientInfo.ssConfig = MakeUdsConfigByName(channelName);
CClientConnect client;
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::initialization_pending);
client.Initialize(sClientInfo);
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::initialized);
EXPECT_TRUE(client.Connect());
EXPECT_TRUE(client.IsConnected());
// The client should expose the remote repository after successful connect.
sdv::core::IObjectAccess* pObjectAccess =
sdv::TInterfaceAccessPtr(client.GetRemoteRepository())
.GetInterface<sdv::core::IObjectAccess>();
EXPECT_NE(pObjectAccess, nullptr);
sdv::core::IModuleInfo* pModuleInfo = nullptr;
if (pObjectAccess)
{
pModuleInfo =
sdv::TInterfaceAccessPtr(pObjectAccess->GetObject("ModuleControlService"))
.GetInterface<sdv::core::IModuleInfo>();
}
EXPECT_NE(pModuleInfo, nullptr);
if (pModuleInfo)
{
EXPECT_FALSE(pModuleInfo->GetModuleList().empty());
}
EXPECT_TRUE(client.Disconnect());
std::cout << "Client Shutdown" << std::endl;
client.Shutdown();
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::destruction_pending);
std::cout << "Listener Shutdown" << std::endl;
listener.Shutdown();
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::destruction_pending);
appcontrol.Shutdown();
}

View File

@@ -0,0 +1,278 @@
/********************************************************************************
* 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:
* Denisa Ros - initial API and implementation
********************************************************************************/
#include "../../include/gtest_custom.h"
#include <support/sdv_core.h>
#include <support/app_control.h>
#include <support/pssup.h>
#include <support/interface_ptr.h>
#include <chrono>
#include <string>
#include <thread>
#include "../../../sdv_services/ipc_connect/listener.h"
#include "../../../sdv_services/ipc_connect/client.h"
namespace
{
const char* GetTunnelModuleName()
{
#ifdef _WIN32
return "uds_win_tunnel.sdv";
#else
return "uds_unix_tunnel.sdv";
#endif
}
const char* GetTunnelChannelControlClassName()
{
#ifdef _WIN32
return "WinTunnelChannelControl";
#else
return "UnixTunnelChannelControl";
#endif
}
std::string UniqueSuffix()
{
const auto now = std::chrono::steady_clock::now().time_since_epoch().count();
return std::to_string(static_cast<long long>(now));
}
std::string MakeChannelName(const char* base)
{
return std::string(base) + "_" + UniqueSuffix();
}
std::string MakeTunnelName(const char* base)
{
return std::string("t_") + base + "_" + UniqueSuffix();
}
std::string MakeTunnelConfigByName(const std::string& channelName,
const std::string& tunnelName)
{
return std::string("[Provider]\n")
+ "Name = \"unix_domain_sockets_tunnel\"\n\n"
+ "[IpcChannel]\n"
+ "Name = \"" + channelName + "\"\n"
+ "Tunnel = \"" + tunnelName + "\"\n";
}
void LoadRequiredModulesAndObjects(bool createTunnelChannelControl = true)
{
auto* pModuleControl =
sdv::core::GetObject<sdv::core::IModuleControl>("ModuleControlService");
ASSERT_NE(pModuleControl, nullptr);
EXPECT_NE(pModuleControl->Load("ipc_com.sdv"), 0);
EXPECT_NE(pModuleControl->Load(GetTunnelModuleName()), 0);
EXPECT_NE(pModuleControl->Load("core_ps.sdv"), 0);
auto* pRepositoryControl =
sdv::core::GetObject<sdv::core::IRepositoryControl>("RepositoryService");
ASSERT_NE(pRepositoryControl, nullptr);
EXPECT_NE(pRepositoryControl->CreateObject("CommunicationControl", {}, {}), 0);
if (createTunnelChannelControl)
{
EXPECT_NE(
pRepositoryControl->CreateObject(GetTunnelChannelControlClassName(), {}, {}),
0);
}
}
} // anonymous namespace
TEST(IPC_Connect_Test_UDS_Tunnel, InstantiateListener)
{
sdv::app::CAppControl appcontrol;
ASSERT_TRUE(appcontrol.Startup(R"config(
[Application]
Mode = "Essential"
Instance = 1234
[LogHandler]
ViewFilter = "Fatal"
)config"));
ASSERT_TRUE(appcontrol.IsRunning());
LoadRequiredModulesAndObjects(true);
const std::string channelName = MakeChannelName("MyPersonalChannelName");
const std::string tunnelName = MakeTunnelName("listener");
sdv::SObjectInfo sListenerInfo{};
sListenerInfo.ssConfig = MakeTunnelConfigByName(channelName, tunnelName);
CListener listener;
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::initialization_pending);
listener.Initialize(sListenerInfo);
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::initialized);
EXPECT_EQ(listener.GetProviderName(), "unix_domain_sockets_tunnel");
listener.Shutdown();
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::destruction_pending);
appcontrol.Shutdown();
}
TEST(IPC_Connect_Test_UDS_Tunnel, InstantiateClientNoListener)
{
sdv::app::CAppControl appcontrol;
ASSERT_TRUE(appcontrol.Startup(R"config(
[Application]
Mode = "Essential"
[LogHandler]
ViewFilter = "Fatal"
)config"));
ASSERT_TRUE(appcontrol.IsRunning());
LoadRequiredModulesAndObjects(true);
const std::string channelName = MakeChannelName("MyPersonalChannelName");
const std::string tunnelName = MakeTunnelName("no_listener");
sdv::SObjectInfo sClientInfo{};
sClientInfo.ssConfig = MakeTunnelConfigByName(channelName, tunnelName);
CClientConnect client;
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::initialization_pending);
client.Initialize(sClientInfo);
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::initialized);
EXPECT_FALSE(client.Connect());
EXPECT_FALSE(client.IsConnected());
client.Shutdown();
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::destruction_pending);
appcontrol.Shutdown();
}
TEST(IPC_Connect_Test_UDS_Tunnel, InstantiateClientAndListener)
{
sdv::app::CAppControl appcontrol;
ASSERT_TRUE(appcontrol.Startup(R"config(
[Application]
Mode = "Essential"
[LogHandler]
ViewFilter = "Fatal"
)config"));
ASSERT_TRUE(appcontrol.IsRunning());
LoadRequiredModulesAndObjects(true);
const std::string channelName = MakeChannelName("CHANNEL_1234");
const std::string tunnelName = MakeTunnelName("client_listener");
sdv::SObjectInfo sListenerInfo{};
sListenerInfo.ssConfig = MakeTunnelConfigByName(channelName, tunnelName);
CListener listener;
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::initialization_pending);
listener.Initialize(sListenerInfo);
EXPECT_EQ(listener.GetProviderName(), "unix_domain_sockets_tunnel");
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::initialized);
// Allow listener endpoint publication to complete before client connect.
std::this_thread::sleep_for(std::chrono::milliseconds(100));
sdv::SObjectInfo sClientInfo{};
sClientInfo.ssConfig = MakeTunnelConfigByName(channelName, tunnelName);
CClientConnect client;
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::initialization_pending);
client.Initialize(sClientInfo);
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::initialized);
EXPECT_TRUE(client.Connect());
EXPECT_TRUE(client.IsConnected());
// The client should expose the remote repository after successful connect.
sdv::core::IObjectAccess* pObjectAccess =
sdv::TInterfaceAccessPtr(client.GetRemoteRepository())
.GetInterface<sdv::core::IObjectAccess>();
EXPECT_NE(pObjectAccess, nullptr);
sdv::core::IModuleInfo* pModuleInfo = nullptr;
if (pObjectAccess)
{
pModuleInfo =
sdv::TInterfaceAccessPtr(pObjectAccess->GetObject("ModuleControlService"))
.GetInterface<sdv::core::IModuleInfo>();
}
EXPECT_NE(pModuleInfo, nullptr);
if (pModuleInfo)
{
EXPECT_FALSE(pModuleInfo->GetModuleList().empty());
}
EXPECT_TRUE(client.Disconnect());
client.Shutdown();
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::destruction_pending);
listener.Shutdown();
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::destruction_pending);
appcontrol.Shutdown();
}
TEST(IPC_Connect_Test_UDS_Tunnel, InvalidProvider_ShouldNotInitializeClient)
{
sdv::app::CAppControl appcontrol;
ASSERT_TRUE(appcontrol.Startup(R"config(
[Application]
Mode = "Essential"
[LogHandler]
ViewFilter = "Fatal"
)config"));
ASSERT_TRUE(appcontrol.IsRunning());
LoadRequiredModulesAndObjects(true);
sdv::SObjectInfo sClientInfo{};
sClientInfo.ssConfig = R"toml(
[Provider]
Name = "invalid_tunnel_provider"
[IpcChannel]
Name = "CHANNEL_1234"
Tunnel = "t_invalid_provider"
)toml";
CClientConnect client;
client.Initialize(sClientInfo);
EXPECT_NE(client.GetObjectState(), sdv::EObjectState::initialized);
EXPECT_FALSE(client.Connect());
EXPECT_FALSE(client.IsConnected());
client.Shutdown();
appcontrol.Shutdown();
}