2026-03-27 14:12:49 +01:00
/********************************************************************************
* 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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2025-11-04 13:28:06 +01:00
# include <gtest/gtest.h>
# include <interfaces/repository.h>
# include <support/local_service_access.h>
# include <support/app_control.h>
# include "../../../global/process_watchdog.h"
# include "../../include/basic_test_helper.h"
# include "generated/test_component.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 ( ) ;
}
const uint32_t LoopCount = 100 ; //< amount of loops used for concurrency tests. more loops means more thorough deadlock check at the cost of increased runtime
// used to supply external objects for testing pruposes. Implements IObjectControl to make sure this is NOT called for externally supplied objects
class TestExternalObject : public sdv : : IInterfaceAccess , public sdv : : IObjectControl
{
public :
BEGIN_SDV_INTERFACE_MAP ( )
SDV_INTERFACE_ENTRY ( sdv : : IObjectControl )
END_SDV_INTERFACE_MAP ( )
2026-03-27 14:12:49 +01:00
virtual void Initialize ( [[maybe_unused]] const sdv : : u8string & ssObjectConfig ) override
2025-11-04 13:28:06 +01:00
{
FAIL ( ) < < " Error: Initialize should not be called by Repo Service! " ;
2026-03-27 14:12:49 +01:00
// m_eObjectState = sdv::EObjectState::initialization_failure;
2025-11-04 13:28:06 +01:00
}
2026-03-27 14:12:49 +01:00
virtual sdv : : EObjectState GetObjectState ( ) const override
2025-11-04 13:28:06 +01:00
{
2026-03-27 14:12:49 +01:00
return m_eObjectState ;
2025-11-04 13:28:06 +01:00
}
2026-03-27 14:12:49 +01:00
virtual void SetOperationMode ( sdv : : EOperationMode eMode ) override
2025-11-04 13:28:06 +01:00
{
switch ( eMode )
{
case sdv : : EOperationMode : : configuring :
2026-03-27 14:12:49 +01:00
m_eObjectState = sdv : : EObjectState : : configuring ;
2025-11-04 13:28:06 +01:00
break ;
case sdv : : EOperationMode : : running :
2026-03-27 14:12:49 +01:00
m_eObjectState = sdv : : EObjectState : : running ;
2025-11-04 13:28:06 +01:00
break ;
default :
break ;
}
}
2026-03-27 14:12:49 +01:00
virtual sdv : : u8string GetObjectConfig ( ) const override
{
return { } ;
}
virtual void Shutdown ( ) override
2025-11-04 13:28:06 +01:00
{
2026-03-27 14:12:49 +01:00
m_eObjectState = sdv : : EObjectState : : destruction_pending ;
2025-11-04 13:28:06 +01:00
}
2026-03-27 14:12:49 +01:00
sdv : : EObjectState m_eObjectState = sdv : : EObjectState : : initialization_pending ;
2025-11-04 13:28:06 +01:00
} ;
TEST ( RepositoryTest , LoadNonexistentModule )
{
sdv : : app : : CAppControl control ( R " code(
[ LogHandler ]
ViewFilter = " Fatal "
[ Application ]
Mode = " Essential "
) code " );
ASSERT_TRUE ( control . IsRunning ( ) ) ;
control . SetConfigMode ( ) ;
auto pModuleControl = sdv : : core : : GetObject < sdv : : core : : IModuleControl > ( " ModuleControlService " ) ;
ASSERT_TRUE ( pModuleControl ) ;
auto pRepositoryControl = sdv : : core : : GetObject < sdv : : core : : IRepositoryControl > ( " RepositoryService " ) ;
ASSERT_TRUE ( pRepositoryControl ) ;
EXPECT_FALSE ( pModuleControl - > Load ( ( GetExecDirectory ( ) / " TestFooBar.sdv " ) . generic_u8string ( ) ) ) ;
control . SetRunningMode ( ) ;
control . Shutdown ( ) ;
}
TEST ( RepositoryTest , CreateNonexistantClass )
{
sdv : : app : : CAppControl control ( R " code(
[ LogHandler ]
ViewFilter = " Fatal "
[ Application ]
Mode = " Essential "
) code " );
ASSERT_TRUE ( control . IsRunning ( ) ) ;
control . SetConfigMode ( ) ;
auto pModuleControl = sdv : : core : : GetObject < sdv : : core : : IModuleControl > ( " ModuleControlService " ) ;
ASSERT_TRUE ( pModuleControl ) ;
auto pRepositoryControl = sdv : : core : : GetObject < sdv : : core : : IRepositoryControl > ( " RepositoryService " ) ;
ASSERT_TRUE ( pRepositoryControl ) ;
ASSERT_TRUE ( pModuleControl - > Load ( ( GetExecDirectory ( ) / " ComponentTest_Repository_test_module.sdv " ) . generic_u8string ( ) ) ) ;
EXPECT_FALSE ( pRepositoryControl - > CreateObject ( " TestFooBar " , nullptr , nullptr ) ) ;
control . SetRunningMode ( ) ;
control . Shutdown ( ) ;
}
TEST ( RepositoryTest , GetNonexistantObject )
{
sdv : : app : : CAppControl control ( R " code(
[ LogHandler ]
ViewFilter = " Fatal "
[ Application ]
Mode = " Essential "
) code " );
ASSERT_TRUE ( control . IsRunning ( ) ) ;
control . SetConfigMode ( ) ;
auto pModuleControl = sdv : : core : : GetObject < sdv : : core : : IModuleControl > ( " ModuleControlService " ) ;
ASSERT_TRUE ( pModuleControl ) ;
auto pRepositoryControl = sdv : : core : : GetObject < sdv : : core : : IRepositoryControl > ( " RepositoryService " ) ;
ASSERT_TRUE ( pRepositoryControl ) ;
auto pObjectAccess = sdv : : core : : GetObject < sdv : : core : : IObjectAccess > ( " RepositoryService " ) ;
ASSERT_TRUE ( pObjectAccess ) ;
ASSERT_TRUE ( pModuleControl - > Load ( ( GetExecDirectory ( ) / " ComponentTest_Repository_test_module.sdv " ) . generic_u8string ( ) ) ) ;
bool bRes = pRepositoryControl - > CreateObject ( " Example_Object " , nullptr , nullptr ) ;
EXPECT_TRUE ( bRes ) ;
EXPECT_EQ ( nullptr , pObjectAccess - > GetObject ( " TestFooBar " ) ) ;
control . SetRunningMode ( ) ;
control . Shutdown ( ) ;
}
TEST ( RepositoryTest , InstantiateAndGet )
{
sdv : : app : : CAppControl control ( R " code(
[ LogHandler ]
ViewFilter = " Fatal "
[ Application ]
Mode = " Essential "
) code " );
ASSERT_TRUE ( control . IsRunning ( ) ) ;
control . SetConfigMode ( ) ;
auto pModuleControl = sdv : : core : : GetObject < sdv : : core : : IModuleControl > ( " ModuleControlService " ) ;
ASSERT_TRUE ( pModuleControl ) ;
auto pRepositoryControl = sdv : : core : : GetObject < sdv : : core : : IRepositoryControl > ( " RepositoryService " ) ;
ASSERT_TRUE ( pRepositoryControl ) ;
auto pObjectAccess = sdv : : core : : GetObject < sdv : : core : : IObjectAccess > ( " RepositoryService " ) ;
ASSERT_TRUE ( pObjectAccess ) ;
ASSERT_TRUE ( pModuleControl - > Load ( ( GetExecDirectory ( ) / " ComponentTest_Repository_test_module.sdv " ) . generic_u8string ( ) ) ) ;
bool bRes = pRepositoryControl - > CreateObject ( " Example_Object " , nullptr , nullptr ) ;
EXPECT_TRUE ( bRes ) ;
EXPECT_NE ( nullptr , pObjectAccess - > GetObject ( " Example_Object " ) ) ;
control . SetRunningMode ( ) ;
control . Shutdown ( ) ;
EXPECT_EQ ( nullptr , pObjectAccess - > GetObject ( " Example_Object " ) ) ;
}
TEST ( RepositoryTest , InstantiateInitFail )
{
sdv : : app : : CAppControl control ( R " code(
[ LogHandler ]
ViewFilter = " Fatal "
[ Application ]
Mode = " Essential "
) code " );
ASSERT_TRUE ( control . IsRunning ( ) ) ;
control . SetConfigMode ( ) ;
auto pModuleControl = sdv : : core : : GetObject < sdv : : core : : IModuleControl > ( " ModuleControlService " ) ;
ASSERT_TRUE ( pModuleControl ) ;
auto pRepositoryControl = sdv : : core : : GetObject < sdv : : core : : IRepositoryControl > ( " RepositoryService " ) ;
ASSERT_TRUE ( pRepositoryControl ) ;
auto pObjectAccess = sdv : : core : : GetObject < sdv : : core : : IObjectAccess > ( " RepositoryService " ) ;
ASSERT_TRUE ( pObjectAccess ) ;
ASSERT_TRUE ( pModuleControl - > Load ( ( GetExecDirectory ( ) / " ComponentTest_Repository_test_module.sdv " ) . generic_u8string ( ) ) ) ;
bool bRes = pRepositoryControl - > CreateObject ( " TestObject_IObjectControlFail " , nullptr , nullptr ) ;
EXPECT_FALSE ( bRes ) ;
EXPECT_EQ ( nullptr , pObjectAccess - > GetObject ( " TestObject_IObjectControlFail " ) ) ;
control . SetRunningMode ( ) ;
control . Shutdown ( ) ;
}
TEST ( RepositoryTest , InstantiateDuplicateCreateObjectName )
{
sdv : : app : : CAppControl control ( R " code(
[ LogHandler ]
ViewFilter = " Fatal "
[ Application ]
Mode = " Essential "
) code " );
ASSERT_TRUE ( control . IsRunning ( ) ) ;
control . SetConfigMode ( ) ;
auto pModuleControl = sdv : : core : : GetObject < sdv : : core : : IModuleControl > ( " ModuleControlService " ) ;
ASSERT_TRUE ( pModuleControl ) ;
auto pRepositoryControl = sdv : : core : : GetObject < sdv : : core : : IRepositoryControl > ( " RepositoryService " ) ;
ASSERT_TRUE ( pRepositoryControl ) ;
auto pObjectAccess = sdv : : core : : GetObject < sdv : : core : : IObjectAccess > ( " RepositoryService " ) ;
ASSERT_TRUE ( pObjectAccess ) ;
ASSERT_TRUE ( pModuleControl - > Load ( ( GetExecDirectory ( ) / " ComponentTest_Repository_test_module.sdv " ) . generic_u8string ( ) ) ) ;
// Instantiating the same object twice is allowed (only one instance will be created).
EXPECT_TRUE ( pRepositoryControl - > CreateObject ( " Example_Object " , nullptr , nullptr ) ) ;
EXPECT_TRUE ( pRepositoryControl - > CreateObject ( " Example_Object " , nullptr , nullptr ) ) ;
EXPECT_NE ( nullptr , pObjectAccess - > GetObject ( " Example_Object " ) ) ;
// Instantiating a different object with the same name as the previous object is not allowed.
EXPECT_FALSE ( pRepositoryControl - > CreateObject ( " Example_Object_2 " , " Example_Object " , nullptr ) ) ;
// Instantiating a different object with a completely different name is allowed
EXPECT_TRUE ( pRepositoryControl - > CreateObject ( " Example_Object_2 " , " abracadabra " , nullptr ) ) ;
EXPECT_NE ( nullptr , pObjectAccess - > GetObject ( " abracadabra " ) ) ;
control . SetRunningMode ( ) ;
control . Shutdown ( ) ;
}
TEST ( RepositoryTest , InstantiateDuplicateExternalObjectName )
{
sdv : : app : : CAppControl control ( R " code(
[ LogHandler ]
ViewFilter = " Fatal "
[ Application ]
Mode = " Essential "
) code " );
ASSERT_TRUE ( control . IsRunning ( ) ) ;
control . SetConfigMode ( ) ;
auto pModuleControl = sdv : : core : : GetObject < sdv : : core : : IModuleControl > ( " ModuleControlService " ) ;
ASSERT_TRUE ( pModuleControl ) ;
auto pRepositoryControl = sdv : : core : : GetObject < sdv : : core : : IRepositoryControl > ( " RepositoryService " ) ;
ASSERT_TRUE ( pRepositoryControl ) ;
auto pObjectAccess = sdv : : core : : GetObject < sdv : : core : : IObjectAccess > ( " RepositoryService " ) ;
ASSERT_TRUE ( pObjectAccess ) ;
sdv : : core : : IRegisterForeignObject * pExternalObject = sdv : : core : : GetObject < sdv : : core : : IRegisterForeignObject > ( " RepositoryService " ) ;
ASSERT_TRUE ( pExternalObject ) ;
ASSERT_TRUE ( pModuleControl - > Load ( ( GetExecDirectory ( ) / " ComponentTest_Repository_test_module.sdv " ) . generic_u8string ( ) ) ) ;
//no two objects of same name allowed! Second Register fails, Get returns instance of first Register
TestExternalObject testObj1 ;
EXPECT_TRUE ( pExternalObject - > RegisterObject ( & testObj1 , " Example_Object " ) ) ;
TestExternalObject testObj2 ;
EXPECT_FALSE ( pExternalObject - > RegisterObject ( & testObj2 , " Example_Object " ) ) ;
EXPECT_EQ ( & testObj1 , pObjectAccess - > GetObject ( " Example_Object " ) ) ;
control . SetRunningMode ( ) ;
control . Shutdown ( ) ;
}
TEST ( RepositoryTest , InstantiateDuplicateObjectNameMixed )
{
sdv : : app : : CAppControl control ( R " code(
[ LogHandler ]
ViewFilter = " Fatal "
[ Application ]
Mode = " Essential "
) code " );
ASSERT_TRUE ( control . IsRunning ( ) ) ;
control . SetConfigMode ( ) ;
auto pModuleControl = sdv : : core : : GetObject < sdv : : core : : IModuleControl > ( " ModuleControlService " ) ;
ASSERT_TRUE ( pModuleControl ) ;
auto pRepositoryControl = sdv : : core : : GetObject < sdv : : core : : IRepositoryControl > ( " RepositoryService " ) ;
ASSERT_TRUE ( pRepositoryControl ) ;
auto pObjectAccess = sdv : : core : : GetObject < sdv : : core : : IObjectAccess > ( " RepositoryService " ) ;
ASSERT_TRUE ( pObjectAccess ) ;
sdv : : core : : IRegisterForeignObject * pExternalObject = sdv : : core : : GetObject < sdv : : core : : IRegisterForeignObject > ( " RepositoryService " ) ;
ASSERT_TRUE ( pExternalObject ) ;
ASSERT_TRUE ( pModuleControl - > Load ( ( GetExecDirectory ( ) / " ComponentTest_Repository_test_module.sdv " ) . generic_u8string ( ) ) ) ;
//no two objects of same name allowed! Register fails, Get returns instance previously created
bool bRes = pRepositoryControl - > CreateObject ( " Example_Object " , nullptr , nullptr ) ;
EXPECT_TRUE ( bRes ) ;
TestExternalObject testObj2 ;
EXPECT_FALSE ( pExternalObject - > RegisterObject ( & testObj2 , " Example_Object " ) ) ;
EXPECT_NE ( nullptr , pObjectAccess - > GetObject ( " Example_Object " ) ) ;
control . SetRunningMode ( ) ;
control . Shutdown ( ) ;
}
TEST ( RepositoryTest , InstantiateTwoNamedInstances )
{
sdv : : app : : CAppControl control ( R " code(
[ LogHandler ]
ViewFilter = " Fatal "
[ Application ]
Mode = " Essential "
) code " );
ASSERT_TRUE ( control . IsRunning ( ) ) ;
control . SetConfigMode ( ) ;
auto pModuleControl = sdv : : core : : GetObject < sdv : : core : : IModuleControl > ( " ModuleControlService " ) ;
ASSERT_TRUE ( pModuleControl ) ;
auto pRepositoryControl = sdv : : core : : GetObject < sdv : : core : : IRepositoryControl > ( " RepositoryService " ) ;
ASSERT_TRUE ( pRepositoryControl ) ;
auto pObjectAccess = sdv : : core : : GetObject < sdv : : core : : IObjectAccess > ( " RepositoryService " ) ;
ASSERT_TRUE ( pObjectAccess ) ;
ASSERT_TRUE ( pModuleControl - > Load ( ( GetExecDirectory ( ) / " ComponentTest_Repository_test_module.sdv " ) . generic_u8string ( ) ) ) ;
bool bRes1 = pRepositoryControl - > CreateObject ( " Example_Object " , " Obj_1 " , nullptr ) ;
EXPECT_TRUE ( bRes1 ) ;
EXPECT_NE ( nullptr , pObjectAccess - > GetObject ( " Obj_1 " ) ) ;
bool bRes2 = pRepositoryControl - > CreateObject ( " Example_Object " , " Obj_2 " , nullptr ) ;
EXPECT_TRUE ( bRes2 ) ;
EXPECT_NE ( nullptr , pObjectAccess - > GetObject ( " Obj_2 " ) ) ;
EXPECT_EQ ( nullptr , pObjectAccess - > GetObject ( " Example_Object " ) ) ;
control . SetRunningMode ( ) ;
control . Shutdown ( ) ;
EXPECT_EQ ( nullptr , pObjectAccess - > GetObject ( " Obj_1 " ) ) ;
EXPECT_EQ ( nullptr , pObjectAccess - > GetObject ( " Obj_2 " ) ) ;
}
TEST ( RepositoryTest , ChainCreateSimple )
{
sdv : : app : : CAppControl control ( R " code(
[ LogHandler ]
ViewFilter = " Fatal "
[ Application ]
Mode = " Essential "
) code " );
ASSERT_TRUE ( control . IsRunning ( ) ) ;
control . SetConfigMode ( ) ;
auto pModuleControl = sdv : : core : : GetObject < sdv : : core : : IModuleControl > ( " ModuleControlService " ) ;
ASSERT_TRUE ( pModuleControl ) ;
auto pRepositoryControl = sdv : : core : : GetObject < sdv : : core : : IRepositoryControl > ( " RepositoryService " ) ;
ASSERT_TRUE ( pRepositoryControl ) ;
auto pObjectAccess = sdv : : core : : GetObject < sdv : : core : : IObjectAccess > ( " RepositoryService " ) ;
ASSERT_TRUE ( pObjectAccess ) ;
ASSERT_TRUE ( pModuleControl - > Load ( ( GetExecDirectory ( ) / " ComponentTest_Repository_test_module.sdv " ) . generic_u8string ( ) ) ) ;
2026-03-27 14:12:49 +01:00
bool bRes = pRepositoryControl - > CreateObject ( " TestObject_CreateChain " , nullptr , " chained_object = \" ChainedObject \" " ) ;
2025-11-04 13:28:06 +01:00
EXPECT_TRUE ( bRes ) ;
EXPECT_NE ( nullptr , pObjectAccess - > GetObject ( " TestObject_CreateChain " ) ) ;
EXPECT_NE ( nullptr , pObjectAccess - > GetObject ( " ChainedObject " ) ) ;
control . SetRunningMode ( ) ;
control . Shutdown ( ) ;
EXPECT_EQ ( nullptr , pObjectAccess - > GetObject ( " TestObject_CreateChain " ) ) ;
EXPECT_EQ ( nullptr , pObjectAccess - > GetObject ( " ChainedObject " ) ) ;
}
TEST ( RepositoryTest , ChainCreateParallel )
{
sdv : : app : : CAppControl control ( R " code(
[ LogHandler ]
ViewFilter = " Fatal "
[ Application ]
Mode = " Essential "
) code " );
ASSERT_TRUE ( control . IsRunning ( ) ) ;
control . SetConfigMode ( ) ;
auto pModuleControl = sdv : : core : : GetObject < sdv : : core : : IModuleControl > ( " ModuleControlService " ) ;
ASSERT_TRUE ( pModuleControl ) ;
auto pRepositoryControl = sdv : : core : : GetObject < sdv : : core : : IRepositoryControl > ( " RepositoryService " ) ;
ASSERT_TRUE ( pRepositoryControl ) ;
auto pObjectAccess = sdv : : core : : GetObject < sdv : : core : : IObjectAccess > ( " RepositoryService " ) ;
ASSERT_TRUE ( pObjectAccess ) ;
ASSERT_TRUE ( pModuleControl - > Load ( ( GetExecDirectory ( ) / " ComponentTest_Repository_test_module.sdv " ) . generic_u8string ( ) ) ) ;
std : : thread testThread ( [ pRepositoryControl , pObjectAccess ] ( )
{
for ( uint32_t i = 0 ; i < LoopCount ; + + i )
{
std : : string count = std : : to_string ( i ) ;
2026-03-27 14:12:49 +01:00
bool bRes = pRepositoryControl - > CreateObject ( " TestObject_CreateChain " , " Bar_ " + count ,
" chained_object = \" BarFoo_ " + count + " \" " ) ;
2025-11-04 13:28:06 +01:00
EXPECT_TRUE ( bRes ) ;
EXPECT_NE ( nullptr , pObjectAccess - > GetObject ( " BarFoo_ " + count ) ) ;
}
} ) ;
for ( uint32_t i = 0 ; i < LoopCount ; + + i )
{
std : : string count = std : : to_string ( i ) ;
2026-03-27 14:12:49 +01:00
bool bRes =
pRepositoryControl - > CreateObject ( " TestObject_CreateChain " , " Foo_ " + count , " chained_object = \" FooBar_ " + count + " \" " ) ;
2025-11-04 13:28:06 +01:00
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(
[ LogHandler ]
ViewFilter = " Fatal "
[ Application ]
Mode = " Essential "
) code " );
ASSERT_TRUE ( control . IsRunning ( ) ) ;
control . SetConfigMode ( ) ;
auto pModuleControl = sdv : : core : : GetObject < sdv : : core : : IModuleControl > ( " ModuleControlService " ) ;
ASSERT_TRUE ( pModuleControl ) ;
auto pRepositoryControl = sdv : : core : : GetObject < sdv : : core : : IRepositoryControl > ( " RepositoryService " ) ;
ASSERT_TRUE ( pRepositoryControl ) ;
auto pObjectAccess = sdv : : core : : GetObject < sdv : : core : : IObjectAccess > ( " RepositoryService " ) ;
ASSERT_TRUE ( pObjectAccess ) ;
ASSERT_TRUE ( pModuleControl - > Load ( ( GetExecDirectory ( ) / " ComponentTest_Repository_test_module.sdv " ) . generic_u8string ( ) ) ) ;
bool bRes = pRepositoryControl - > CreateObject ( " TestLockService " , nullptr , nullptr ) ;
ASSERT_TRUE ( bRes ) ;
auto pLock = sdv : : core : : GetObject ( " TestLockService " ) . GetInterface < ITestLock > ( ) ;
ASSERT_NE ( pLock , nullptr ) ;
//attempt to create deadlock by taking lock during initialize and by taking lock before call to create object
std : : thread testThread ( [ & ] ( )
{
for ( uint32_t i = 0 ; i < LoopCount ; + + i )
{
std : : string count = std : : to_string ( i ) ;
//locks using TestLockService during construction
2026-03-27 14:12:49 +01:00
bRes = pRepositoryControl - > CreateObject ( " TestObject_CreateChainLock " , " Bar_ " + count ,
" chained_object = \" BarFoo_ " + count + " \" " ) ;
2025-11-04 13:28:06 +01:00
EXPECT_TRUE ( bRes ) ;
EXPECT_NE ( nullptr , pObjectAccess - > GetObject ( " BarFoo_ " + count ) ) ;
}
} ) ;
for ( uint32_t i = 0 ; i < LoopCount ; + + i )
{
std : : string count = std : : to_string ( i ) ;
pLock - > Lock ( ) ;
2026-03-27 14:12:49 +01:00
bRes = pRepositoryControl - > CreateObject ( " TestObject_CreateChain " , " Foo_ " + count ,
" chained_object = \" FooBar_ " + count + " \" " ) ;
2025-11-04 13:28:06 +01:00
EXPECT_TRUE ( bRes ) ;
EXPECT_NE ( nullptr , pObjectAccess - > GetObject ( " FooBar_ " + count ) ) ;
pLock - > Unlock ( ) ;
}
testThread . join ( ) ;
control . SetRunningMode ( ) ;
control . Shutdown ( ) ;
}
TEST ( RepositoryTest , ChainCreateParallelThreadLock )
{
sdv : : app : : CAppControl control ( R " code(
[ LogHandler ]
ViewFilter = " Fatal "
[ Application ]
Mode = " Essential "
) code " );
ASSERT_TRUE ( control . IsRunning ( ) ) ;
control . SetConfigMode ( ) ;
auto pModuleControl = sdv : : core : : GetObject < sdv : : core : : IModuleControl > ( " ModuleControlService " ) ;
ASSERT_TRUE ( pModuleControl ) ;
auto pRepositoryControl = sdv : : core : : GetObject < sdv : : core : : IRepositoryControl > ( " RepositoryService " ) ;
ASSERT_TRUE ( pRepositoryControl ) ;
auto pObjectAccess = sdv : : core : : GetObject < sdv : : core : : IObjectAccess > ( " RepositoryService " ) ;
ASSERT_TRUE ( pObjectAccess ) ;
ASSERT_TRUE ( pModuleControl - > Load ( ( GetExecDirectory ( ) / " ComponentTest_Repository_test_module.sdv " ) . generic_u8string ( ) ) ) ;
bool bRes = pRepositoryControl - > CreateObject ( " TestLockService " , nullptr , nullptr ) ;
ASSERT_TRUE ( bRes ) ;
auto pLock = sdv : : core : : GetObject ( " TestLockService " ) . GetInterface < ITestLock > ( ) ;
ASSERT_NE ( pLock , nullptr ) ;
//attempt to create deadlock by taking lock during initialize and by taking lock before call to create object
std : : thread testThread ( [ & ] ( )
{
for ( uint32_t i = 0 ; i < LoopCount ; + + i )
{
std : : string count = std : : to_string ( i ) ;
//locks using TestLockService during construction in a seperate thread
2026-03-27 14:12:49 +01:00
bRes = pRepositoryControl - > CreateObject ( " TestObject_CreateChainLockThread " , " Bar_ " + count ,
" chained_object = \" BarFoo_ " + count + " \" " ) ;
2025-11-04 13:28:06 +01:00
EXPECT_TRUE ( bRes ) ;
EXPECT_NE ( nullptr , pObjectAccess - > GetObject ( " BarFoo_ " + count ) ) ;
}
} ) ;
for ( uint32_t i = 0 ; i < LoopCount ; + + i )
{
std : : string count = std : : to_string ( i ) ;
pLock - > Lock ( ) ;
2026-03-27 14:12:49 +01:00
bRes = pRepositoryControl - > CreateObject ( " TestObject_CreateChain " , " Foo_ " + count ,
" chained_object = \" FooBar_ " + count + " \" " ) ;
2025-11-04 13:28:06 +01:00
EXPECT_TRUE ( bRes ) ;
EXPECT_NE ( nullptr , pObjectAccess - > GetObject ( " FooBar_ " + count ) ) ;
pLock - > Unlock ( ) ;
}
testThread . join ( ) ;
control . SetRunningMode ( ) ;
control . Shutdown ( ) ;
}
TEST ( RepositoryTest , InstantiateDuringShutdown )
{
sdv : : app : : CAppControl control ( R " code(
[ LogHandler ]
ViewFilter = " Fatal "
[ Application ]
Mode = " Essential "
) code " );
ASSERT_TRUE ( control . IsRunning ( ) ) ;
control . SetConfigMode ( ) ;
auto pModuleControl = sdv : : core : : GetObject < sdv : : core : : IModuleControl > ( " ModuleControlService " ) ;
ASSERT_TRUE ( pModuleControl ) ;
auto pRepositoryControl = sdv : : core : : GetObject < sdv : : core : : IRepositoryControl > ( " RepositoryService " ) ;
ASSERT_TRUE ( pRepositoryControl ) ;
auto pObjectAccess = sdv : : core : : GetObject < sdv : : core : : IObjectAccess > ( " RepositoryService " ) ;
ASSERT_TRUE ( pObjectAccess ) ;
ASSERT_TRUE ( pModuleControl - > Load ( ( GetExecDirectory ( ) / " ComponentTest_Repository_test_module.sdv " ) . generic_u8string ( ) ) ) ;
//object creates new object during shutdown
//this is needed in case new proxies are requested during shutdown
bool bRes = pRepositoryControl - > CreateObject ( " TestObject_CreateDuringShutdown " , nullptr , nullptr ) ;
EXPECT_TRUE ( bRes ) ;
control . SetRunningMode ( ) ;
control . Shutdown ( ) ;
}
TEST ( RepositoryTest , CreateUtility )
{
sdv : : app : : CAppControl control ( R " code(
[ LogHandler ]
ViewFilter = " Fatal "
[ Application ]
Mode = " Essential "
) code " );
ASSERT_TRUE ( control . IsRunning ( ) ) ;
control . SetConfigMode ( ) ;
auto ptrUtility = sdv : : core : : CreateUtility ( " TOMLParserUtility " ) ;
ASSERT_TRUE ( ptrUtility ) ;
ptrUtility . Clear ( ) ;
ASSERT_FALSE ( ptrUtility ) ;
control . SetRunningMode ( ) ;
control . Shutdown ( ) ;
}
2026-03-27 14:12:49 +01:00
TEST ( RepositoryTest , MainApplication_GetInstalledAndLoadedComponent )
2025-11-04 13:28:06 +01:00
{
// 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(
[ LogHandler ]
ViewFilter = " Fatal "
[ Application ]
Mode = " Main "
Instance = 2005
) code " );
ASSERT_TRUE ( control . IsRunning ( ) ) ;
control . SetConfigMode ( ) ;
// The example object is part of the installation and should have automatically instantiated through the configuration.
auto pInterfaceAccess = sdv : : core : : GetObject < sdv : : IInterfaceAccess > ( " Example_Object_2 " ) ;
EXPECT_NE ( pInterfaceAccess , nullptr ) ;
control . SetRunningMode ( ) ;
control . Shutdown ( ) ;
}
2026-03-27 14:12:49 +01:00
TEST ( RepositoryTest , MainApplication_GetInstalledComponent )
2025-11-04 13:28:06 +01:00
{
// 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(
[ LogHandler ]
ViewFilter = " Fatal "
[ Application ]
Mode = " Main "
Instance = 2005
AppConfig = " " # override application config
) code " );
ASSERT_TRUE ( control . IsRunning ( ) ) ;
control . SetConfigMode ( ) ;
// The example object is part of the installation and should have be automatically instantiated.
auto pInterfaceAccess = sdv : : core : : GetObject < sdv : : IInterfaceAccess > ( " Example_Object_2 " ) ;
EXPECT_NE ( pInterfaceAccess , nullptr ) ;
control . SetRunningMode ( ) ;
control . Shutdown ( ) ;
}