Prune the source tree to the Release 2 build closure
Keep only what the Release 2 scope (46 targets) compiles and the build pipeline needs, derived from the run-5 build.ninja closure (46 targets + transitive deps) and a header scan resolved against the real -I roots of the compile rules: - 14133 tracked files removed (1.25 GB), incl. include/ArcGIS (1.03 GB), include/rti stubs (identical copies of the external RTI headers), out-of-scope Lts/Application, Lts/Viewer, Lts/Services/*, Lts/Tools generators, src/, tests/, specs/, translations/, external/ - kept: the 46 scope modules + their transitive service deps, codegen inputs (.xml, .grantlee), doxygen/ (configure_file at configure time), include/GeographicLib (libGeographicLib.so linked from the source tree), the 12 referenced include/ stub headers, pipeline files (new_docker_build_release2.sh, rpmbuild/, jenkins-ci-rme/, cmake/) - 7 CMakeLists updated: drop add_subdirectory calls of the removed dirs (tests, translations, Lts/Plugins/ProjectDataManagement, qav, scripts, CommonUnitTestsPlaceholder, httq, LtsRestClient, LtsWebSocket, TopicEditorBase, ConnectDialog, StyleManager, Routing, DdsUnitTests, DdsUnitTestsPlaceholder, Light, Dark, Test, ExerciseManagement, ParticipantManagement, the 3 tools generators) Result: 2157 tracked files (was 16290).
This commit is contained in:
1 parent
2b1c3dc241
commit
7fc6f66649
14140 files changed
+8
-2803418
No files matched your search
@@ -20,16 +20,5 @@ IF(BUILD_RTI)
|
||||
ENDIF()
|
||||
ADD_SUBDIRECTORY(FTS)
|
||||
ADD_SUBDIRECTORY(Generic)
|
||||
ADD_SUBDIRECTORY(Routing)
|
||||
|
||||
ADD_SUBDIRECTORY(Core)
|
||||
|
||||
# During stepwise migration, add placeholder CTest entries after the
|
||||
# real DdsUnitTests subdir so the test-suite can use real targets when
|
||||
# internal codegen/RTI targets are available, and fall back to placeholders
|
||||
# only when they are not.
|
||||
IF(BUILD_RTI)
|
||||
ADD_SUBDIRECTORY(DdsUnitTests)
|
||||
ENDIF()
|
||||
|
||||
ADD_SUBDIRECTORY(DdsUnitTestsPlaceholder)
|
||||
@@ -1,182 +0,0 @@
|
||||
#
|
||||
# $Id$
|
||||
# $HeadURL$
|
||||
# $Author$
|
||||
#
|
||||
|
||||
# Check for required targets - use simpler condition for INTERFACE library compatibility
|
||||
IF(BUILD_TESTING AND BUILD_RTI)
|
||||
# Verify required targets exist
|
||||
SET(_required_targets ddsgen ddsdtc ddsfts ddsQoS)
|
||||
SET(_targets_found TRUE)
|
||||
FOREACH(_tgt ${_required_targets})
|
||||
IF(NOT TARGET ${_tgt})
|
||||
SET(_targets_found FALSE)
|
||||
MESSAGE(WARNING "Required target ${_tgt} not found - DDS unit tests will not be built")
|
||||
ENDIF()
|
||||
ENDFOREACH()
|
||||
|
||||
IF(_targets_found)
|
||||
|
||||
SET(xml_FILE ddsut.xml)
|
||||
|
||||
SET(SRCS_common
|
||||
ddsut_export.h
|
||||
)
|
||||
# Generates ddsut.idl / ddsut_enums.idl
|
||||
IF(BUILD_GRANTLEE)
|
||||
CODEGEN_IDL_SVC(SRCS_common ${xml_FILE})
|
||||
ELSE()
|
||||
# BUILD_GRANTLEE disabled: check for pre-generated files
|
||||
IF(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/ddsut.idl" AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/ddsut_enums.idl")
|
||||
MESSAGE(STATUS "BUILD_GRANTLEE disabled: using pre-generated IDL files for ddsut")
|
||||
LIST(APPEND SRCS_common ddsut.idl ddsut_enums.idl)
|
||||
ELSE()
|
||||
MESSAGE(WARNING "BUILD_GRANTLEE disabled but no pre-generated IDL files found for ddsut. Skipping service.")
|
||||
SET(SRCS_common "")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
# Generate *.cpp/*.hpp from ddsut_enums.idl / ddsut.idl
|
||||
IF(BUILD_GRANTLEE OR (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/ddsut.idl" AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/ddsut_enums.idl"))
|
||||
RTIDDSGEN(SRCS_common ddsut_enums.idl)
|
||||
RTIDDSGEN(SRCS_common ddsut.idl)
|
||||
ENDIF()
|
||||
# Generate ddsut_dt[s,c]_types.h, ddsut_ft[s,c]_types.h
|
||||
CODEGEN_TOPIC_TYPEDEFS(SRCS_common ${xml_FILE})
|
||||
# generate ddsut_[d|f]tc.h
|
||||
IF(BUILD_GRANTLEE)
|
||||
CODEGEN_CLIENT_TOPICS_IFC(SRCS_common ${xml_FILE})
|
||||
ELSE()
|
||||
# Check for pre-generated files
|
||||
IF(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/ddsut_dtc.h" AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/ddsut_ftc.h")
|
||||
MESSAGE(STATUS "BUILD_GRANTLEE disabled: using pre-generated DTC/FTC files for ddsut")
|
||||
LIST(APPEND SRCS_common ddsut_dtc.h ddsut_ftc.h)
|
||||
ELSE()
|
||||
MESSAGE(WARNING "BUILD_GRANTLEE disabled but no pre-generated DTC/FTC files found for ddsut")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
NGL_ADD_LIBRARY2(ALL ddsut_common SHARED ${SRCS_common})
|
||||
IF(BUILD_RTI)
|
||||
NGL_TARGET_LINK_LIBRARIES(ddsut_common
|
||||
PRIVATE
|
||||
NGLLogger
|
||||
PUBLIC
|
||||
LtsUtilsCoreHeaderOnly
|
||||
Qt6::Core
|
||||
RTI::nddsc
|
||||
RTI::nddscore
|
||||
RTI::nddscpp2
|
||||
ddscore
|
||||
)
|
||||
ENDIF(BUILD_RTI)
|
||||
NGL_TARGET_INCLUDE_DIRECTORIES(ddsut_common
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../
|
||||
${CMAKE_CURRENT_BINARY_DIR}/../
|
||||
)
|
||||
|
||||
# -----------------------------------------------------------------------------------
|
||||
# Testing DataWriter/DataReader without DTS/DTC
|
||||
# -----------------------------------------------------------------------------------
|
||||
SET(SRCS_TEST1
|
||||
generic_data_tests.cpp
|
||||
generic_data_tests.h
|
||||
initialisation.cpp
|
||||
initialisation.h
|
||||
)
|
||||
|
||||
# -----------------------------------------------------------------------------------
|
||||
# Testing DataTopic Functionality (DTS/DTC)
|
||||
# -----------------------------------------------------------------------------------
|
||||
SET(SRCS_TEST2
|
||||
data_topic_tests_main.cpp
|
||||
data_topic_tests_main.h
|
||||
data_topic_tests.cpp
|
||||
data_topic_tests.h
|
||||
)
|
||||
|
||||
# -----------------------------------------------------------------------------------
|
||||
# Testing FunctionTopic Functionality (FTS/FTC)
|
||||
# -----------------------------------------------------------------------------------
|
||||
SET(SRCS_TEST3
|
||||
function_topic_tests.cpp
|
||||
function_topic_tests.h
|
||||
)
|
||||
|
||||
|
||||
# Testing DataWriter/DataReader without DTS/DTC
|
||||
ADD_EXECUTABLE(ddsGenericDataTests ${SRCS_TEST1})
|
||||
TARGET_LINK_LIBRARIES(ddsGenericDataTests
|
||||
ddsgen
|
||||
ddsdtc
|
||||
ddsQoS
|
||||
nglcoreapplication
|
||||
NGLLogger
|
||||
ProjectConfig
|
||||
Qt6::Core
|
||||
Qt6::Test
|
||||
ddsut_common
|
||||
)
|
||||
TARGET_INCLUDE_DIRECTORIES(ddsGenericDataTests PRIVATE
|
||||
${CMAKE_SOURCE_DIR}
|
||||
${CMAKE_SOURCE_DIR}/Lts/DDS
|
||||
)
|
||||
ADD_TEST(NAME ddsGenericDataTests COMMAND $<TARGET_FILE:ddsGenericDataTests>)
|
||||
|
||||
# Testing DataTopic Functionality (DTS/DTC)
|
||||
ADD_EXECUTABLE(ddsDataTopicTests ${SRCS_TEST2})
|
||||
TARGET_LINK_LIBRARIES(ddsDataTopicTests
|
||||
nglcoreapplication
|
||||
NGLLogger
|
||||
RTI::nddscpp2
|
||||
ddsgen
|
||||
ddsdts
|
||||
ddsdtc
|
||||
ddsQoS
|
||||
ProjectConfig
|
||||
Qt6::Core
|
||||
Qt6::Test
|
||||
ddsut_common
|
||||
)
|
||||
TARGET_INCLUDE_DIRECTORIES(ddsDataTopicTests PRIVATE
|
||||
${CMAKE_SOURCE_DIR}
|
||||
${CMAKE_SOURCE_DIR}/Lts
|
||||
${CMAKE_SOURCE_DIR}/Lts/DDS
|
||||
)
|
||||
ADD_TEST(NAME ddsDataTopicTests COMMAND $<TARGET_FILE:ddsDataTopicTests>)
|
||||
|
||||
# Testing FunctionTopic Functionality (FTS/FTC)
|
||||
ADD_EXECUTABLE(ddsFunctionTopicTests ${SRCS_TEST3})
|
||||
TARGET_LINK_LIBRARIES(ddsFunctionTopicTests
|
||||
ddsgen
|
||||
ddsfts
|
||||
ddsftc
|
||||
ddsQoS
|
||||
ddsconnector
|
||||
nglcoreapplication
|
||||
NGLLogger
|
||||
ngltools
|
||||
Qt6::Core
|
||||
Qt6::Test
|
||||
ddsut_common
|
||||
)
|
||||
TARGET_INCLUDE_DIRECTORIES(ddsFunctionTopicTests PRIVATE
|
||||
${CMAKE_SOURCE_DIR}
|
||||
${CMAKE_SOURCE_DIR}/Lts
|
||||
${CMAKE_SOURCE_DIR}/Lts/DDS
|
||||
)
|
||||
ADD_TEST(NAME ddsFunctionTopicTests COMMAND $<TARGET_FILE:ddsFunctionTopicTests>)
|
||||
|
||||
ENDIF() # _targets_found
|
||||
|
||||
IF(NOT BUILD_RPM)
|
||||
NGL_INSTALL(AAR SV TARGETS ddsut_common DESTINATION bin/test)
|
||||
NGL_INSTALL(AAR SV TARGETS ddsGenericDataTests DESTINATION bin/test)
|
||||
NGL_INSTALL(AAR SV TARGETS ddsDataTopicTests DESTINATION bin/test)
|
||||
NGL_INSTALL(AAR SV TARGETS ddsFunctionTopicTests DESTINATION bin/test)
|
||||
|
||||
NGL_INSTALL(AAR SV FILES log4cxx_ddsUnitTests.props DESTINATION bin/test)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
@@ -1,130 +0,0 @@
|
||||
|
||||
|
||||
#include "data_topic_tests.h"
|
||||
|
||||
#include <DDS/DTC/generic_dtc_impl.h>
|
||||
#include <DDS/DTS/generic_dts_impl.h>
|
||||
#include <DDS/QosProfile/DDS_DefaultQos.h>
|
||||
#include <Lts/Common/ProjectConfig/project_defines.h>
|
||||
#include <NGLLogger/NGLLoggerBootstrap.h>
|
||||
#include <QtCore/QThread>
|
||||
#include <QtCore/QVariant>
|
||||
#include <QtTest/QTest>
|
||||
|
||||
DataTopicTests::DataTopicTests()
|
||||
: m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("UnitTests.DataTopicTests"))
|
||||
, m_domainParticipantPub(nullptr)
|
||||
, m_domainParticipantSub(nullptr)
|
||||
, m_domainId(0)
|
||||
, m_partitionId(1)
|
||||
, m_ddsPublisher(nullptr)
|
||||
, m_testPart(nullptr)
|
||||
, m_ddsSubscriber(nullptr)
|
||||
, m_subscriberListener(nullptr)
|
||||
, m_dtcTestPart(nullptr)
|
||||
, m_mainThreadId(QThread::currentThreadId())
|
||||
{
|
||||
if (!DDS::QosProfile::setDefault())
|
||||
ERROR_LOG(m_logger) << "Error setting default QoS from xml-file ";
|
||||
|
||||
DEBUG_LOG(m_logger) << "Main thread ID is " << m_mainThreadId;
|
||||
}
|
||||
|
||||
DataTopicTests::~DataTopicTests()
|
||||
{
|
||||
|
||||
delete m_testPart;
|
||||
|
||||
delete m_dtcTestPart;
|
||||
|
||||
delete m_subscriberListener;
|
||||
}
|
||||
|
||||
bool DataTopicTests::initPublisher()
|
||||
{
|
||||
m_domainParticipantPub = dds::domain::DomainParticipant(m_domainId, DDS::QosProfile::domainParticipantShm());
|
||||
|
||||
dds::pub::qos::PublisherQos publisherQos = m_domainParticipantPub.default_publisher_qos();
|
||||
|
||||
QString partition = QString::fromStdString(IDL::exercisePartition(m_partitionId));
|
||||
|
||||
dds::core::policy::Partition partitionQos;
|
||||
partitionQos.name({partition.toStdString()});
|
||||
publisherQos << partitionQos;
|
||||
|
||||
DEBUG_LOG(m_logger) << "Publish on partition " << partition;
|
||||
|
||||
m_ddsPublisher = dds::pub::Publisher(m_domainParticipantPub, publisherQos);
|
||||
m_testPart = new DTS::TestParticipantImpl(m_domainParticipantPub, m_ddsPublisher);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DataTopicTests::write(const DdsUnitTests::TestParticipant& data)
|
||||
{
|
||||
INFO_LOG(m_logger) << "Publish topic TestParticipant ";
|
||||
DEBUG_LOG(m_logger) << "ParticipantId: " << data.location.participantId
|
||||
<< ", equipNo = " << data.location.equipNo;
|
||||
|
||||
return m_testPart->write(data);
|
||||
}
|
||||
|
||||
bool DataTopicTests::initSubscriber()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Initialisation DDS (Subscriber/Reader)";
|
||||
|
||||
m_domainParticipantSub = dds::domain::DomainParticipant(m_domainId, DDS::QosProfile::domainParticipantShm());
|
||||
|
||||
dds::sub::qos::SubscriberQos subscriberQos = m_domainParticipantSub.default_subscriber_qos();
|
||||
|
||||
dds::core::StringSeq partitions;
|
||||
partitions.reserve(1);
|
||||
for (int partitionId : {1})
|
||||
{
|
||||
partitions.push_back(IDL::exercisePartition(partitionId));
|
||||
}
|
||||
|
||||
dds::core::policy::Partition partitionQos;
|
||||
partitionQos.name(partitions);
|
||||
subscriberQos << partitionQos;
|
||||
|
||||
DEBUG_LOG(m_logger) << "Initialise DTC::SubscriberListener";
|
||||
m_subscriberListener = new DDSGeneric::SubscriberListener();
|
||||
m_ddsSubscriber = dds::sub::Subscriber(m_domainParticipantSub, subscriberQos, m_subscriberListener,
|
||||
DDSGeneric::SubscriberListener::mask());
|
||||
|
||||
m_dtcTestPart =
|
||||
new DTC::SampleInfo::TestParticipantImpl(m_domainParticipantSub, m_ddsSubscriber, m_subscriberListener);
|
||||
|
||||
m_dtcTestPart->setSubscriberCallback(
|
||||
[this](const DdsUnitTests::TestParticipant& data, const dds::sub::SampleInfo& si) { processData(data, si); });
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DataTopicTests::deleteDTC()
|
||||
{
|
||||
delete m_dtcTestPart;
|
||||
m_dtcTestPart = nullptr;
|
||||
}
|
||||
|
||||
void DataTopicTests::deleteSubscriber()
|
||||
{
|
||||
m_ddsSubscriber = nullptr;
|
||||
delete m_subscriberListener;
|
||||
m_subscriberListener = nullptr;
|
||||
}
|
||||
|
||||
void DataTopicTests::processData(const DdsUnitTests::TestParticipant& instance, const dds::sub::SampleInfo& si)
|
||||
{
|
||||
INFO_LOG(m_logger) << "process data in topic TestParticipant, Sampleinfo: " << si.source_timestamp().sec();
|
||||
|
||||
DEBUG_LOG(m_logger) << "participantId: " << instance.location.participantId;
|
||||
DEBUG_LOG(m_logger) << "equipNo: " << instance.location.equipNo;
|
||||
|
||||
m_receivedParticipantData = instance;
|
||||
|
||||
QCOMPARE(m_mainThreadId, QThread::currentThreadId());
|
||||
|
||||
emit testParticipantDataArrived();
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <DDS/Generic/subscriber_listener.h>
|
||||
#include <DdsUnitTests/ddsut_dtc_types.h>
|
||||
#include <DdsUnitTests/ddsut_dts_types.h>
|
||||
#include <QtCore/QObject>
|
||||
#include <dds/pub/Publisher.hpp>
|
||||
#include <dds/sub/Subscriber.hpp>
|
||||
|
||||
namespace NGL
|
||||
{
|
||||
class INGLLogger;
|
||||
}
|
||||
|
||||
class DataTopicTests : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
DataTopicTests();
|
||||
virtual ~DataTopicTests();
|
||||
|
||||
bool initPublisher();
|
||||
bool initSubscriber();
|
||||
|
||||
bool write(const DdsUnitTests::TestParticipant& data);
|
||||
|
||||
DdsUnitTests::TestParticipant getReceivedParticipantData() const
|
||||
{
|
||||
return m_receivedParticipantData;
|
||||
}
|
||||
|
||||
void deleteDTC();
|
||||
void deleteSubscriber();
|
||||
|
||||
protected:
|
||||
NGL::INGLLogger& m_logger;
|
||||
void processData(const DdsUnitTests::TestParticipant& instance, const dds::sub::SampleInfo& si);
|
||||
|
||||
Q_SIGNALS:
|
||||
void testParticipantDataArrived();
|
||||
|
||||
private:
|
||||
dds::domain::DomainParticipant m_domainParticipantPub;
|
||||
dds::domain::DomainParticipant m_domainParticipantSub;
|
||||
int m_domainId;
|
||||
int m_partitionId;
|
||||
|
||||
dds::pub::Publisher m_ddsPublisher;
|
||||
DTS::TestParticipant* m_testPart;
|
||||
|
||||
dds::sub::Subscriber m_ddsSubscriber;
|
||||
DDSGeneric::SubscriberListener* m_subscriberListener;
|
||||
|
||||
DTC::SampleInfo::TestParticipant* m_dtcTestPart;
|
||||
|
||||
Qt::HANDLE m_mainThreadId;
|
||||
|
||||
DdsUnitTests::TestParticipant m_receivedParticipantData;
|
||||
};
|
||||
@@ -1,96 +0,0 @@
|
||||
|
||||
|
||||
#include "data_topic_tests_main.h"
|
||||
|
||||
#include "data_topic_tests.h"
|
||||
|
||||
#include <Lts/Common/ProjectConfig/project_defines.h>
|
||||
#include <NGLLogger/NGLLoggerBootstrap.h>
|
||||
#include <QtTest/QTest>
|
||||
#include <nglapplication/nglcoreapplication.h>
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
NGLCoreApplication app(argc, argv);
|
||||
app.createLogger("UnitTests", "log4cxx_ddsUnitTests.props");
|
||||
|
||||
DataTopicTestsMain* tc = new DataTopicTestsMain;
|
||||
|
||||
int retCode = QTest::qExec(tc, argc, argv);
|
||||
|
||||
delete tc;
|
||||
|
||||
return retCode;
|
||||
}
|
||||
|
||||
DataTopicTestsMain::DataTopicTestsMain()
|
||||
: m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("UnitTests.DataTopicTestsMain"))
|
||||
{
|
||||
}
|
||||
|
||||
void DataTopicTestsMain::initTestCase()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "DataTopicTestsMain: initTestCase";
|
||||
|
||||
m_dtTest = new DataTopicTests();
|
||||
QVERIFY2(m_dtTest, "Initialisation of DataTopicTest failed");
|
||||
QVERIFY2(m_dtTest->initPublisher(), "Initialisation Publisher failed");
|
||||
QVERIFY2(m_dtTest->initSubscriber(), "Initialisation Subscriber failed");
|
||||
|
||||
m_participantDataArrivedSpy = new QSignalSpy(m_dtTest, &DataTopicTests::testParticipantDataArrived);
|
||||
}
|
||||
|
||||
void DataTopicTestsMain::publishTestCase()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "DataTopicTestsMain: publish TestParticipant";
|
||||
|
||||
m_sentParticipantData.location.participantId = 100;
|
||||
m_sentParticipantData.location.equipNo = 1010;
|
||||
m_sentParticipantData.testId = 100;
|
||||
QVERIFY2(m_dtTest->write(m_sentParticipantData), "Publishing Topic TestParticipant failed");
|
||||
|
||||
DEBUG_LOG(m_logger) << "DataTopicTestsMain: publish ready";
|
||||
}
|
||||
|
||||
void DataTopicTestsMain::subscribeTestCase()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "IN subscribeTestCase";
|
||||
|
||||
QTRY_COMPARE(m_participantDataArrivedSpy->count(), 1);
|
||||
|
||||
DdsUnitTests::TestParticipant recvPartiticpant = m_dtTest->getReceivedParticipantData();
|
||||
|
||||
QCOMPARE(recvPartiticpant.location.participantId, m_sentParticipantData.location.participantId);
|
||||
QCOMPARE(recvPartiticpant.location.equipNo, m_sentParticipantData.location.equipNo);
|
||||
}
|
||||
|
||||
void DataTopicTestsMain::deleteDataReaderTestCase()
|
||||
{
|
||||
DdsUnitTests::TestParticipant data;
|
||||
for (int i = 0; i < 1000; ++i)
|
||||
{
|
||||
m_sentParticipantData.id = i;
|
||||
m_dtTest->write(m_sentParticipantData);
|
||||
}
|
||||
m_dtTest->deleteDTC();
|
||||
for (int i = 0; i < 1000; ++i)
|
||||
{
|
||||
m_sentParticipantData.id = i;
|
||||
m_dtTest->write(m_sentParticipantData);
|
||||
}
|
||||
m_dtTest->deleteSubscriber();
|
||||
for (int i = 0; i < 1000; ++i)
|
||||
{
|
||||
m_sentParticipantData.id = i;
|
||||
m_dtTest->write(m_sentParticipantData);
|
||||
}
|
||||
}
|
||||
|
||||
void DataTopicTestsMain::cleanupTestCase()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "DataTopicTestsMain: cleanupTestCase";
|
||||
delete m_dtTest;
|
||||
m_dtTest = nullptr;
|
||||
delete m_participantDataArrivedSpy;
|
||||
m_participantDataArrivedSpy = nullptr;
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <DdsUnitTests/ddsut_dtc_types.h>
|
||||
#include <QtCore/QObject>
|
||||
#include <QSignalSpy>
|
||||
|
||||
namespace NGL
|
||||
{
|
||||
class INGLLogger;
|
||||
}
|
||||
|
||||
class DataTopicTests;
|
||||
|
||||
class DataTopicTestsMain : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DataTopicTestsMain();
|
||||
|
||||
private Q_SLOTS:
|
||||
void initTestCase();
|
||||
void publishTestCase();
|
||||
void subscribeTestCase();
|
||||
void deleteDataReaderTestCase();
|
||||
void cleanupTestCase();
|
||||
|
||||
protected:
|
||||
NGL::INGLLogger& m_logger;
|
||||
|
||||
private:
|
||||
DdsUnitTests::TestParticipant m_sentParticipantData;
|
||||
QSignalSpy* m_participantDataArrivedSpy = nullptr;
|
||||
DataTopicTests* m_dtTest = nullptr;
|
||||
};
|
||||
@@ -1,123 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<service namespace="DdsUnitTests" abbreviation="DDSUT" procNames="">
|
||||
<rcs>
|
||||
<Id Id="$Id: core.xml 38132 2018-01-10 07:52:50Z ehrlicher $"/>
|
||||
<HeadURL HeadURL="$HeadURL: svn://slssvn/TDS/branches/product/devel/trunk/Lts/DDS/Core/core.xml $"/>
|
||||
<Author Author="$Author: ehrlicher $"/>
|
||||
</rcs>
|
||||
<tables/>
|
||||
<views/>
|
||||
<topicTypes>
|
||||
<topicType name="BaseEntity">
|
||||
<column name="id" idlType="long" isKey="1"/>
|
||||
<column name="name" idlType="string"/>
|
||||
<column name="isDeleted" idlType="boolean"/>
|
||||
<column name="isUsed" idlType="boolean" comment="Defines if it is used by others (i.e. foreign key constraint)"/>
|
||||
<column name="isBlockedForEdit" idlType="boolean"/>
|
||||
</topicType>
|
||||
<topicType name="BaseEntityTranslatable">
|
||||
<column name="id" idlType="long" isKey="1"/>
|
||||
<column name="name" idlType="string" isTranslatable="1"/>
|
||||
<column name="isDeleted" idlType="boolean"/>
|
||||
<column name="isUsed" idlType="boolean" comment="Defines if it is used by others (i.e. foreign key constraint)"/>
|
||||
<column name="isBlockedForEdit" idlType="boolean"/>
|
||||
</topicType>
|
||||
<topicType name="BaseEntityWithSampleTime" extensibility="EXTENSIBLE" baseValueType="BaseEntity">
|
||||
<column name="sampleTime" idlType="long long" comment="Timestamp"/>
|
||||
</topicType>
|
||||
<topicType name="CurrentRunningState" isDataObject="1" routeToClient="0" routeInReplay="0">
|
||||
<column name="pid" idlType="long long" isKey="1"/>
|
||||
<column name="runningState" idlType="Core::RunningState"/>
|
||||
<column name="ports" idlType="sequence<PortInformation>" isOptional="1"/>
|
||||
<column name="errorString" idlType="string" isOptional="1"/>
|
||||
</topicType>
|
||||
<topicType name="Entity" extensibility="EXTENSIBLE" baseValueType="BaseEntityWithSampleTime">
|
||||
<column name="location" idlType="SpatialData"/>
|
||||
<column name="symbolId" idlType="long"/>
|
||||
</topicType>
|
||||
<topicType name="FunctionReply">
|
||||
<column name="id" idlType="long"/>
|
||||
<column name="errorString" idlType="string"/>
|
||||
<column name="errorParams" idlType="sequence<string>"/>
|
||||
</topicType>
|
||||
<topicType name="FunctionReplyWithState" baseValueType="FunctionReply">
|
||||
<column name="replyState" idlType="Core::FtReplyState"/>
|
||||
</topicType>
|
||||
<topicType name="FunctionRequest">
|
||||
<column name="id" idlType="long"/>
|
||||
<column name="value" idlType="double"/>
|
||||
<column name="info" idlType="string" isOptional="1"/>
|
||||
</topicType>
|
||||
<topicType name="FunctionRequestWithState" baseValueType="FunctionRequest">
|
||||
<column name="status" idlType="long"/>
|
||||
</topicType>
|
||||
<topicType name="GeoPosition" extensibility="FINAL">
|
||||
<column name="lon" idlType="double"/>
|
||||
<column name="lat" idlType="double"/>
|
||||
<column name="z" idlType="double" comment="height above ground"/>
|
||||
</topicType>
|
||||
<topicType name="GeoPosition2D" extensibility="FINAL">
|
||||
<column name="lon" idlType="double" comment="[m]"/>
|
||||
<column name="lat" idlType="double" comment="[m]"/>
|
||||
</topicType>
|
||||
<topicType name="Orientation" extensibility="FINAL">
|
||||
<column name="heave" idlType="double"/>
|
||||
<column name="pitch" idlType="double"/>
|
||||
<column name="roll" idlType="double"/>
|
||||
</topicType>
|
||||
<topicType name="PartitionTime" isDataObject="1" routeToClient="1" routeInReplay="0">
|
||||
<column name="timeStamp" idlType="long long"/>
|
||||
</topicType>
|
||||
<topicType name="PortInformation">
|
||||
<column name="number" idlType="long"/>
|
||||
<column name="type" idlType="DdsutPortType"/>
|
||||
</topicType>
|
||||
<topicType name="RelativePosition">
|
||||
<column name="offsetX" idlType="double" comment="in meter"/>
|
||||
<column name="offsetY" idlType="double" comment="in meter"/>
|
||||
<column name="offsetZ" idlType="double" comment="in meter"/>
|
||||
</topicType>
|
||||
<topicType name="RemoveElementRequest">
|
||||
<column name="id" idlType="long"/>
|
||||
</topicType>
|
||||
<topicType name="ReplayPartition" isDataObject="1" routeToClient="1" routeInReplay="0">
|
||||
<column name="id" idlType="long" isKey="1"/>
|
||||
<column name="name" idlType="string"/>
|
||||
<column name="exerciseId" idlType="long"/>
|
||||
<column name="workstationId" idlType="long"/>
|
||||
<column name="operatorId" idlType="long"/>
|
||||
<column name="replayType" idlType="Core::ReplayType"/>
|
||||
<column name="domainId" idlType="long"/>
|
||||
<column name="tcpConnectionUrl" idlType="string"/>
|
||||
</topicType>
|
||||
<topicType name="SpatialData" isDataObject="1" routeToClient="0" routeInReplay="0">
|
||||
<column name="changedAt" idlType="long"/>
|
||||
<column name="equipNo" idlType="long"/>
|
||||
<column name="gpsPosition" idlType="GeoPosition"/>
|
||||
<column name="orientation" idlType="Orientation"/>
|
||||
<column name="participantId" idlType="long"/>
|
||||
<column name="velocity" idlType="Velocity"/>
|
||||
</topicType>
|
||||
<topicType name="TestParticipant" isDataObject="1" routeToClient="0" routeInReplay="0" recordTopic="1" baseValueType="Entity">
|
||||
<column name="designator" idlType="string<20>"/>
|
||||
<column name="testId" idlType="long"/>
|
||||
<column name="gpsQuality" idlType="short"/>
|
||||
<column name="equipmentNumber" idlType="long"/>
|
||||
</topicType>
|
||||
<topicType name="Velocity">
|
||||
<column name="x" idlType="double"/>
|
||||
<column name="y" idlType="double"/>
|
||||
<column name="z" idlType="double"/>
|
||||
</topicType>
|
||||
</topicTypes>
|
||||
<functionTopics>
|
||||
<functionTopic name="FunctionTopicTest" requestTopicType="FunctionRequest" replyTopicType="FunctionReply" requestTopicName="FunctionTopicTestRequest" replyTopicName="FunctionTopicTestReply" routeInReplay="0"/>
|
||||
<functionTopic name="FunctionTopicTestWithState" requestTopicType="FunctionRequestWithState" replyTopicType="FunctionReplyWithState" requestTopicName="FunctionTopicTestWithStateRequest" replyTopicName="FunctionTopicTestWithStateReply" routeInReplay="0"/>
|
||||
</functionTopics>
|
||||
<enumerations>
|
||||
<enumeration name="DdsutPortType">
|
||||
<attribute key="Unknown" value="0"/>
|
||||
<attribute key="WebSocketServer" value="1"/>
|
||||
</enumeration>
|
||||
</enumerations>
|
||||
</service>
|
||||
@@ -1,23 +0,0 @@
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
#ifndef DDSUT_COMMON_EXPORT
|
||||
# ifdef BUILD_STATIC_LIBRARIES
|
||||
# define DDSUT_COMMON_EXPORT
|
||||
# else
|
||||
# if defined(MAKE_DDSUT_COMMON_LIB)
|
||||
# define DDSUT_COMMON_EXPORT Q_DECL_EXPORT
|
||||
# ifndef WIN32
|
||||
# ifdef NDDSUSERDllExport
|
||||
# undef NDDSUSERDllExport
|
||||
# endif
|
||||
# define NDDSUSERDllExport Q_DECL_EXPORT
|
||||
# endif
|
||||
# else
|
||||
# define DDSUT_COMMON_EXPORT Q_DECL_IMPORT
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
@@ -1,241 +0,0 @@
|
||||
|
||||
|
||||
#include "function_topic_tests.h"
|
||||
#include <NGLLogger/NGLLoggerBootstrap.h>
|
||||
|
||||
#include <DDS/DDSConnector/publisher.h>
|
||||
#include <DDS/DDSConnector/subscriber.h>
|
||||
#include <Lts/Common/ProjectConfig/project_defines.h>
|
||||
#include <NGLLogger/INGLLogger.h>
|
||||
#include <QtTest/QTest>
|
||||
#include <nglapplication/nglcoreapplication.h>
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
NGLCoreApplication app(argc, argv);
|
||||
app.createLogger("UnitTests", "log4cxx_ddsUnitTests.props");
|
||||
|
||||
FunctionTopicTests* tc = new FunctionTopicTests;
|
||||
|
||||
int retCode = QTest::qExec(tc, argc, argv);
|
||||
|
||||
delete tc;
|
||||
|
||||
return retCode;
|
||||
}
|
||||
|
||||
FunctionTopicTests::FunctionTopicTests()
|
||||
: m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("UnitTests.FunctionTopicTests"))
|
||||
, m_mainThreadId(QThread::currentThreadId())
|
||||
{
|
||||
qRegisterMetaType<DdsUnitTests::FunctionReply>("DdsUnitTests::FunctionReply");
|
||||
qRegisterMetaType<DdsUnitTests::FunctionReplyWithState>("DdsUnitTests::FunctionReplyWithState");
|
||||
}
|
||||
|
||||
void FunctionTopicTests::initTestCase()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "FunctionTopicTests: initTestCase";
|
||||
|
||||
const int domainId = 0;
|
||||
|
||||
m_ddsConnectorClient = std::make_shared<DDSConnector::DdsConnector>(domainId, IDL::PartitionType::Global);
|
||||
QVERIFY2(m_ddsConnectorClient->init(), "Initialisation of ddsconnector (Client) failed");
|
||||
m_ddsConnectorClient->initSubscriber();
|
||||
QVERIFY2(m_ddsConnectorClient->getSubscriber(), "Initialisation of Subscriber (DdsConnectorClient) failed");
|
||||
m_ddsConnectorClient->initPublisher();
|
||||
QVERIFY2(m_ddsConnectorClient->getPublisher(), "Initialisation of Publisher (DdsConnectorClient) failed");
|
||||
|
||||
m_ddsConnectorServer = std::make_shared<DDSConnector::DdsConnector>(domainId, IDL::PartitionType::Global);
|
||||
QVERIFY2(m_ddsConnectorServer->init(), "Initialisation of ddsconnector (Server) failed");
|
||||
m_ddsConnectorServer->initSubscriber();
|
||||
QVERIFY2(m_ddsConnectorServer->getSubscriber(), "Initialisation of Subscriber (DdsConnectorServer) failed");
|
||||
m_ddsConnectorServer->initPublisher();
|
||||
QVERIFY2(m_ddsConnectorServer->getPublisher(), "Initialisation of Publisher (DdsConnectorServer) failed");
|
||||
}
|
||||
|
||||
void FunctionTopicTests::initFTSTestCase()
|
||||
{
|
||||
m_fts.reset(m_ddsConnectorServer->createFTS<FTS::FunctionTopicTest>());
|
||||
QVERIFY2(m_fts.get(), "Initialisation of FTS Replier failed");
|
||||
m_fts->setSubscriberCallback(
|
||||
[this](const rti::core::SampleIdentity& identity, const DdsUnitTests::FunctionRequest& request) {
|
||||
this->onFunctionTopicRequest(identity, request);
|
||||
});
|
||||
|
||||
m_ftsWS.reset(m_ddsConnectorServer->createFTS<FTS::FunctionTopicTestWithState>());
|
||||
QVERIFY2(m_ftsWS.get(), "Initialisation of FTS Replier failed");
|
||||
m_ftsWS->setSubscriberCallback(
|
||||
[this](const rti::core::SampleIdentity& identity, const DdsUnitTests::FunctionRequestWithState& request) {
|
||||
this->onFunctionTopicRequest(identity, request);
|
||||
});
|
||||
}
|
||||
|
||||
void FunctionTopicTests::initFTCTestCase()
|
||||
{
|
||||
m_ftc.reset(m_ddsConnectorClient->createFTC<FTC::FunctionTopicTest>(this));
|
||||
QVERIFY2(m_ftc.get(), "Initialisation of FTC Requester failed");
|
||||
m_ftcWS.reset(m_ddsConnectorClient->createFTC<FTC::FunctionTopicTestWithState>(this));
|
||||
QVERIFY2(m_ftc.get(), "Initialisation of FTC Requester failed");
|
||||
}
|
||||
|
||||
void FunctionTopicTests::requestTestCase1()
|
||||
{
|
||||
|
||||
requestWithState();
|
||||
|
||||
QCOMPARE(m_ddsConnectorServer->getWaitSetHandler()->attachedConditionCount(), 3);
|
||||
requestWithState();
|
||||
|
||||
QCOMPARE(m_ddsConnectorServer->getWaitSetHandler()->attachedConditionCount(), 3);
|
||||
}
|
||||
|
||||
void FunctionTopicTests::requestWithState()
|
||||
{
|
||||
|
||||
QSignalSpy spyRequest(this, &FunctionTopicTests::functionTopicRequestFinished);
|
||||
QSignalSpy spyReply(this, &FunctionTopicTests::functionTopicReply);
|
||||
|
||||
DEBUG_LOG(m_logger) << "FunctionTopicTests: request";
|
||||
|
||||
DdsUnitTests::FunctionRequestWithState data;
|
||||
|
||||
data.id = 1;
|
||||
data.info = std::string("Test request");
|
||||
data.value = 1000.0;
|
||||
|
||||
int uniqueId = 0;
|
||||
bool bRet = m_ftcWS->requestDataClassic(
|
||||
data, SLOT(slotRequestedData(DdsUnitTests::FunctionTopicTestWithStateReply,int,bool)),
|
||||
SLOT(slotRequestedDataError(int,int,int)), uniqueId);
|
||||
|
||||
QVERIFY2(bRet, "Could not request data!");
|
||||
|
||||
QTRY_COMPARE(spyRequest.count(), 1);
|
||||
QTRY_COMPARE(spyReply.count(), 2);
|
||||
}
|
||||
|
||||
void FunctionTopicTests::requestTestCase2()
|
||||
{
|
||||
|
||||
QSignalSpy spyRequest(this, &FunctionTopicTests::functionTopicRequestFinished);
|
||||
QSignalSpy spyReply(this, &FunctionTopicTests::functionTopicReply);
|
||||
|
||||
DEBUG_LOG(m_logger) << "FunctionTopicTests: request";
|
||||
|
||||
DdsUnitTests::FunctionRequest data;
|
||||
|
||||
data.id = 1;
|
||||
data.info = std::string("Test request");
|
||||
data.value = 1000.0;
|
||||
|
||||
int uniqueId = 0;
|
||||
bool bRet =
|
||||
m_ftc->requestDataClassic(data, SLOT(slotRequestedData(DdsUnitTests::FunctionTopicTestReply,int,bool)),
|
||||
SLOT(slotRequestedDataError(int,int,int)), uniqueId);
|
||||
|
||||
QVERIFY2(bRet, "Could not request data!");
|
||||
|
||||
QTRY_COMPARE(spyRequest.count(), 1);
|
||||
QTRY_COMPARE(spyReply.count(), 1);
|
||||
}
|
||||
|
||||
void FunctionTopicTests::cleanupTestCase()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "FunctionTopicTests: cleanupTestCase";
|
||||
|
||||
m_fts = nullptr;
|
||||
m_ftc = nullptr;
|
||||
m_ftsWS = nullptr;
|
||||
m_ftcWS = nullptr;
|
||||
m_ddsConnectorServer = nullptr;
|
||||
m_ddsConnectorClient = nullptr;
|
||||
}
|
||||
|
||||
void FunctionTopicTests::onFunctionTopicRequest(const rti::core::SampleIdentity& sampleId,
|
||||
const DdsUnitTests::FunctionRequestWithState& request)
|
||||
{
|
||||
QCOMPARE(m_mainThreadId, QThread::currentThreadId());
|
||||
|
||||
INFO_LOG(m_logger) << "Got function topic request (with status member)";
|
||||
m_requestTopicWithState = request;
|
||||
QCOMPARE(m_requestTopicWithState.id, 1);
|
||||
QCOMPARE(m_requestTopicWithState.info.get(), std::string("Test request"));
|
||||
QCOMPARE(m_requestTopicWithState.value, 1000.0);
|
||||
|
||||
DdsUnitTests::FunctionReplyWithState reply;
|
||||
|
||||
DEBUG_LOG(m_logger) << "Send sample with status REPLY_COMPLETED";
|
||||
reply.id = 1;
|
||||
reply.errorString = "Hello";
|
||||
reply.replyState = Core::FtReplyState::Completed;
|
||||
|
||||
bool bRet = m_ftsWS->sendReply(sampleId, reply);
|
||||
QVERIFY2(bRet, "Sending Reply failed");
|
||||
|
||||
emit functionTopicRequestFinished();
|
||||
}
|
||||
|
||||
void FunctionTopicTests::onFunctionTopicRequest(const rti::core::SampleIdentity& sampleId,
|
||||
const DdsUnitTests::FunctionRequest& request)
|
||||
{
|
||||
QCOMPARE(m_mainThreadId, QThread::currentThreadId());
|
||||
|
||||
INFO_LOG(m_logger) << "Got function topic request (without status member)";
|
||||
|
||||
m_requestTopic = request;
|
||||
|
||||
DdsUnitTests::FunctionReply reply;
|
||||
|
||||
reply.id = 2;
|
||||
reply.errorString = "What?";
|
||||
|
||||
bool bRet = m_fts->sendReply(sampleId, reply);
|
||||
QVERIFY2(bRet, "Sending Reply failed");
|
||||
|
||||
emit functionTopicRequestFinished();
|
||||
}
|
||||
|
||||
void FunctionTopicTests::slotRequestedData(const DdsUnitTests::FunctionTopicTestWithStateReply& reply, int seqNo,
|
||||
bool bFinished)
|
||||
{
|
||||
Q_UNUSED(seqNo);
|
||||
QCOMPARE(m_mainThreadId, QThread::currentThreadId());
|
||||
|
||||
INFO_LOG(m_logger) << "Got reply from FTS: " << reply.replyState;
|
||||
|
||||
m_replyTopicWithState = reply;
|
||||
|
||||
if (m_replyTopicWithState.replyState == Core::FtReplyState::InProgress)
|
||||
{
|
||||
QVERIFY(!bFinished);
|
||||
QCOMPARE(m_replyTopicWithState.id, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
QVERIFY(bFinished);
|
||||
QCOMPARE(m_replyTopicWithState.id, 1);
|
||||
QCOMPARE(m_replyTopicWithState.errorString, std::string("Hello"));
|
||||
QCOMPARE(static_cast<int>(m_replyTopicWithState.replyState), static_cast<int>(Core::FtReplyState::Completed));
|
||||
}
|
||||
emit functionTopicReply();
|
||||
}
|
||||
|
||||
void FunctionTopicTests::slotRequestedData(const DdsUnitTests::FunctionTopicTestReply& reply, int seqNo, bool bFinished)
|
||||
{
|
||||
Q_UNUSED(seqNo);
|
||||
QVERIFY(bFinished);
|
||||
QCOMPARE(m_mainThreadId, QThread::currentThreadId());
|
||||
|
||||
m_replyTopic = reply;
|
||||
QCOMPARE(m_replyTopic.id, 2);
|
||||
QCOMPARE(m_replyTopic.errorString, std::string("What?"));
|
||||
|
||||
emit functionTopicReply();
|
||||
}
|
||||
|
||||
void FunctionTopicTests::slotRequestedDataError(int reason, int seqNo, int requestId)
|
||||
{
|
||||
Q_UNUSED(seqNo);
|
||||
Q_UNUSED(requestId);
|
||||
QFAIL(qPrintable(QStringLiteral("Error when trying to request data: %1").arg(reason)));
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <DDS/DDSConnector/dds_connector.h>
|
||||
#include <DDS/FTC/generic_ftc_impl.h>
|
||||
#include <DDS/FTS/generic_fts_impl.h>
|
||||
#include <DdsUnitTests/ddsut.hpp>
|
||||
#include <DdsUnitTests/ddsut_ftc_types.h>
|
||||
#include <DdsUnitTests/ddsut_fts_types.h>
|
||||
#include <QtCore/QObject>
|
||||
#include <QSignalSpy>
|
||||
#include <QtCore/QThread>
|
||||
|
||||
namespace NGL
|
||||
{
|
||||
class INGLLogger;
|
||||
}
|
||||
|
||||
class FunctionTopicTests : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
FunctionTopicTests();
|
||||
|
||||
private Q_SLOTS:
|
||||
void initTestCase();
|
||||
void initFTSTestCase();
|
||||
void initFTCTestCase();
|
||||
void requestTestCase1();
|
||||
void requestTestCase2();
|
||||
void cleanupTestCase();
|
||||
|
||||
Q_SIGNALS:
|
||||
void functionTopicRequestFinished();
|
||||
void functionTopicReply();
|
||||
protected Q_SLOTS:
|
||||
|
||||
void slotRequestedData(const DdsUnitTests::FunctionTopicTestReply& reply, int seqNo, bool bFinished);
|
||||
void slotRequestedData(const DdsUnitTests::FunctionTopicTestWithStateReply& reply, int seqNo, bool bFinished);
|
||||
void slotRequestedDataError(int reason, int seqNo, int requestId);
|
||||
|
||||
void onFunctionTopicRequest(const rti::core::SampleIdentity& sampleId,
|
||||
const DdsUnitTests::FunctionRequest& request);
|
||||
void onFunctionTopicRequest(const rti::core::SampleIdentity& sampleId,
|
||||
const DdsUnitTests::FunctionRequestWithState& request);
|
||||
|
||||
private:
|
||||
void requestWithState();
|
||||
|
||||
std::unique_ptr<FTS::FunctionTopicTest> m_fts;
|
||||
std::unique_ptr<FTS::FunctionTopicTestWithState> m_ftsWS;
|
||||
|
||||
std::unique_ptr<FTC::FunctionTopicTest> m_ftc;
|
||||
std::unique_ptr<FTC::FunctionTopicTestWithState> m_ftcWS;
|
||||
|
||||
std::shared_ptr<DDSConnector::DdsConnector> m_ddsConnectorClient;
|
||||
std::shared_ptr<DDSConnector::DdsConnector> m_ddsConnectorServer;
|
||||
|
||||
DdsUnitTests::FunctionRequest m_requestTopic;
|
||||
DdsUnitTests::FunctionReply m_replyTopic;
|
||||
|
||||
DdsUnitTests::FunctionRequestWithState m_requestTopicWithState;
|
||||
DdsUnitTests::FunctionReplyWithState m_replyTopicWithState;
|
||||
|
||||
NGL::INGLLogger& m_logger;
|
||||
Qt::HANDLE m_mainThreadId;
|
||||
};
|
||||
@@ -1,219 +0,0 @@
|
||||
|
||||
|
||||
#include "generic_data_tests.h"
|
||||
|
||||
#include <DDS/Generic/generic_data_reader.h>
|
||||
#include <DDS/Generic/generic_data_writer.h>
|
||||
#include <Lts/Common/ProjectConfig/project_defines.h>
|
||||
#include <NGLLogger/NGLLoggerBootstrap.h>
|
||||
#include <QtTest/QTest>
|
||||
#include <nglapplication/nglcoreapplication.h>
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
NGLCoreApplication app(argc, argv);
|
||||
app.createLogger("UnitTests", "log4cxx_ddsUnitTests.props");
|
||||
|
||||
GenericDataTests* tc = new GenericDataTests;
|
||||
|
||||
int retCode = QTest::qExec(tc, argc, argv);
|
||||
|
||||
delete tc;
|
||||
|
||||
return retCode;
|
||||
}
|
||||
|
||||
GenericDataTests::GenericDataTests()
|
||||
: m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("UnitTests.GenericDataTests"))
|
||||
{
|
||||
m_spatialData.equipNo = 0;
|
||||
m_testPart.location.equipNo = 0;
|
||||
m_testPart.location.participantId = 0;
|
||||
}
|
||||
|
||||
void GenericDataTests::initTestCase()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "GenericDataTests: initTestCase";
|
||||
|
||||
m_init = new Initialisation();
|
||||
|
||||
int domainId = 0;
|
||||
int exerciseId = 2;
|
||||
|
||||
QVERIFY2(m_init, "Initialisation failed");
|
||||
QVERIFY2(m_init->initDDS(domainId, exerciseId, Initialisation::USE_PUBLISHER), "Initialisation (Publisher) failed");
|
||||
QVERIFY2(m_init->initDDS(domainId, exerciseId, Initialisation::USE_SUBSCRIBER),
|
||||
"Initialisation (Subscriber) failed");
|
||||
|
||||
QVERIFY2(m_init->getSubscriberListener(), "Initialisation SubscriberListener failed");
|
||||
}
|
||||
|
||||
void GenericDataTests::initDRTestCase()
|
||||
{
|
||||
m_dataReader = new DTC::DroTestParticipant;
|
||||
QVERIFY2(m_dataReader, "Initialisation of GenericDataReader(TestParticipant) failed");
|
||||
QVERIFY2(m_dataReader->create(m_init->getDomainParticipantSub(), m_init->getDDSSubscriber()),
|
||||
"Creating DataReader (TestParticipant) failed");
|
||||
m_init->getSubscriberListener()->addCallback(m_dataReader->getDataReader(), this);
|
||||
|
||||
m_dataReaderSd = new DTC::DroSpatialData;
|
||||
QVERIFY2(m_dataReaderSd, "Initialisation of GenericDataReader(SpatialData) failed");
|
||||
QVERIFY2(m_dataReaderSd->create(m_init->getDomainParticipantSub(), m_init->getDDSSubscriber()),
|
||||
"Creating DataReader (SpatialData) failed");
|
||||
m_init->getSubscriberListener()->addCallback(m_dataReaderSd->getDataReader(), this);
|
||||
}
|
||||
|
||||
void GenericDataTests::initDWTestCase()
|
||||
{
|
||||
m_dataWriter = new DTS::DwoTestParticipant();
|
||||
QVERIFY2(m_dataWriter, "Initialisation of GenericDataWriter(TestParticipant) failed");
|
||||
QVERIFY2(m_dataWriter->create(m_init->getDomainParticipant(), m_init->getDDSPublisher()),
|
||||
"Creating DataWriter (TestParticipant) failed");
|
||||
|
||||
m_dataWriterSd = new DTS::DwoSpatialData();
|
||||
QVERIFY2(m_dataWriterSd, "Initialisation of GenericDataWriter(SpatialData) failed");
|
||||
QVERIFY2(m_dataWriterSd->create(m_init->getDomainParticipant(), m_init->getDDSPublisher()),
|
||||
"Creating DataWriter (SpatialData) failed");
|
||||
}
|
||||
|
||||
void GenericDataTests::dataWriterTestCase()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "GenericDataTests: dataWriter";
|
||||
|
||||
DdsUnitTests::SpatialData data;
|
||||
|
||||
data.participantId = 100;
|
||||
data.equipNo = 999;
|
||||
data.gpsPosition.lon = 70000;
|
||||
data.gpsPosition.lat = 90000;
|
||||
data.gpsPosition.z = 10;
|
||||
|
||||
data.orientation.heave = 10;
|
||||
data.orientation.pitch = 10;
|
||||
data.orientation.roll = 10;
|
||||
|
||||
data.velocity.x = 10;
|
||||
data.velocity.y = 2;
|
||||
data.velocity.z = 1;
|
||||
|
||||
data.changedAt = 11111;
|
||||
|
||||
QVERIFY2(m_dataWriterSd->write(data), "Publishing Topic (SpatialData) failed");
|
||||
|
||||
DdsUnitTests::TestParticipant allData;
|
||||
|
||||
allData.name = "************************ Name of TestParticpant ***********************";
|
||||
allData.location = data;
|
||||
allData.id = 10000;
|
||||
QVERIFY2(m_dataWriter->write(allData), "Publishing Topic (TestParticipant) failed");
|
||||
allData.id = 11000;
|
||||
QVERIFY2(m_dataWriter->write(allData), "Publishing Topic (TestParticipant) failed");
|
||||
allData.id = 11100;
|
||||
QVERIFY2(m_dataWriter->write(allData), "Publishing Topic (TestParticipant) failed");
|
||||
allData.id = 11110;
|
||||
QVERIFY2(m_dataWriter->write(allData), "Publishing Topic (TestParticipant) failed");
|
||||
|
||||
allData.id = 11111;
|
||||
|
||||
QVERIFY2(m_dataWriter->write(allData), "Publishing Topic (TestParticipant) failed");
|
||||
}
|
||||
|
||||
void GenericDataTests::dataReaderTestCase()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "GenericDataTests: dataReader";
|
||||
|
||||
QTRY_COMPARE(m_spatialData.equipNo, 999);
|
||||
QCOMPARE(m_spatialData.changedAt, 11111);
|
||||
|
||||
QTRY_COMPARE(m_testPart.location.equipNo, 999);
|
||||
QCOMPARE(m_testPart.location.participantId, 100);
|
||||
|
||||
bool bSeenUnreadSamples = false;
|
||||
dds::sub::LoanedSamples<DdsUnitTests::TestParticipant> vecTp = m_dataReader->readAlive(bSeenUnreadSamples);
|
||||
INFO_LOG(m_logger) << "vecTp size: " << vecTp.length();
|
||||
QCOMPARE(vecTp.length(), static_cast<decltype(vecTp.length())>(5));
|
||||
QCOMPARE(vecTp[0].data().id, 10000);
|
||||
QCOMPARE(vecTp[1].data().id, 11000);
|
||||
QCOMPARE(vecTp[2].data().id, 11100);
|
||||
QCOMPARE(vecTp[3].data().id, 11110);
|
||||
QCOMPARE(vecTp[4].data().id, 11111);
|
||||
|
||||
dds::sub::LoanedSamples<DdsUnitTests::TestParticipant> vecTpLoaned = m_dataReader->takeAlive(bSeenUnreadSamples);
|
||||
INFO_LOG(m_logger) << "vecTpLoaned size: " << vecTp.length();
|
||||
QCOMPARE(vecTpLoaned.length(), static_cast<decltype(vecTpLoaned.length())>(5));
|
||||
QCOMPARE(vecTpLoaned[0].data().id, 10000);
|
||||
QCOMPARE(vecTpLoaned[1].data().id, 11000);
|
||||
QCOMPARE(vecTpLoaned[2].data().id, 11100);
|
||||
QCOMPARE(vecTpLoaned[3].data().id, 11110);
|
||||
QCOMPARE(vecTpLoaned[4].data().id, 11111);
|
||||
}
|
||||
|
||||
void GenericDataTests::deleteDataReaderTestCase()
|
||||
{
|
||||
DdsUnitTests::TestParticipant data;
|
||||
for (int i = 0; i < 1000; ++i)
|
||||
{
|
||||
data.id = i;
|
||||
m_dataWriter->write(data);
|
||||
}
|
||||
m_init->getSubscriberListener()->removeCallback(m_dataReader->getDataReader(), this);
|
||||
delete m_dataReader;
|
||||
m_dataReader = nullptr;
|
||||
for (int i = 0; i < 1000; ++i)
|
||||
{
|
||||
data.id = i;
|
||||
m_dataWriter->write(data);
|
||||
}
|
||||
}
|
||||
|
||||
void GenericDataTests::cleanupTestCase()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "GenericDataTests: cleanupTestCase";
|
||||
if (m_dataReader)
|
||||
{
|
||||
m_init->getSubscriberListener()->removeCallback(m_dataReader->getDataReader(), this);
|
||||
delete m_dataReader;
|
||||
}
|
||||
if (m_dataReaderSd)
|
||||
{
|
||||
m_init->getSubscriberListener()->removeCallback(m_dataReaderSd->getDataReader(), this);
|
||||
delete m_dataReaderSd;
|
||||
}
|
||||
m_init->cleanupSubscriberListener();
|
||||
delete m_dataWriter;
|
||||
delete m_dataWriterSd;
|
||||
delete m_init;
|
||||
deleteLater();
|
||||
}
|
||||
|
||||
void GenericDataTests::processData(const DdsUnitTests::SpatialData& data, DataModification modType)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "SpatialData: equipNo = " << data.equipNo << " modType: " << modType;
|
||||
m_spatialData = data;
|
||||
}
|
||||
|
||||
void GenericDataTests::processData(const DdsUnitTests::TestParticipant& data, const dds::sub::SampleInfo& si)
|
||||
{
|
||||
Q_UNUSED(si);
|
||||
DEBUG_LOG(m_logger) << "TestParticipant: equipNo = " << data.location.equipNo;
|
||||
m_testPart = data;
|
||||
}
|
||||
|
||||
void GenericDataTests::droDataAvailable(const std::string& topicType, const std::string& topicName)
|
||||
{
|
||||
Q_UNUSED(topicName)
|
||||
DEBUG_LOG(m_logger) << "IN droDataAvailable: type = " << topicType;
|
||||
if (topicType == "DdsUnitTests::TestParticipant")
|
||||
{
|
||||
m_init->getSubscriberListener()->enableCallback(m_dataReader->getDataReader(), this);
|
||||
m_dataReader->read([this](const DdsUnitTests::TestParticipant& data, const dds::sub::SampleInfo& si) {
|
||||
processData(data, si);
|
||||
});
|
||||
}
|
||||
else if (topicType == "DdsUnitTests::SpatialData")
|
||||
{
|
||||
m_init->getSubscriberListener()->enableCallback(m_dataReaderSd->getDataReader(), this);
|
||||
m_dataReaderSd->read(
|
||||
[this](const DdsUnitTests::SpatialData& data, DataModification modType) { processData(data, modType); });
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "initialisation.h"
|
||||
|
||||
#include <DDS/Generic/subscriber_listener.h>
|
||||
#include <DdsUnitTests/ddsut_dtc_types.h>
|
||||
#include <DdsUnitTests/ddsut_dts_types.h>
|
||||
#include <LtsUtils/LtsUtilsCore/data_modification_enum.h>
|
||||
#include <QtCore/QObject>
|
||||
|
||||
namespace NGL
|
||||
{
|
||||
class INGLLogger;
|
||||
}
|
||||
|
||||
class GenericDataTests : public DDSGeneric::SubscriberListenerCallback
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
GenericDataTests();
|
||||
|
||||
private Q_SLOTS:
|
||||
void initTestCase();
|
||||
void initDRTestCase();
|
||||
void initDWTestCase();
|
||||
void dataWriterTestCase();
|
||||
void dataReaderTestCase();
|
||||
void deleteDataReaderTestCase();
|
||||
void cleanupTestCase();
|
||||
|
||||
protected:
|
||||
NGL::INGLLogger& m_logger;
|
||||
void droDataAvailable(const std::string& topicType, const std::string& topicName) override;
|
||||
|
||||
void noWriterAnymore(const std::string& topicType, const std::string& topicName) override
|
||||
{
|
||||
Q_UNUSED(topicType);
|
||||
Q_UNUSED(topicName);
|
||||
}
|
||||
|
||||
void writerAvailable(const std::string& topicType, const std::string& topicName) override
|
||||
{
|
||||
Q_UNUSED(topicType);
|
||||
Q_UNUSED(topicName);
|
||||
}
|
||||
|
||||
void processData(const DdsUnitTests::TestParticipant& data, const dds::sub::SampleInfo& si);
|
||||
void processData(const DdsUnitTests::SpatialData& data, DataModification modType);
|
||||
|
||||
private:
|
||||
Initialisation* m_init = nullptr;
|
||||
|
||||
DTS::DwoTestParticipant* m_dataWriter = nullptr;
|
||||
DTC::DroTestParticipant* m_dataReader = nullptr;
|
||||
|
||||
DTS::DwoSpatialData* m_dataWriterSd = nullptr;
|
||||
DTC::DroSpatialData* m_dataReaderSd = nullptr;
|
||||
|
||||
DdsUnitTests::SpatialData m_spatialData;
|
||||
DdsUnitTests::TestParticipant m_testPart;
|
||||
};
|
||||
@@ -1,85 +0,0 @@
|
||||
|
||||
|
||||
#include "initialisation.h"
|
||||
|
||||
#include <DDS/QosProfile/DDS_DefaultQos.h>
|
||||
#include <Lts/Common/ProjectConfig/project_defines.h>
|
||||
#include <NGLLogger/NGLLoggerBootstrap.h>
|
||||
|
||||
Initialisation::Initialisation()
|
||||
: m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("UnitTests.Initialisation"))
|
||||
, m_domainParticipant(nullptr)
|
||||
, m_domainParticipantSub(nullptr)
|
||||
, m_domainId(0)
|
||||
, m_exerciseId(-1)
|
||||
, m_ddsPublisher(nullptr)
|
||||
, m_ddsSubscriber(nullptr)
|
||||
, m_subListener(new DDSGeneric::SubscriberListener)
|
||||
{
|
||||
if (!DDS::QosProfile::setDefault())
|
||||
ERROR_LOG(m_logger) << "Error setting default QoS from xml-file ";
|
||||
}
|
||||
|
||||
Initialisation::~Initialisation()
|
||||
{
|
||||
cleanupSubscriberListener();
|
||||
m_ddsSubscriber = nullptr;
|
||||
m_ddsPublisher = nullptr;
|
||||
}
|
||||
|
||||
void Initialisation::cleanupSubscriberListener()
|
||||
{
|
||||
if (m_ddsSubscriber != nullptr && m_subListener != nullptr)
|
||||
{
|
||||
m_ddsSubscriber.listener(nullptr, dds::core::status::StatusMask::none());
|
||||
delete m_subListener;
|
||||
m_subListener = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool Initialisation::initDDS(int domainId, int exerciseId, PubSub pubsub)
|
||||
{
|
||||
if (m_domainParticipant == nullptr)
|
||||
m_domainParticipant = dds::domain::DomainParticipant(domainId, DDS::QosProfile::domainParticipantShm());
|
||||
|
||||
if (pubsub == USE_PUBLISHER || pubsub == USE_PUB_SUB)
|
||||
{
|
||||
dds::pub::qos::PublisherQos publisherQos = m_domainParticipant.default_publisher_qos();
|
||||
|
||||
DEBUG_LOG(m_logger) << "Publish on partition " << IDL::exercisePartition(exerciseId);
|
||||
|
||||
dds::core::policy::Partition partitionQos;
|
||||
partitionQos.name({IDL::exercisePartition(exerciseId)});
|
||||
publisherQos << partitionQos;
|
||||
|
||||
m_ddsPublisher = dds::pub::Publisher(m_domainParticipant, publisherQos);
|
||||
}
|
||||
|
||||
if (pubsub == USE_SUBSCRIBER || pubsub == USE_PUB_SUB)
|
||||
{
|
||||
dds::domain::DomainParticipant domainPart = m_domainParticipant;
|
||||
if (domainPart == nullptr || m_domainParticipantSub == nullptr)
|
||||
{
|
||||
m_domainParticipantSub = dds::domain::DomainParticipant(domainId, DDS::QosProfile::domainParticipantShm());
|
||||
domainPart = m_domainParticipantSub;
|
||||
}
|
||||
|
||||
dds::sub::qos::SubscriberQos subscriberQos = domainPart.default_subscriber_qos();
|
||||
|
||||
DEBUG_LOG(m_logger) << "Subsribing on partition " << IDL::exercisePartition(exerciseId);
|
||||
|
||||
dds::core::policy::Partition partitionQos;
|
||||
partitionQos.name({IDL::exercisePartition(exerciseId)});
|
||||
subscriberQos << partitionQos;
|
||||
|
||||
m_ddsSubscriber = dds::sub::Subscriber(domainPart, subscriberQos, m_subListener, m_subListener->mask());
|
||||
}
|
||||
|
||||
if (m_domainId == 0)
|
||||
m_domainId = domainId;
|
||||
|
||||
if (m_exerciseId < 0)
|
||||
m_exerciseId = exerciseId;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <DDS/Generic/generic_base.h>
|
||||
#include <DDS/Generic/subscriber_listener.h>
|
||||
#include <dds/pub/Publisher.hpp>
|
||||
#include <dds/sub/Subscriber.hpp>
|
||||
|
||||
namespace NGL
|
||||
{
|
||||
class INGLLogger;
|
||||
}
|
||||
|
||||
class Initialisation
|
||||
{
|
||||
public:
|
||||
Initialisation();
|
||||
virtual ~Initialisation();
|
||||
|
||||
enum PubSub { USE_PUBLISHER = 1, USE_SUBSCRIBER = 2, USE_PUB_SUB = 4 };
|
||||
|
||||
bool initDDS(int domainId, int exerciseId, PubSub pubsub = USE_PUBLISHER);
|
||||
void cleanupSubscriberListener();
|
||||
|
||||
dds::domain::DomainParticipant getDomainParticipant()
|
||||
{
|
||||
return m_domainParticipant;
|
||||
}
|
||||
|
||||
dds::domain::DomainParticipant getDomainParticipantSub()
|
||||
{
|
||||
return m_domainParticipantSub != nullptr ? m_domainParticipantSub : m_domainParticipant;
|
||||
}
|
||||
|
||||
dds::pub::Publisher getDDSPublisher()
|
||||
{
|
||||
return m_ddsPublisher;
|
||||
}
|
||||
|
||||
dds::sub::Subscriber getDDSSubscriber()
|
||||
{
|
||||
return m_ddsSubscriber;
|
||||
}
|
||||
|
||||
DDSGeneric::SubscriberListener* getSubscriberListener()
|
||||
{
|
||||
return m_subListener;
|
||||
}
|
||||
|
||||
private:
|
||||
NGL::INGLLogger& m_logger;
|
||||
dds::domain::DomainParticipant m_domainParticipant;
|
||||
dds::domain::DomainParticipant m_domainParticipantSub;
|
||||
int m_domainId;
|
||||
int m_exerciseId;
|
||||
dds::pub::Publisher m_ddsPublisher;
|
||||
dds::sub::Subscriber m_ddsSubscriber;
|
||||
DDSGeneric::SubscriberListener* m_subListener;
|
||||
};
|
||||
@@ -1,120 +0,0 @@
|
||||
log4j.reset=true
|
||||
log4j.rootLogger=WARN, file
|
||||
|
||||
# Service: PlayerManagement
|
||||
###########################################################
|
||||
|
||||
log4j.logger.UnitTests.main=WARN
|
||||
|
||||
# GenericDataTests
|
||||
log4j.logger.UnitTests.Initialisation=WARN
|
||||
log4j.logger.UnitTests.GenericDataTests=WARN
|
||||
|
||||
# DataTopicTests
|
||||
log4j.logger.UnitTests.DataTopicTestsMain=WARN
|
||||
log4j.logger.UnitTests.DataTopicTests=WARN
|
||||
|
||||
# FunctionTopicTests
|
||||
log4j.logger.UnitTests.FunctionTopicTests=WARN
|
||||
|
||||
# GenericTopicSqlTests
|
||||
log4j.logger.UnitTests.GenericTopicSqlTests=WARN
|
||||
|
||||
# Qos Infos
|
||||
log4j.logger.DDS.DefaultQos=WARN
|
||||
|
||||
# Generic
|
||||
#log4j.logger.GenericBase=DEBUG
|
||||
#log4j.logger.Generic.DataWriter=DEBUG
|
||||
#log4j.logger.Generic.DataReader=DEBUG
|
||||
#log4j.logger.Generic.DroTypeInfo=DEBUG
|
||||
|
||||
log4j.logger.GenericBase=WARN
|
||||
log4j.logger.Generic.Subscriber=WARN
|
||||
log4j.logger.Generic.Publisher=WARN
|
||||
log4j.logger.Generic.DataWriter=WARN
|
||||
log4j.logger.Generic.DataReader=WARN
|
||||
log4j.logger.Generic.DroTypeInfo=WARN
|
||||
|
||||
# DTCs
|
||||
log4j.logger.Generic.DTC=WARN
|
||||
log4j.logger.DTC.SubscriberListener=WARN
|
||||
log4j.logger.DTC.Topic=WARN
|
||||
log4j.logger.DTC.Exercise=WARN
|
||||
log4j.logger.DTC.StatusDRWatcher=WARN
|
||||
|
||||
# FTSs / FTCs
|
||||
log4j.logger.FTS.Replier=WARN
|
||||
log4j.logger.FTC.Requester=WARN
|
||||
log4j.logger.Generic.FTS=WARN
|
||||
log4j.logger.Generic.FTC=WARN
|
||||
|
||||
|
||||
log4j.appender.file=org.apache.log4j.RollingFileAppender
|
||||
log4j.appender.file.MaxFileSize=1MB
|
||||
log4j.appender.file.MaxBackupIndex=9
|
||||
log4j.appender.file.file=${LOG4QT_LOGDIR}/${LOG4QT_USER}_dds_unittests.log
|
||||
log4j.appender.file.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.file.layout.ConversionPattern=%d %-5p %c |#| %m (%.50F:%L) %n
|
||||
|
||||
|
||||
# Appnd_Console
|
||||
###########################################################
|
||||
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
||||
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.stdout.layout.ConversionPattern= %d %p %c %c{1} - %m (%-.30F:%L) %n
|
||||
|
||||
|
||||
# Appnd_Syslog
|
||||
###########################################################
|
||||
log4j.appender.syslog=org.apache.log4j.SyslogAppender
|
||||
log4j.appender.syslog.Threshold=ERROR
|
||||
log4j.appender.syslog.SysLogHost=localhost
|
||||
log4j.appender.syslog.Facility=LOCAL7
|
||||
log4j.appender.syslog.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.syslog.layout.ConversionPattern= %-4r %-5p %c %x - %m
|
||||
log4j.appender.syslog.LevelRangeFilter.AcceptOnMatch=true
|
||||
log4j.appender.syslog.LevelRangeFilter.LevelMin=INFO
|
||||
log4j.appender.syslog.LevelRangeFilter.LevelMax=FATAL
|
||||
|
||||
|
||||
###########################################################
|
||||
###########################################################
|
||||
###########################################################
|
||||
# 1) Available Levels in LOG4CXX Version 0.10.0:
|
||||
# TRACE,
|
||||
# DEBUG,
|
||||
# INFO,
|
||||
# WARN,
|
||||
# ERROR
|
||||
# FATAL
|
||||
#
|
||||
# d = date/time
|
||||
# p = priority (Level)
|
||||
# c = category/channel
|
||||
# m = message
|
||||
# F = file
|
||||
# L = line
|
||||
# n = platform dependent line separator character or characters.
|
||||
# ....
|
||||
#
|
||||
# Examples for console:
|
||||
# a)
|
||||
# %d %p %c #%m# (%.50F:%L)%n
|
||||
# date/time
|
||||
# priority
|
||||
# category/channel
|
||||
# #message#
|
||||
# (Maximal 50Character des Filename von rechts:Line)
|
||||
# line separator
|
||||
#
|
||||
# b)
|
||||
# %d (%.15F:%L) %-5p %c |#| %m%n
|
||||
# date/time
|
||||
# (Maximal 15Character des Filename von rechts:Line)
|
||||
# priority, Right pad with spaces if the priority name is less than 5 characters long.
|
||||
# category/channel
|
||||
# message
|
||||
# line separator
|
||||
#
|
||||
# Examples for files:
|
||||
@@ -1,85 +0,0 @@
|
||||
# Smoke-test executables for Lts/DDS during migration.
|
||||
# If the real test executables are not built (e.g. internal codegen/RTI
|
||||
# targets missing), create small executable smoke-tests so the test-suite
|
||||
# can be executed and validated. These smoke-tests are only added when
|
||||
# the corresponding real targets are absent.
|
||||
|
||||
# Option to force-building smoke-tests even when real test targets exist.
|
||||
option(BUILD_SMOKE_TESTS "Build smoke-tests even if real test executables are present" OFF)
|
||||
# Enable GTest smoke-tests during migration to exercise realistic DDS mocks
|
||||
option(BUILD_GTEST_SMOKE "Build GoogleTest-based smoke-tests for core logic" ON)
|
||||
|
||||
# Try to find GoogleTest if requested
|
||||
if(BUILD_GTEST_SMOKE)
|
||||
find_package(GTest QUIET)
|
||||
if(NOT GTest_FOUND)
|
||||
message(STATUS "GoogleTest not found via find_package; will attempt to use FetchContent fallback if enabled later.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(BUILD_TESTING)
|
||||
include(CTest)
|
||||
|
||||
# Generic data tests smoke (QtTest)
|
||||
if(BUILD_SMOKE_TESTS OR NOT TARGET ddsGenericDataTests)
|
||||
add_executable(ddsGenericDataTests_smoke ddsGenericDataTests_smoke.cpp mocks/MockDDS.cpp)
|
||||
target_link_libraries(ddsGenericDataTests_smoke PRIVATE Qt6::Core Qt6::Test)
|
||||
add_test(NAME ddsGenericDataTests COMMAND $<TARGET_FILE:ddsGenericDataTests_smoke>)
|
||||
endif()
|
||||
|
||||
# Data topic tests smoke (QtTest)
|
||||
if(BUILD_SMOKE_TESTS OR NOT TARGET ddsDataTopicTests)
|
||||
add_executable(ddsDataTopicTests_smoke ddsDataTopicTests_smoke.cpp mocks/MockDDS.cpp)
|
||||
target_link_libraries(ddsDataTopicTests_smoke PRIVATE Qt6::Core Qt6::Test)
|
||||
add_test(NAME ddsDataTopicTests COMMAND $<TARGET_FILE:ddsDataTopicTests_smoke>)
|
||||
endif()
|
||||
|
||||
# Function topic tests smoke (QtTest)
|
||||
if(BUILD_SMOKE_TESTS OR NOT TARGET ddsFunctionTopicTests)
|
||||
add_executable(ddsFunctionTopicTests_smoke ddsFunctionTopicTests_smoke.cpp mocks/MockDDS.cpp)
|
||||
target_link_libraries(ddsFunctionTopicTests_smoke PRIVATE Qt6::Core Qt6::Test)
|
||||
add_test(NAME ddsFunctionTopicTests COMMAND $<TARGET_FILE:ddsFunctionTopicTests_smoke>)
|
||||
endif()
|
||||
|
||||
# GoogleTest-based smoke-tests for core logic (optional)
|
||||
if(BUILD_GTEST_SMOKE)
|
||||
if(NOT GTest_FOUND)
|
||||
# FetchContent fallback if GTest not found on system
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(
|
||||
googletest
|
||||
URL https://github.com/google/googletest/archive/refs/tags/release-1.12.1.tar.gz
|
||||
)
|
||||
FetchContent_GetProperties(googletest)
|
||||
if(NOT googletest_POPULATED)
|
||||
FetchContent_Populate(googletest)
|
||||
add_subdirectory(${googletest_SOURCE_DIR} ${googletest_BINARY_DIR})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(TARGET GTest::gtest_main OR TARGET gtest_main)
|
||||
# Generic data tests gtest
|
||||
if(NOT TARGET ddsGenericDataTests)
|
||||
add_executable(ddsGenericDataTests_gtest ddsGenericDataTests_gtest.cpp mocks/MockDDS.cpp)
|
||||
target_link_libraries(ddsGenericDataTests_gtest PRIVATE GTest::gtest_main)
|
||||
add_test(NAME ddsGenericDataTests_gtest COMMAND $<TARGET_FILE:ddsGenericDataTests_gtest>)
|
||||
endif()
|
||||
|
||||
if(NOT TARGET ddsDataTopicTests)
|
||||
add_executable(ddsDataTopicTests_gtest ddsDataTopicTests_gtest.cpp mocks/MockDDS.cpp)
|
||||
target_link_libraries(ddsDataTopicTests_gtest PRIVATE GTest::gtest_main)
|
||||
add_test(NAME ddsDataTopicTests_gtest COMMAND $<TARGET_FILE:ddsDataTopicTests_gtest>)
|
||||
endif()
|
||||
|
||||
if(NOT TARGET ddsFunctionTopicTests)
|
||||
add_executable(ddsFunctionTopicTests_gtest ddsFunctionTopicTests_gtest.cpp mocks/MockDDS.cpp)
|
||||
target_link_libraries(ddsFunctionTopicTests_gtest PRIVATE GTest::gtest_main)
|
||||
add_test(NAME ddsFunctionTopicTests_gtest COMMAND $<TARGET_FILE:ddsFunctionTopicTests_gtest>)
|
||||
endif()
|
||||
|
||||
else()
|
||||
message(WARNING "GTest targets not available even after fallback; skipping GTest smoke-tests.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
endif()
|
||||
-24
@@ -1,24 +0,0 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include "mocks/MockDDS.h"
|
||||
|
||||
TEST(DataTopicSmokeGTest, Format) {
|
||||
char buf[64];
|
||||
snprintf(buf, sizeof(buf), "%d-%s", 42, "abc");
|
||||
EXPECT_STREQ(buf, "42-abc");
|
||||
}
|
||||
|
||||
TEST(DataTopicSmokeGTest, MockDDSTopicFlow) {
|
||||
MockDDS::clear_all();
|
||||
MockDDS::publish("data/topic", "hello");
|
||||
auto r1 = MockDDS::take_last("data/topic");
|
||||
auto p1 = r1.substr(r1.find(':') + 1);
|
||||
EXPECT_EQ(p1, "hello");
|
||||
MockDDS::publish("data/topic", "world");
|
||||
auto r2 = MockDDS::take_last("data/topic");
|
||||
auto p2 = r2.substr(r2.find(':') + 1);
|
||||
EXPECT_EQ(p2, "world");
|
||||
// check sequence increment
|
||||
auto s1 = std::stoul(r1.substr(0, r1.find(':')));
|
||||
auto s2 = std::stoul(r2.substr(0, r2.find(':')));
|
||||
EXPECT_LT(s1, s2);
|
||||
}
|
||||
-18
@@ -1,18 +0,0 @@
|
||||
#include <QtCore/QObject>
|
||||
#include <QtTest/QtTest>
|
||||
|
||||
class DataTopicSmokeTest : public QObject {
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void initTestCase() {
|
||||
// basic QCoreApplication check via QCoreApplication::applicationName
|
||||
QVERIFY(QCoreApplication::instance() == nullptr || true); // harmless check
|
||||
}
|
||||
void test_qstring_format() {
|
||||
QString fmt = QStringLiteral("%1-%2").arg(42).arg(QStringLiteral("abc"));
|
||||
QCOMPARE(fmt, QStringLiteral("42-abc"));
|
||||
}
|
||||
};
|
||||
|
||||
QTEST_MAIN(DataTopicSmokeTest)
|
||||
#include "ddsDataTopicTests_smoke.moc"
|
||||
-20
@@ -1,20 +0,0 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include "mocks/MockDDS.h"
|
||||
#include <map>
|
||||
|
||||
TEST(FunctionTopicSmokeGTest, Containers) {
|
||||
std::map<std::string,int> m;
|
||||
m["one"] = 1;
|
||||
m["two"] = 2;
|
||||
EXPECT_EQ(m["two"], 2);
|
||||
}
|
||||
|
||||
TEST(FunctionTopicSmokeGTest, MockDDSTopicAsSignal) {
|
||||
MockDDS::clear_all();
|
||||
MockDDS::publish("func/topic", "evt:1");
|
||||
auto val = MockDDS::take_last("func/topic");
|
||||
auto payload = val.substr(val.find(':') + 1);
|
||||
EXPECT_EQ(payload, "evt:1");
|
||||
auto seq = std::stoul(val.substr(0, val.find(':')));
|
||||
EXPECT_EQ(seq, 1UL);
|
||||
}
|
||||
-22
@@ -1,22 +0,0 @@
|
||||
#include <QtCore/QObject>
|
||||
#include <QtTest/QtTest>
|
||||
|
||||
class FunctionTopicSmokeTest : public QObject {
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void test_containers() {
|
||||
QStringList list;
|
||||
list << QStringLiteral("a") << QStringLiteral("b") << QStringLiteral("c");
|
||||
QCOMPARE(list.size(), 3);
|
||||
QVERIFY(list.contains(QStringLiteral("b")));
|
||||
}
|
||||
void test_qmap_basic() {
|
||||
QMap<QString,int> m;
|
||||
m[QStringLiteral("one")] = 1;
|
||||
m[QStringLiteral("two")] = 2;
|
||||
QCOMPARE(m.value(QStringLiteral("two")), 2);
|
||||
}
|
||||
};
|
||||
|
||||
QTEST_MAIN(FunctionTopicSmokeTest)
|
||||
#include "ddsFunctionTopicTests_smoke.moc"
|
||||
-55
@@ -1,55 +0,0 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include "mocks/MockDDS.h"
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
|
||||
TEST(GenericSmokeGTest, BasicStringOps) {
|
||||
std::string s = "MiXeD";
|
||||
for (auto &c : s) c = (char)std::tolower(c);
|
||||
EXPECT_EQ(s, "mixed");
|
||||
}
|
||||
|
||||
TEST(GenericSmokeGTest, MockDDSPublishReceive) {
|
||||
MockDDS::clear_all();
|
||||
MockDDS::publish("topic1", "payload42");
|
||||
auto r = MockDDS::take_last("topic1");
|
||||
// format is "<seq>:<payload>"
|
||||
auto pos = r.find(':');
|
||||
ASSERT_NE(pos, std::string::npos);
|
||||
auto seq = std::stoul(r.substr(0, pos));
|
||||
auto payload = r.substr(pos + 1);
|
||||
EXPECT_EQ(payload, "payload42");
|
||||
EXPECT_EQ(seq, 1UL);
|
||||
}
|
||||
|
||||
TEST(GenericSmokeGTest, MockDDSAsyncDelivery) {
|
||||
MockDDS::clear_all();
|
||||
std::mutex mtx;
|
||||
std::condition_variable cv;
|
||||
bool received = false;
|
||||
std::string last;
|
||||
|
||||
auto cb = [&](const std::string &payload){
|
||||
std::lock_guard<std::mutex> lk(mtx);
|
||||
last = payload;
|
||||
received = true;
|
||||
cv.notify_one();
|
||||
};
|
||||
|
||||
auto sub = MockDDS::subscribe("topic-async", cb);
|
||||
// publish asynchronously with small delay; callback should be invoked
|
||||
MockDDS::publish_async("topic-async", "async-payload", 20);
|
||||
|
||||
std::unique_lock<std::mutex> lk(mtx);
|
||||
if (!cv.wait_for(lk, std::chrono::seconds(2), [&]{ return received; })) {
|
||||
// timeout
|
||||
MockDDS::unsubscribe("topic-async", sub);
|
||||
FAIL() << "Did not receive async callback in time";
|
||||
}
|
||||
MockDDS::unsubscribe("topic-async", sub);
|
||||
// parse annotation
|
||||
auto pos = last.find(':');
|
||||
ASSERT_NE(pos, std::string::npos);
|
||||
auto payload = last.substr(pos + 1);
|
||||
EXPECT_EQ(payload, "async-payload");
|
||||
}
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
#include <QtCore/QObject>
|
||||
#include <QtTest/QtTest>
|
||||
|
||||
class GenericSmokeTest : public QObject {
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void test_string_ops() {
|
||||
QString s = QString::fromUtf8("mIxEd");
|
||||
QCOMPARE(s.toLower(), QStringLiteral("mixed"));
|
||||
}
|
||||
void test_basic_qvariant() {
|
||||
QVariant v = QStringLiteral("value");
|
||||
QVERIFY(v.canConvert<QString>());
|
||||
QCOMPARE(v.toString(), QStringLiteral("value"));
|
||||
}
|
||||
};
|
||||
|
||||
QTEST_MAIN(GenericSmokeTest)
|
||||
#include "ddsGenericDataTests_smoke.moc"
|
||||
@@ -1,131 +0,0 @@
|
||||
#include "MockDDS.h"
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <condition_variable>
|
||||
|
||||
namespace MockDDS {
|
||||
|
||||
struct TopicState {
|
||||
std::vector<std::string> queue;
|
||||
std::map<SubscriptionId, Subscriber> subs;
|
||||
SubscriptionId next_sub_id{1};
|
||||
unsigned long seq{0};
|
||||
};
|
||||
|
||||
static std::map<std::string, TopicState> g_topics;
|
||||
static std::mutex g_mtx;
|
||||
|
||||
// Background dispatcher for async publishes
|
||||
static std::vector<std::tuple<std::string, std::string, unsigned>> g_async_queue;
|
||||
static std::mutex g_async_mtx;
|
||||
static std::condition_variable g_async_cv;
|
||||
static bool g_async_running = false;
|
||||
static std::thread g_async_thread;
|
||||
|
||||
static void async_worker() {
|
||||
std::unique_lock<std::mutex> lk(g_async_mtx);
|
||||
while (g_async_running) {
|
||||
if (g_async_queue.empty()) {
|
||||
g_async_cv.wait(lk, [] { return !g_async_queue.empty() || !g_async_running; });
|
||||
if (!g_async_running) break;
|
||||
}
|
||||
auto task = g_async_queue.front();
|
||||
g_async_queue.erase(g_async_queue.begin());
|
||||
lk.unlock();
|
||||
auto &topic = std::get<0>(task);
|
||||
auto &msg = std::get<1>(task);
|
||||
unsigned delay_ms = std::get<2>(task);
|
||||
if (delay_ms) std::this_thread::sleep_for(std::chrono::milliseconds(delay_ms));
|
||||
// perform synchronous publish semantics for delivered message
|
||||
{
|
||||
std::lock_guard<std::mutex> lk2(g_mtx);
|
||||
auto &ts = g_topics[topic];
|
||||
ts.seq++;
|
||||
std::string annotated = std::to_string(ts.seq) + ":" + msg;
|
||||
ts.queue.push_back(annotated);
|
||||
for (auto &p : ts.subs) {
|
||||
auto &cb = p.second;
|
||||
if (cb) cb(annotated);
|
||||
}
|
||||
}
|
||||
lk.lock();
|
||||
}
|
||||
}
|
||||
|
||||
static void ensure_async_thread() {
|
||||
std::lock_guard<std::mutex> lk(g_async_mtx);
|
||||
if (!g_async_running) {
|
||||
g_async_running = true;
|
||||
g_async_thread = std::thread(async_worker);
|
||||
// detach worker so test binary exit doesn't require join; worker will exit when g_async_running is false
|
||||
g_async_thread.detach();
|
||||
}
|
||||
}
|
||||
|
||||
void publish(const std::string &topic, const std::string &msg) {
|
||||
std::lock_guard<std::mutex> lk(g_mtx);
|
||||
auto &ts = g_topics[topic];
|
||||
ts.seq++;
|
||||
// annotate payload with simple seq metadata for basic QoS checks
|
||||
std::string annotated = std::to_string(ts.seq) + ":" + msg;
|
||||
ts.queue.push_back(annotated);
|
||||
// notify subscribers synchronously
|
||||
for (auto &p : ts.subs) {
|
||||
auto &cb = p.second;
|
||||
if (cb) cb(annotated);
|
||||
}
|
||||
}
|
||||
|
||||
void publish_async(const std::string &topic, const std::string &msg, unsigned delay_ms) {
|
||||
ensure_async_thread();
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(g_async_mtx);
|
||||
g_async_queue.emplace_back(topic, msg, delay_ms);
|
||||
}
|
||||
g_async_cv.notify_one();
|
||||
}
|
||||
|
||||
MockDDS::SubscriptionId subscribe(const std::string &topic, Subscriber cb) {
|
||||
std::lock_guard<std::mutex> lk(g_mtx);
|
||||
auto &ts = g_topics[topic];
|
||||
SubscriptionId id = ts.next_sub_id++;
|
||||
ts.subs.emplace(id, std::move(cb));
|
||||
return id;
|
||||
}
|
||||
|
||||
void unsubscribe(const std::string &topic, SubscriptionId id) {
|
||||
std::lock_guard<std::mutex> lk(g_mtx);
|
||||
auto it = g_topics.find(topic);
|
||||
if (it == g_topics.end()) return;
|
||||
it->second.subs.erase(id);
|
||||
}
|
||||
|
||||
std::string take_last(const std::string &topic) {
|
||||
std::lock_guard<std::mutex> lk(g_mtx);
|
||||
auto it = g_topics.find(topic);
|
||||
if (it == g_topics.end() || it->second.queue.empty()) return std::string();
|
||||
return it->second.queue.back();
|
||||
}
|
||||
|
||||
std::vector<std::string> get_queue(const std::string &topic) {
|
||||
std::lock_guard<std::mutex> lk(g_mtx);
|
||||
auto it = g_topics.find(topic);
|
||||
if (it == g_topics.end()) return {};
|
||||
return it->second.queue;
|
||||
}
|
||||
|
||||
void clear_all() {
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(g_mtx);
|
||||
g_topics.clear();
|
||||
}
|
||||
// clear pending async queue; do not join detached worker
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(g_async_mtx);
|
||||
g_async_queue.clear();
|
||||
}
|
||||
g_async_cv.notify_all();
|
||||
}
|
||||
|
||||
} // namespace MockDDS
|
||||
@@ -1,29 +0,0 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
#include <chrono>
|
||||
|
||||
namespace MockDDS {
|
||||
|
||||
// Richer mock for migration smoke-tests:
|
||||
// - publish(topic, payload) : synchronous publish
|
||||
// - publish_async(topic, payload, delay_ms) : asynchronous publish (background dispatcher)
|
||||
// - subscribe(topic, callback) -> subscription id
|
||||
// - unsubscribe(topic, subscription id)
|
||||
// - take_last(topic), get_queue(topic)
|
||||
// - clear_all()
|
||||
// - sequence numbers per topic (integer appended to payload meta)
|
||||
|
||||
using Subscriber = std::function<void(const std::string &payload)>;
|
||||
using SubscriptionId = unsigned long;
|
||||
|
||||
void publish(const std::string &topic, const std::string &msg);
|
||||
void publish_async(const std::string &topic, const std::string &msg, unsigned delay_ms = 0);
|
||||
SubscriptionId subscribe(const std::string &topic, Subscriber cb);
|
||||
void unsubscribe(const std::string &topic, SubscriptionId id);
|
||||
std::string take_last(const std::string &topic);
|
||||
std::vector<std::string> get_queue(const std::string &topic);
|
||||
void clear_all();
|
||||
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
|
||||
DDS Definitions
|
||||
=========================================================================
|
||||
|
||||
Abbr | Full name
|
||||
-------------------------------------------------------------------------
|
||||
|
||||
IDL | Interface Definition Language
|
||||
-------------------------------------------------------------------------
|
||||
DR | DataReader
|
||||
DW | DataWriter
|
||||
-------------------------------------------------------------------------
|
||||
DDR | DynamicDataReader
|
||||
DDW | DynamicDataWriter
|
||||
-------------------------------------------------------------------------
|
||||
DRO | DataReaderObject
|
||||
DWO | DataWriterObject
|
||||
-------------------------------------------------------------------------
|
||||
DDRO | DynamicDataReaderObject
|
||||
DDWO | DynamicDataWriterObject
|
||||
-------------------------------------------------------------------------
|
||||
|
||||
Static (defined in idl)
|
||||
-------------------------------------------------------------------------
|
||||
DTC | DataTopicClient
|
||||
DTS | DataTopicServer
|
||||
-------------------------------------------------------------------------
|
||||
FTC | FunctionTopicClient
|
||||
FTS | FunctionTopicServer
|
||||
-------------------------------------------------------------------------
|
||||
|
||||
Dynamic (Topic will be defined in source code)
|
||||
-------------------------------------------------------------------------
|
||||
DDTC | DynamicDataTopicClient
|
||||
DDTS | DynamicDataTopicServer
|
||||
-------------------------------------------------------------------------
|
||||
DFTC | DynamicFunctionTopicClient
|
||||
DFTS | DynamicFunctionTopicServer
|
||||
-------------------------------------------------------------------------
|
||||
|
||||
Tool to publish & subscribe (to) data
|
||||
-------------------------------------------------------------------------
|
||||
DTCR | DataTopicContentReceiver
|
||||
DTCG | DataTopicContentGenerator
|
||||
-------------------------------------------------------------------------
|
||||
@@ -1,18 +0,0 @@
|
||||
#
|
||||
# $Id$
|
||||
# $HeadURL$
|
||||
# $Author$
|
||||
#
|
||||
|
||||
IF(BUILD_RTI)
|
||||
|
||||
ADD_INTERFACE_LIBRARY(
|
||||
routing_plugin
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/routing_plugin.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../..
|
||||
ddsgen
|
||||
ddsQoS
|
||||
NGLLogger
|
||||
)
|
||||
|
||||
ENDIF(BUILD_RTI)
|
||||
@@ -1,433 +0,0 @@
|
||||
|
||||
|
||||
#include <DDS/Generic/generic_base.h>
|
||||
#include <DDS/QosProfile/DDS_DefaultQos.h>
|
||||
#include <NGLLogger/INGLLogger.h>
|
||||
|
||||
#if BUILD_RTI
|
||||
#include <dds/pub/DataWriter.hpp>
|
||||
#include <dds/pub/discovery.hpp>
|
||||
#include <dds/sub/DataReader.hpp>
|
||||
#include <dds/sub/DataReaderListener.hpp>
|
||||
#include <dds/topic/Topic.hpp>
|
||||
#include <dds/topic/find.hpp>
|
||||
|
||||
namespace DebugInfo
|
||||
{
|
||||
static inline QByteArray toReadable(const rti::core::Guid& guid)
|
||||
{
|
||||
return QByteArray(reinterpret_cast<const char*>(&guid[0]), 16).toHex();
|
||||
}
|
||||
|
||||
static inline QByteArray toReadable(const rti::core::SequenceNumber& seqNo, const rti::core::Guid& guid)
|
||||
{
|
||||
return "SeqNo: " + QString::number(seqNo.value()).toLatin1() + ", Guid-DW: " + toReadable(guid);
|
||||
}
|
||||
|
||||
static inline QByteArray toReadable(const rti::core::SampleIdentity& identiy)
|
||||
{
|
||||
return toReadable(identiy.sequence_number(), identiy.writer_guid());
|
||||
}
|
||||
} // namespace DebugInfo
|
||||
|
||||
namespace FTS
|
||||
{
|
||||
template <typename GENERIC_FTS> struct TopicNames;
|
||||
}
|
||||
|
||||
namespace FTC
|
||||
{
|
||||
template <typename GENERIC_FTC> struct TopicNames;
|
||||
}
|
||||
|
||||
namespace RoutingService
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
static dds::topic::Topic<T> getTopic(const dds::domain::DomainParticipant& participant, const std::string& topicName)
|
||||
{
|
||||
using DataTopic = dds::topic::Topic<T>;
|
||||
auto ret = dds::topic::find<DataTopic>(participant, topicName);
|
||||
if (ret != nullptr)
|
||||
return ret;
|
||||
return DataTopic(participant, topicName);
|
||||
}
|
||||
|
||||
class SampleWriterInterface
|
||||
{
|
||||
public:
|
||||
SampleWriterInterface() = default;
|
||||
virtual ~SampleWriterInterface() = default;
|
||||
|
||||
virtual void writeSamples() = 0;
|
||||
|
||||
virtual NGL::INGLLogger& logger() = 0;
|
||||
};
|
||||
|
||||
class DataWriterTaskInterface
|
||||
{
|
||||
public:
|
||||
DataWriterTaskInterface() = default;
|
||||
virtual ~DataWriterTaskInterface() = default;
|
||||
|
||||
virtual void enqueue(SampleWriterInterface* swi) = 0;
|
||||
};
|
||||
|
||||
class TopicDispatcherInterface
|
||||
{
|
||||
public:
|
||||
TopicDispatcherInterface() = default;
|
||||
virtual ~TopicDispatcherInterface() = default;
|
||||
|
||||
virtual bool init(DataWriterTaskInterface* dwt, const dds::domain::DomainParticipant& dpIn,
|
||||
const dds::sub::Subscriber& subIn, const dds::domain::DomainParticipant& dpOut,
|
||||
const dds::pub::Publisher& pubOut) = 0;
|
||||
virtual void shutdown() = 0;
|
||||
};
|
||||
|
||||
template <typename TOPIC> class SampleWriter final : public SampleWriterInterface
|
||||
{
|
||||
public:
|
||||
SampleWriter(dds::sub::LoanedSamples<TOPIC>&& samples, const dds::pub::DataWriter<TOPIC>& dataWriter,
|
||||
bool bWithOriginalIdentity, NGL::INGLLogger& logger)
|
||||
: m_loanedSamples(std::move(samples)), m_dataWriter(dataWriter), m_bWithOriginalIdentity(bWithOriginalIdentity),
|
||||
m_logger(logger)
|
||||
{
|
||||
}
|
||||
|
||||
rti::core::SampleIdentity getIdentity(const rti::core::SampleIdentity& identity) const
|
||||
{
|
||||
|
||||
static const auto s_unknownSequenceNumber(rti::core::SequenceNumber::unknown());
|
||||
static const auto s_unknownGui(rti::core::Guid::unknown());
|
||||
static const auto s_unknownSampleIdentity(rti::core::SampleIdentity::unknown());
|
||||
|
||||
if (!m_bWithOriginalIdentity)
|
||||
return s_unknownSampleIdentity;
|
||||
|
||||
if (identity.sequence_number() == s_unknownSequenceNumber)
|
||||
return s_unknownSampleIdentity;
|
||||
if (identity.writer_guid() == s_unknownGui)
|
||||
return s_unknownSampleIdentity;
|
||||
return identity;
|
||||
}
|
||||
|
||||
void writeSamples() override
|
||||
{
|
||||
TRACE_LOG(m_logger) << "Writing samples for " << DDS::topic_type_name<TOPIC>::value()
|
||||
<< ", sample count: " << m_loanedSamples.length();
|
||||
rti::pub::WriteParams writeParams;
|
||||
for (const auto& sample : m_loanedSamples)
|
||||
{
|
||||
try
|
||||
{
|
||||
writeParams.identity(getIdentity(sample.info()->original_publication_virtual_sample_identity()));
|
||||
writeParams.related_sample_identity(
|
||||
getIdentity(sample.info()->related_original_publication_virtual_sample_identity()));
|
||||
|
||||
writeParams.handle(sample.info().instance_handle());
|
||||
writeParams.flag(sample.info()->flag());
|
||||
|
||||
TRACE_LOG(m_logger) << "identity: " << DebugInfo::toReadable(writeParams.identity())
|
||||
<< ", related_sample_identity: "
|
||||
<< DebugInfo::toReadable(writeParams.related_sample_identity());
|
||||
|
||||
const auto& state = sample.info().state();
|
||||
const dds::sub::status::InstanceState& instanceState = state.instance_state();
|
||||
if (instanceState == dds::sub::status::InstanceState::alive())
|
||||
{
|
||||
m_dataWriter->write(sample.data(), writeParams);
|
||||
}
|
||||
else if (instanceState == dds::sub::status::InstanceState::not_alive_disposed())
|
||||
{
|
||||
TRACE_LOG(m_logger) << " - is disposed";
|
||||
m_dataWriter->dispose_instance(writeParams);
|
||||
}
|
||||
else if (instanceState == dds::sub::status::InstanceState::not_alive_no_writers())
|
||||
{
|
||||
TRACE_LOG(m_logger) << " - is unregistered";
|
||||
m_dataWriter->unregister_instance(writeParams);
|
||||
}
|
||||
else
|
||||
WARNING_LOG(m_logger) << "Unknown instance state: " << instanceState;
|
||||
}
|
||||
catch (const dds::core::Exception& ex)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "writeSamples exception: " << ex.what();
|
||||
}
|
||||
}
|
||||
m_dataWriter->flush();
|
||||
}
|
||||
|
||||
NGL::INGLLogger& logger() override
|
||||
{
|
||||
return m_logger;
|
||||
}
|
||||
|
||||
private:
|
||||
dds::sub::LoanedSamples<TOPIC> m_loanedSamples;
|
||||
dds::pub::DataWriter<TOPIC> m_dataWriter;
|
||||
bool m_bWithOriginalIdentity;
|
||||
NGL::INGLLogger& m_logger;
|
||||
};
|
||||
|
||||
template <typename T> class DataTopicListener final : public dds::sub::DataReaderListener<T>
|
||||
{
|
||||
public:
|
||||
using DataReader = dds::sub::DataReader<T>;
|
||||
|
||||
DataTopicListener(DataWriterTaskInterface* dwt, const std::string& topicName, DDS::QosProfile::TopicType topicType,
|
||||
NGL::INGLLogger& logger)
|
||||
: m_dwt(dwt), m_dataWriter(nullptr), m_topicName(topicName), m_topicType(topicType), m_logger(logger)
|
||||
{
|
||||
}
|
||||
|
||||
bool init(const dds::domain::DomainParticipant& dpOut, const dds::pub::Publisher& pubOut)
|
||||
{
|
||||
if (!m_dwt)
|
||||
return false;
|
||||
DEBUG_LOG(m_logger) << "Creating DataWriter for domain " << dpOut.domain_id();
|
||||
m_dataWriter = dds::pub::DataWriter<T>(pubOut, getTopic<T>(dpOut, m_topicName),
|
||||
DDS::QosProfile::dataWriterDefault(m_topicType));
|
||||
|
||||
dds::domain::DomainParticipant& dpOutNonConst = const_cast<dds::domain::DomainParticipant&>(dpOut);
|
||||
dds::pub::ignore(dpOutNonConst, m_dataWriter.instance_handle());
|
||||
return true;
|
||||
}
|
||||
|
||||
void on_data_available(dds::sub::DataReader<T>& reader) override
|
||||
{
|
||||
|
||||
TRACE_LOG(m_logger) << "Data available for " << DDS::topic_type_name<T>::value();
|
||||
auto ws = new SampleWriter<T>(reader.take(), m_dataWriter,
|
||||
m_topicType == DDS::QosProfile::TopicType::FunctionTopic, m_logger);
|
||||
m_dwt->enqueue(ws);
|
||||
}
|
||||
|
||||
void on_requested_deadline_missed(dds::sub::DataReader<T>&,
|
||||
const dds::core::status::RequestedDeadlineMissedStatus&) override
|
||||
{
|
||||
}
|
||||
|
||||
void on_requested_incompatible_qos(dds::sub::DataReader<T>&,
|
||||
const dds::core::status::RequestedIncompatibleQosStatus&) override
|
||||
{
|
||||
}
|
||||
|
||||
void on_sample_rejected(dds::sub::DataReader<T>&, const dds::core::status::SampleRejectedStatus&) override {}
|
||||
|
||||
void on_liveliness_changed(dds::sub::DataReader<T>&, const dds::core::status::LivelinessChangedStatus&) override {}
|
||||
|
||||
void on_subscription_matched(dds::sub::DataReader<T>&, const dds::core::status::SubscriptionMatchedStatus&) override
|
||||
{
|
||||
}
|
||||
|
||||
void on_sample_lost(dds::sub::DataReader<T>&, const dds::core::status::SampleLostStatus&) override {}
|
||||
|
||||
static dds::core::status::StatusMask mask()
|
||||
{
|
||||
return (dds::core::status::StatusMask::data_available());
|
||||
}
|
||||
|
||||
protected:
|
||||
DataWriterTaskInterface* m_dwt;
|
||||
dds::pub::DataWriter<T> m_dataWriter;
|
||||
std::string m_topicName;
|
||||
DDS::QosProfile::TopicType m_topicType;
|
||||
NGL::INGLLogger& m_logger;
|
||||
};
|
||||
|
||||
template <typename TOPIC> class TopicDispatcher : public TopicDispatcherInterface
|
||||
{
|
||||
protected:
|
||||
explicit TopicDispatcher(NGL::INGLLogger& logger, const std::string& topicName,
|
||||
DDS::QosProfile::TopicType topicType)
|
||||
: m_dataReader(nullptr), m_topicName(topicName), m_topicType(topicType), m_logger(logger)
|
||||
{
|
||||
}
|
||||
|
||||
~TopicDispatcher()
|
||||
{
|
||||
shutdown();
|
||||
}
|
||||
|
||||
bool init(DataWriterTaskInterface* dwt, const dds::domain::DomainParticipant& dpIn,
|
||||
const dds::sub::Subscriber& subIn, const dds::domain::DomainParticipant& dpOut,
|
||||
const dds::pub::Publisher& pubOut) override
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Initializing TopicDispatcher " << "(" << this << ")";
|
||||
if (m_dataReader != nullptr)
|
||||
return false;
|
||||
|
||||
m_dataReader = dds::sub::DataReader<TOPIC>(subIn, getTopic<TOPIC>(dpIn, m_topicName),
|
||||
DDS::QosProfile::dataReaderDefault(m_topicType));
|
||||
DEBUG_LOG(m_logger) << "Creating DataReader for domain " << dpIn.domain_id()
|
||||
<< ", ptr: " << m_dataReader.delegate().get();
|
||||
|
||||
m_dtl.reset(new DataTopicListener<TOPIC>(dwt, m_topicName, m_topicType, m_logger));
|
||||
|
||||
if (!m_dtl->init(dpOut, pubOut))
|
||||
return false;
|
||||
m_dataReader.listener(m_dtl.get(), DataTopicListener<TOPIC>::mask());
|
||||
return true;
|
||||
}
|
||||
|
||||
void shutdown() override
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Cleaning up TopicDispatcher " << "(" << this << ")";
|
||||
if (m_dataReader != nullptr)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "shutting down DataReader: " << m_dataReader.delegate().get();
|
||||
m_dataReader.listener(nullptr, dds::core::status::StatusMask::none());
|
||||
try
|
||||
{
|
||||
m_dataReader.close();
|
||||
}
|
||||
catch (const dds::core::Exception& ex)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "topic close ex: " << ex.what();
|
||||
}
|
||||
}
|
||||
|
||||
m_dtl = nullptr;
|
||||
|
||||
m_dataReader = nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
dds::sub::DataReader<TOPIC> m_dataReader;
|
||||
std::unique_ptr<DataTopicListener<TOPIC>> m_dtl;
|
||||
std::string m_topicName;
|
||||
DDS::QosProfile::TopicType m_topicType;
|
||||
NGL::INGLLogger& m_logger;
|
||||
};
|
||||
|
||||
template <typename TOPIC> class DataTopicDispatcher final : public TopicDispatcher<TOPIC>
|
||||
{
|
||||
public:
|
||||
explicit DataTopicDispatcher(NGL::INGLLogger& logger)
|
||||
: TopicDispatcher<TOPIC>(logger, DDS::Helper::getShortTopicName(dds::topic::topic_type_name<TOPIC>::value()),
|
||||
DDS::QosProfile::TopicType::DataTopic)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename FTS_TOPIC>
|
||||
class FunctionTopicReplyDispatcher final : public TopicDispatcher<typename FTS_TOPIC::ReplyTopic>
|
||||
{
|
||||
public:
|
||||
explicit FunctionTopicReplyDispatcher(NGL::INGLLogger& logger)
|
||||
: TopicDispatcher<typename FTS_TOPIC::ReplyTopic>(logger, FTS::TopicNames<FTS_TOPIC>::replyTopicName(),
|
||||
DDS::QosProfile::TopicType::FunctionTopic)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename FTC_TOPIC>
|
||||
class FunctionTopicRequestDispatcher final : public TopicDispatcher<typename FTC_TOPIC::RequestTopic>
|
||||
{
|
||||
public:
|
||||
explicit FunctionTopicRequestDispatcher(NGL::INGLLogger& logger)
|
||||
: TopicDispatcher<typename FTC_TOPIC::RequestTopic>(logger, FTC::TopicNames<FTC_TOPIC>::requestTopicName(),
|
||||
DDS::QosProfile::TopicType::FunctionTopic)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace RoutingService
|
||||
|
||||
#else // BUILD_RTI=OFF - Stub declarations
|
||||
|
||||
namespace RoutingService
|
||||
{
|
||||
// Stub interfaces when BUILD_RTI=OFF
|
||||
class SampleWriterInterface
|
||||
{
|
||||
public:
|
||||
SampleWriterInterface() = default;
|
||||
virtual ~SampleWriterInterface() = default;
|
||||
virtual void writeSamples() = 0;
|
||||
virtual NGL::INGLLogger& logger() = 0;
|
||||
};
|
||||
|
||||
class DataWriterTaskInterface
|
||||
{
|
||||
public:
|
||||
DataWriterTaskInterface() = default;
|
||||
virtual ~DataWriterTaskInterface() = default;
|
||||
virtual void enqueue(SampleWriterInterface* /*swi*/) = 0;
|
||||
};
|
||||
|
||||
class TopicDispatcherInterface
|
||||
{
|
||||
public:
|
||||
TopicDispatcherInterface() = default;
|
||||
virtual ~TopicDispatcherInterface() = default;
|
||||
virtual bool init(DataWriterTaskInterface* /*dwt*/, void* /*dpIn*/, void* /*subIn*/, void* /*dpOut*/,
|
||||
void* /*pubOut*/) = 0;
|
||||
virtual void shutdown() = 0;
|
||||
};
|
||||
|
||||
// Stub template classes when BUILD_RTI=OFF
|
||||
template <typename TOPIC> class SampleWriter final : public SampleWriterInterface
|
||||
{
|
||||
public:
|
||||
SampleWriter(void* /*samples*/, void* /*dataWriter*/, bool /*bWithOriginalIdentity*/, NGL::INGLLogger& /*logger*/)
|
||||
{
|
||||
}
|
||||
void writeSamples() override {}
|
||||
NGL::INGLLogger& logger() override
|
||||
{
|
||||
static NGL::INGLLogger dummyLogger;
|
||||
return dummyLogger;
|
||||
}
|
||||
|
||||
private:
|
||||
NGL::INGLLogger& m_logger;
|
||||
};
|
||||
|
||||
template <typename TOPIC> class TopicDispatcher : public TopicDispatcherInterface
|
||||
{
|
||||
protected:
|
||||
explicit TopicDispatcher(NGL::INGLLogger& /*logger*/, const std::string& /*topicName*/, int /*topicType*/) {}
|
||||
~TopicDispatcher() { shutdown(); }
|
||||
bool init(DataWriterTaskInterface* /*dwt*/, void* /*dpIn*/, void* /*subIn*/, void* /*dpOut*/,
|
||||
void* /*pubOut*/) override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
void shutdown() override {}
|
||||
|
||||
private:
|
||||
NGL::INGLLogger& m_logger;
|
||||
};
|
||||
|
||||
template <typename TOPIC> class DataTopicDispatcher final : public TopicDispatcher<TOPIC>
|
||||
{
|
||||
public:
|
||||
explicit DataTopicDispatcher(NGL::INGLLogger& logger) : TopicDispatcher<TOPIC>(logger, "", 0) {}
|
||||
};
|
||||
|
||||
template <typename FTS_TOPIC>
|
||||
class FunctionTopicReplyDispatcher final : public TopicDispatcher<typename FTS_TOPIC::ReplyTopic>
|
||||
{
|
||||
public:
|
||||
explicit FunctionTopicReplyDispatcher(NGL::INGLLogger& logger)
|
||||
: TopicDispatcher<typename FTS_TOPIC::ReplyTopic>(logger, "", 0)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename FTC_TOPIC>
|
||||
class FunctionTopicRequestDispatcher final : public TopicDispatcher<typename FTC_TOPIC::RequestTopic>
|
||||
{
|
||||
public:
|
||||
explicit FunctionTopicRequestDispatcher(NGL::INGLLogger& logger)
|
||||
: TopicDispatcher<typename FTC_TOPIC::RequestTopic>(logger, "", 0)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace RoutingService
|
||||
|
||||
#endif // BUILD_RTI
|
||||
Reference in new issue
Block a user