From e3985be899270564492820befd9b10350652f24e Mon Sep 17 00:00:00 2001 From: Miguel Company <miguelcompany@eprosima.com> Date: Thu, 4 Jul 2024 14:28:00 +0200 Subject: [PATCH 1/3] Fix topic interference on `liveliness_changed` status (#4988) * Refs #21189. Basic infrastructure for ROS2 blackbox tests. Signed-off-by: Miguel Company <miguelcompany@eprosima.com> * Refs #21189. Added callback for liveliness_changed event. Signed-off-by: Miguel Company <miguelcompany@eprosima.com> * Refs #21189. Added ROS2 regression test. Signed-off-by: Miguel Company <miguelcompany@eprosima.com> * Refs #21189. Added blackbox regression test. Signed-off-by: Miguel Company <miguelcompany@eprosima.com> * Refs #21189. Fix StatefulReader. Signed-off-by: Miguel Company <miguelcompany@eprosima.com> * Refs #21189. Fix StatelessReader. Signed-off-by: Miguel Company <miguelcompany@eprosima.com> * Refs #21189. Uncrustify and doxygen. Signed-off-by: Miguel Company <miguelcompany@eprosima.com> * Refs #21245. Change liveliness announcement periods. Signed-off-by: Miguel Company <miguelcompany@eprosima.com> * Refs #21245. Create ROS 2 builtin endpoints. Signed-off-by: Miguel Company <miguelcompany@eprosima.com> * Refs #21245. Fix type and QoS on ros_discovery_info. Signed-off-by: Miguel Company <miguelcompany@eprosima.com> * Refs #21245. Avoid collision with true ROS 2 topics. Signed-off-by: Miguel Company <miguelcompany@eprosima.com> * Refs #21245. Uncrustify. Signed-off-by: Miguel Company <miguelcompany@eprosima.com> * Refs #21245. Fix warnings on MacOS. Signed-off-by: Miguel Company <miguelcompany@eprosima.com> * Refs #21245. Fix tsan reported deadlock. Signed-off-by: Miguel Company <miguelcompany@eprosima.com> * Refs #21189. Fix long-standing deadlock in WLP. Signed-off-by: Miguel Company <miguelcompany@eprosima.com> * Refs #21189. Fix build after rebase. Signed-off-by: Miguel Company <miguelcompany@eprosima.com> --------- Signed-off-by: Miguel Company <miguelcompany@eprosima.com> (cherry picked from commit 9243eadae1553142514e6220f736f71d9020cc47) # Conflicts: # src/cpp/rtps/reader/StatefulReader.cpp # src/cpp/rtps/reader/StatelessReader.cpp # test/blackbox/common/BlackboxTestsLivelinessQos.cpp --- src/cpp/rtps/builtin/liveliness/WLP.cpp | 3 +- src/cpp/rtps/reader/StatefulReader.cpp | 37 ++- src/cpp/rtps/reader/StatelessReader.cpp | 49 ++- .../common/BlackboxTestsLivelinessQos.cpp | 173 ++++++++++ test/blackbox/common/DDSBlackboxTestsROS2.cpp | 167 ++++++++++ test/blackbox/common/ros2/Context.hpp | 295 ++++++++++++++++++ .../blackbox/common/ros2/DataReaderHolder.hpp | 38 +++ .../blackbox/common/ros2/DataWriterHolder.hpp | 38 +++ test/blackbox/common/ros2/GenericHolder.hpp | 77 +++++ test/blackbox/common/ros2/Node.hpp | 204 ++++++++++++ test/blackbox/common/ros2/PublicationNode.hpp | 123 ++++++++ .../blackbox/common/ros2/SubscriptionNode.hpp | 122 ++++++++ test/blackbox/common/ros2/TopicHolder.hpp | 38 +++ 13 files changed, 1349 insertions(+), 15 deletions(-) create mode 100644 test/blackbox/common/DDSBlackboxTestsROS2.cpp create mode 100644 test/blackbox/common/ros2/Context.hpp create mode 100644 test/blackbox/common/ros2/DataReaderHolder.hpp create mode 100644 test/blackbox/common/ros2/DataWriterHolder.hpp create mode 100644 test/blackbox/common/ros2/GenericHolder.hpp create mode 100644 test/blackbox/common/ros2/Node.hpp create mode 100644 test/blackbox/common/ros2/PublicationNode.hpp create mode 100644 test/blackbox/common/ros2/SubscriptionNode.hpp create mode 100644 test/blackbox/common/ros2/TopicHolder.hpp diff --git a/src/cpp/rtps/builtin/liveliness/WLP.cpp b/src/cpp/rtps/builtin/liveliness/WLP.cpp index 987702046a4..d10a508010e 100644 --- a/src/cpp/rtps/builtin/liveliness/WLP.cpp +++ b/src/cpp/rtps/builtin/liveliness/WLP.cpp @@ -860,10 +860,11 @@ bool WLP::remove_local_reader( bool WLP::automatic_liveliness_assertion() { - std::lock_guard<std::recursive_mutex> guard(*mp_builtinProtocols->mp_PDP->getMutex()); + std::unique_lock<std::recursive_mutex> lock(*mp_builtinProtocols->mp_PDP->getMutex()); if (0 < automatic_writers_.size()) { + lock.unlock(); return send_liveliness_message(automatic_instance_handle_); } diff --git a/src/cpp/rtps/reader/StatefulReader.cpp b/src/cpp/rtps/reader/StatefulReader.cpp index 33361c6394c..2fc3e364f33 100644 --- a/src/cpp/rtps/reader/StatefulReader.cpp +++ b/src/cpp/rtps/reader/StatefulReader.cpp @@ -373,6 +373,7 @@ bool StatefulReader::matched_writer_remove( const GUID_t& writer_guid, bool removed_by_lease) { +<<<<<<< HEAD if (is_alive_ && liveliness_lease_duration_ < c_TimeInfinite) { @@ -404,9 +405,13 @@ bool StatefulReader::matched_writer_remove( } std::unique_lock<RecursiveTimedMutex> lock(mp_mutex); +======= +>>>>>>> 9243eadae (Fix topic interference on `liveliness_changed` status (#4988)) WriterProxy* wproxy = nullptr; if (is_alive_) { + std::unique_lock<RecursiveTimedMutex> lock(mp_mutex); + //Remove cachechanges belonging to the unmatched writer mp_history->writer_unmatched(writer_guid, get_last_notified(writer_guid)); @@ -468,7 +473,37 @@ bool StatefulReader::matched_writer_remove( } } - return (wproxy != nullptr); + bool ret_val = (wproxy != nullptr); + if (ret_val && liveliness_lease_duration_ < c_TimeInfinite) + { + auto wlp = this->mp_RTPSParticipant->wlp(); + if ( wlp != nullptr) + { + LivelinessData::WriterStatus writer_liveliness_status; + wlp->sub_liveliness_manager_->remove_writer( + writer_guid, + liveliness_kind_, + liveliness_lease_duration_, + writer_liveliness_status); + + if (writer_liveliness_status == LivelinessData::WriterStatus::ALIVE) + { + update_liveliness_changed_status(writer_guid, -1, 0); + } + else if (writer_liveliness_status == LivelinessData::WriterStatus::NOT_ALIVE) + { + update_liveliness_changed_status(writer_guid, 0, -1); + } + + } + else + { + EPROSIMA_LOG_ERROR(RTPS_LIVELINESS, + "Finite liveliness lease duration but WLP not enabled, cannot remove writer"); + } + } + + return ret_val; } bool StatefulReader::matched_writer_is_matched( diff --git a/src/cpp/rtps/reader/StatelessReader.cpp b/src/cpp/rtps/reader/StatelessReader.cpp index 03aa7ac667d..4c1326cf370 100644 --- a/src/cpp/rtps/reader/StatelessReader.cpp +++ b/src/cpp/rtps/reader/StatelessReader.cpp @@ -223,18 +223,9 @@ bool StatelessReader::matched_writer_remove( const GUID_t& writer_guid, bool removed_by_lease) { - if (liveliness_lease_duration_ < c_TimeInfinite) - { - auto wlp = mp_RTPSParticipant->wlp(); - if ( wlp != nullptr) - { - LivelinessData::WriterStatus writer_liveliness_status; - wlp->sub_liveliness_manager_->remove_writer( - writer_guid, - liveliness_kind_, - liveliness_lease_duration_, - writer_liveliness_status); + bool ret_val = false; +<<<<<<< HEAD if (writer_liveliness_status == LivelinessData::WriterStatus::ALIVE) { wlp->update_liveliness_changed_status(writer_guid, this, -1, 0); @@ -250,6 +241,8 @@ bool StatelessReader::matched_writer_remove( "Finite liveliness lease duration but WLP not enabled, cannot remove writer"); } } +======= +>>>>>>> 9243eadae (Fix topic interference on `liveliness_changed` status (#4988)) { std::unique_lock<RecursiveTimedMutex> guard(mp_mutex); @@ -289,11 +282,41 @@ bool StatelessReader::matched_writer_remove( } #endif //FASTDDS_STATISTICS - return true; + ret_val = true; + break; } } } - return false; + + if (ret_val && liveliness_lease_duration_ < c_TimeInfinite) + { + auto wlp = mp_RTPSParticipant->wlp(); + if ( wlp != nullptr) + { + LivelinessData::WriterStatus writer_liveliness_status; + wlp->sub_liveliness_manager_->remove_writer( + writer_guid, + liveliness_kind_, + liveliness_lease_duration_, + writer_liveliness_status); + + if (writer_liveliness_status == LivelinessData::WriterStatus::ALIVE) + { + update_liveliness_changed_status(writer_guid, -1, 0); + } + else if (writer_liveliness_status == LivelinessData::WriterStatus::NOT_ALIVE) + { + update_liveliness_changed_status(writer_guid, 0, -1); + } + } + else + { + EPROSIMA_LOG_ERROR(RTPS_LIVELINESS, + "Finite liveliness lease duration but WLP not enabled, cannot remove writer"); + } + } + + return ret_val; } bool StatelessReader::matched_writer_is_matched( diff --git a/test/blackbox/common/BlackboxTestsLivelinessQos.cpp b/test/blackbox/common/BlackboxTestsLivelinessQos.cpp index 14aab586e0b..70a63ea133b 100644 --- a/test/blackbox/common/BlackboxTestsLivelinessQos.cpp +++ b/test/blackbox/common/BlackboxTestsLivelinessQos.cpp @@ -12,8 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. +<<<<<<< HEAD #include "BlackboxTests.hpp" +======= +#include <string> +>>>>>>> 9243eadae (Fix topic interference on `liveliness_changed` status (#4988)) #include <thread> #include "PubSubReader.hpp" @@ -2039,6 +2043,175 @@ TEST(LivelinessTests, correct_liveliness_state_one_writer_multiple_readers) ASSERT_EQ(reader.sub_wait_liveliness_lost_for(2, std::chrono::seconds(4)), 2u); } +/** + * This is a regression test for redmine issue #21189. + * + * The test ensures that liveliness changed status is not affected by writers on a topic different from + * the one of the reader. + * + * The test creates two readers and two writers, each reader and writer pair on a different topic. + * Writing a sample on one writer should not affect the liveliness changed status of the other reader. + * Destroying the writer should not affect the liveliness changed status of the other reader. + */ +static void test_liveliness_qos_independent_topics( + const std::string& topic_name, + eprosima::fastdds::dds::ReliabilityQosPolicyKind reliability_kind) +{ + const auto lease_dutation_time = std::chrono::seconds(1); + const eprosima::fastdds::Duration_t lease_duration(1, 0); + const eprosima::fastdds::Duration_t announcement_period(0, 250000000); + + PubSubReader<HelloWorldPubSubType> reader1(topic_name + "1"); + PubSubReader<HelloWorldPubSubType> reader2(topic_name + "2"); + + PubSubWriter<HelloWorldPubSubType> writer1(topic_name + "1"); + PubSubWriter<HelloWorldPubSubType> writer2(topic_name + "2"); + + // Configure and start the readers + reader1.liveliness_kind(eprosima::fastdds::dds::AUTOMATIC_LIVELINESS_QOS) + .liveliness_lease_duration(lease_duration) + .reliability(reliability_kind) + .init(); + reader2.liveliness_kind(eprosima::fastdds::dds::AUTOMATIC_LIVELINESS_QOS) + .liveliness_lease_duration(lease_duration) + .reliability(reliability_kind) + .init(); + + // Configure and start the writers + writer1.liveliness_kind(eprosima::fastdds::dds::AUTOMATIC_LIVELINESS_QOS) + .liveliness_lease_duration(lease_duration) + .liveliness_announcement_period(announcement_period) + .reliability(reliability_kind) + .init(); + writer2.liveliness_kind(eprosima::fastdds::dds::AUTOMATIC_LIVELINESS_QOS) + .liveliness_lease_duration(lease_duration) + .liveliness_announcement_period(announcement_period) + .reliability(reliability_kind) + .init(); + + // Wait for discovery + reader1.wait_discovery(); + reader2.wait_discovery(); + writer1.wait_discovery(); + writer2.wait_discovery(); + + HelloWorldPubSubType::type data; + + // Write a sample on writer1 and wait for reader1 to assert writer1's liveliness + writer1.send_sample(data); + reader1.wait_liveliness_recovered(); + + // Check liveliness changed status on both readers + { + auto liveliness = reader1.get_liveliness_changed_status(); + EXPECT_EQ(liveliness.alive_count, 1); + EXPECT_EQ(liveliness.not_alive_count, 0); + } + + { + auto liveliness = reader2.get_liveliness_changed_status(); + EXPECT_EQ(liveliness.alive_count, 0); + EXPECT_EQ(liveliness.not_alive_count, 0); + } + + // Write a sample on writer2 and wait for reader2 to assert writer2's liveliness + writer2.send_sample(data); + reader2.wait_liveliness_recovered(); + + // Check liveliness changed status on both readers + { + auto liveliness = reader1.get_liveliness_changed_status(); + EXPECT_EQ(liveliness.alive_count, 1); + EXPECT_EQ(liveliness.not_alive_count, 0); + } + + { + auto liveliness = reader2.get_liveliness_changed_status(); + EXPECT_EQ(liveliness.alive_count, 1); + EXPECT_EQ(liveliness.not_alive_count, 0); + } + + // Destroy writer2 and wait twice the lease duration time + writer2.destroy(); + std::this_thread::sleep_for(lease_dutation_time * 2); + + // Check liveliness changed status on both readers + { + auto liveliness = reader1.get_liveliness_changed_status(); + EXPECT_EQ(liveliness.alive_count, 1); + EXPECT_EQ(liveliness.not_alive_count, 0); + } + + { + auto liveliness = reader2.get_liveliness_changed_status(); + EXPECT_EQ(liveliness.alive_count, 0); + EXPECT_EQ(liveliness.not_alive_count, 0); + } + + // Start writer2 again and wait for reader2 to assert writer2's liveliness + writer2.init(); + reader2.wait_discovery(); + writer2.send_sample(data); + reader2.wait_liveliness_recovered(2); + + // Check liveliness changed status on both readers + { + auto liveliness = reader1.get_liveliness_changed_status(); + EXPECT_EQ(liveliness.alive_count, 1); + EXPECT_EQ(liveliness.not_alive_count, 0); + } + + { + auto liveliness = reader2.get_liveliness_changed_status(); + EXPECT_EQ(liveliness.alive_count, 1); + EXPECT_EQ(liveliness.not_alive_count, 0); + } + + // Destroy writer1 and wait twice the lease duration time + writer1.destroy(); + std::this_thread::sleep_for(lease_dutation_time * 2); + + // Check liveliness changed status on both readers + { + auto liveliness = reader1.get_liveliness_changed_status(); + EXPECT_EQ(liveliness.alive_count, 0); + EXPECT_EQ(liveliness.not_alive_count, 0); + } + + { + auto liveliness = reader2.get_liveliness_changed_status(); + EXPECT_EQ(liveliness.alive_count, 1); + EXPECT_EQ(liveliness.not_alive_count, 0); + } + + // Destroy writer2 and wait twice the lease duration time + writer2.destroy(); + std::this_thread::sleep_for(lease_dutation_time * 2); + + // Check liveliness changed status on both readers + { + auto liveliness = reader1.get_liveliness_changed_status(); + EXPECT_EQ(liveliness.alive_count, 0); + EXPECT_EQ(liveliness.not_alive_count, 0); + } + + { + auto liveliness = reader2.get_liveliness_changed_status(); + EXPECT_EQ(liveliness.alive_count, 0); + EXPECT_EQ(liveliness.not_alive_count, 0); + } +} + +TEST_P(LivelinessQos, IndependentTopics_reliable) +{ + test_liveliness_qos_independent_topics(TEST_TOPIC_NAME, eprosima::fastdds::dds::RELIABLE_RELIABILITY_QOS); +} + +TEST_P(LivelinessQos, IndependentTopics_besteffort) +{ + test_liveliness_qos_independent_topics(TEST_TOPIC_NAME, eprosima::fastdds::dds::BEST_EFFORT_RELIABILITY_QOS); +} + #ifdef INSTANTIATE_TEST_SUITE_P #define GTEST_INSTANTIATE_TEST_MACRO(x, y, z, w) INSTANTIATE_TEST_SUITE_P(x, y, z, w) #else diff --git a/test/blackbox/common/DDSBlackboxTestsROS2.cpp b/test/blackbox/common/DDSBlackboxTestsROS2.cpp new file mode 100644 index 00000000000..d04dfbc3005 --- /dev/null +++ b/test/blackbox/common/DDSBlackboxTestsROS2.cpp @@ -0,0 +1,167 @@ +// Copyright 2024 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include <cstdint> +#include <chrono> +#include <functional> +#include <map> +#include <memory> +#include <mutex> +#include <string> +#include <thread> + +#include <gtest/gtest.h> + +#include <fastdds/dds/core/detail/DDSReturnCode.hpp> +#include <fastdds/dds/core/policy/QosPolicies.hpp> +#include <fastdds/dds/core/status/LivelinessChangedStatus.hpp> +#include <fastdds/dds/domain/DomainParticipant.hpp> +#include <fastdds/dds/domain/DomainParticipantFactory.hpp> +#include <fastdds/dds/domain/qos/DomainParticipantQos.hpp> +#include <fastdds/dds/publisher/DataWriter.hpp> +#include <fastdds/dds/publisher/DataWriterListener.hpp> +#include <fastdds/dds/publisher/Publisher.hpp> +#include <fastdds/dds/publisher/qos/DataWriterQos.hpp> +#include <fastdds/dds/publisher/qos/PublisherQos.hpp> +#include <fastdds/dds/subscriber/DataReader.hpp> +#include <fastdds/dds/subscriber/DataReaderListener.hpp> +#include <fastdds/dds/subscriber/qos/DataReaderQos.hpp> +#include <fastdds/dds/subscriber/qos/SubscriberQos.hpp> +#include <fastdds/dds/subscriber/Subscriber.hpp> +#include <fastdds/dds/topic/qos/TopicQos.hpp> +#include <fastdds/dds/topic/Topic.hpp> +#include <fastdds/dds/topic/TypeSupport.hpp> +#include <fastdds/rtps/common/Time_t.hpp> + +#include "./ros2/Context.hpp" +#include "./ros2/DataReaderHolder.hpp" +#include "./ros2/DataWriterHolder.hpp" +#include "./ros2/Node.hpp" +#include "./ros2/PublicationNode.hpp" +#include "./ros2/SubscriptionNode.hpp" +#include "./ros2/TopicHolder.hpp" + +#include "BlackboxTests.hpp" +#include "../types/HelloWorldPubSubTypes.hpp" + +namespace eprosima { +namespace fastdds { +namespace dds { + +namespace ros2 = eprosima::testing::ros2; + +/** + * This is a regression test for redmine issue #21189. + * + * It mimicks the behavior of the following ROS2 system test: + * https://github.com/ros2/system_tests/blob/rolling/test_quality_of_service/test/test_liveliness.cpp + */ +TEST(DDS_ROS2, test_automatic_liveliness_changed) +{ + // Force intraprocess + auto factory = DomainParticipantFactory::get_shared_instance(); + LibrarySettings old_library_settings; + factory->get_library_settings(old_library_settings); + { + LibrarySettings library_settings; + library_settings.intraprocess_delivery = IntraprocessDeliveryType::INTRAPROCESS_FULL; + factory->set_library_settings(library_settings); + } + + { + auto context = std::make_shared<ros2::Context>(); + + auto topic_name = TEST_TOPIC_NAME; + const Duration_t liveliness_duration = { 1, 0 }; + const Duration_t liveliness_announcement_period = { 0, 333333333 }; + LivelinessQosPolicy liveliness; + liveliness.kind = LivelinessQosPolicyKind::AUTOMATIC_LIVELINESS_QOS; + liveliness.lease_duration = liveliness_duration; + liveliness.announcement_period = liveliness_announcement_period; + ReliabilityQosPolicy reliability; + reliability.kind = RELIABLE_RELIABILITY_QOS; + + TypeSupport type_support(new HelloWorldPubSubType()); + auto pub = std::make_shared<ros2::PublicationNode>(context, topic_name + "/pub", topic_name, type_support); + auto sub = std::make_shared<ros2::SubscriptionNode>(context, topic_name + "/sub", topic_name, type_support); + + // Configure the subscription node with a listener that will check the liveliness changed status. + int total_number_of_liveliness_events = 0; + auto sub_listener = std::make_shared<ros2::SubscriptionListener>(); + sub_listener->liveliness_callback = [&total_number_of_liveliness_events]( + const LivelinessChangedStatus& event) -> void + { + total_number_of_liveliness_events++; + + // strict checking for expected events + if (total_number_of_liveliness_events == 1) + { + // publisher came alive + ASSERT_EQ(1, event.alive_count); + ASSERT_EQ(0, event.not_alive_count); + ASSERT_EQ(1, event.alive_count_change); + ASSERT_EQ(0, event.not_alive_count_change); + } + else if (total_number_of_liveliness_events == 2) + { + // publisher died + ASSERT_EQ(0, event.alive_count); + ASSERT_EQ(0, event.not_alive_count); + ASSERT_EQ(-1, event.alive_count_change); + ASSERT_EQ(0, event.not_alive_count_change); + } + }; + sub->set_listener(sub_listener); + + DataReaderQos reader_qos = context->subscriber()->get_default_datareader_qos(); + reader_qos.liveliness(liveliness); + reader_qos.reliability(reliability); + sub->set_qos(reader_qos); + + // Start the subscription node. + sub->start(); + + DataWriterQos writer_qos = context->publisher()->get_default_datawriter_qos(); + writer_qos.liveliness(liveliness); + writer_qos.reliability(reliability); + pub->set_qos(writer_qos); + + // Start the publication node. + pub->start(); + + // Wait some time and kill the publication node. + HelloWorld hello; + hello.message("Hello, World!"); + for (uint16_t i = 0; i < 10; ++i) + { + hello.index(i); + pub->publish(&hello); + std::this_thread::sleep_for(std::chrono::milliseconds(200)); + } + + pub->stop(); + + // Wait some time and check that the liveliness changed status was triggered. + std::this_thread::sleep_for(std::chrono::seconds(6)); + EXPECT_EQ(2, total_number_of_liveliness_events); // check expected number of liveliness events + + sub->stop(); + } + + factory->set_library_settings(old_library_settings); +} + +} // namespace dds +} // namespace fastdds +} // namespace eprosima diff --git a/test/blackbox/common/ros2/Context.hpp b/test/blackbox/common/ros2/Context.hpp new file mode 100644 index 00000000000..7d1644d1f5c --- /dev/null +++ b/test/blackbox/common/ros2/Context.hpp @@ -0,0 +1,295 @@ +// Copyright 2024 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef FASTDDS_TEST_BLACKBOX_COMMON_ROS2__CONTEXT_HPP +#define FASTDDS_TEST_BLACKBOX_COMMON_ROS2__CONTEXT_HPP + +#include <cstdint> +#include <chrono> +#include <functional> +#include <map> +#include <memory> +#include <mutex> +#include <sstream> +#include <string> + +#include <gtest/gtest.h> + +#include <fastdds/dds/core/detail/DDSReturnCode.hpp> +#include <fastdds/dds/core/policy/QosPolicies.hpp> +#include <fastdds/dds/core/status/LivelinessChangedStatus.hpp> +#include <fastdds/dds/domain/DomainParticipant.hpp> +#include <fastdds/dds/domain/DomainParticipantFactory.hpp> +#include <fastdds/dds/domain/qos/DomainParticipantQos.hpp> +#include <fastdds/dds/publisher/DataWriter.hpp> +#include <fastdds/dds/publisher/DataWriterListener.hpp> +#include <fastdds/dds/publisher/Publisher.hpp> +#include <fastdds/dds/publisher/qos/DataWriterQos.hpp> +#include <fastdds/dds/publisher/qos/PublisherQos.hpp> +#include <fastdds/dds/subscriber/DataReader.hpp> +#include <fastdds/dds/subscriber/DataReaderListener.hpp> +#include <fastdds/dds/subscriber/qos/DataReaderQos.hpp> +#include <fastdds/dds/subscriber/qos/SubscriberQos.hpp> +#include <fastdds/dds/subscriber/Subscriber.hpp> +#include <fastdds/dds/topic/qos/TopicQos.hpp> +#include <fastdds/dds/topic/Topic.hpp> +#include <fastdds/dds/topic/TypeSupport.hpp> +#include <fastdds/rtps/common/Time_t.hpp> + +#include "./DataReaderHolder.hpp" +#include "./DataWriterHolder.hpp" +#include "./TopicHolder.hpp" +#include "../BlackboxTests.hpp" +#include "../../types/HelloWorldPubSubTypes.hpp" + +namespace eprosima { +namespace testing { +namespace ros2 { + +using namespace eprosima::fastdds::dds; + +class Context +{ + using RosDiscoveryInfoPubSubType = HelloWorldPubSubType; + +public: + + Context() + { + factory_ = DomainParticipantFactory::get_shared_instance(); + + uint32_t domain_id = static_cast<uint32_t>(GET_PID() % 230); + participant_ = factory_->create_participant(domain_id, PARTICIPANT_QOS_DEFAULT); + EXPECT_NE(nullptr, participant_); + + if (nullptr != participant_) + { + publisher_ = participant_->create_publisher(PUBLISHER_QOS_DEFAULT); + EXPECT_NE(nullptr, publisher_); + subscriber_ = participant_->create_subscriber(SUBSCRIBER_QOS_DEFAULT); + EXPECT_NE(nullptr, subscriber_); + } + + // Create DataWriter for ros_discovery_info topic + if (nullptr != publisher_ && nullptr != subscriber_) + { + TypeSupport type_support(new RosDiscoveryInfoPubSubType()); + std::shared_ptr<TopicHolder> topic_holder; + create_topic(topic_holder, "ros_discovery_info", "rmw_dds_common::msg::dds_::ParticipantEntitiesInfo_", + type_support); + { + DataWriterQos qos = publisher_->get_default_datawriter_qos(); + qos.reliability().kind = RELIABLE_RELIABILITY_QOS; + qos.durability().kind = TRANSIENT_LOCAL_DURABILITY_QOS; + qos.history().kind = KEEP_LAST_HISTORY_QOS; + qos.history().depth = 1; + create_publication(discovery_info_pub_, topic_holder, DATAWRITER_QOS_DEFAULT, nullptr, false); + } + { + DataReaderQos qos = subscriber_->get_default_datareader_qos(); + qos.reliability().kind = RELIABLE_RELIABILITY_QOS; + qos.durability().kind = TRANSIENT_LOCAL_DURABILITY_QOS; + qos.history().kind = KEEP_LAST_HISTORY_QOS; + qos.history().depth = 100; + create_subscription(discovery_info_sub_, topic_holder, DATAREADER_QOS_DEFAULT, nullptr, false); + } + } + } + + ~Context() + { + discovery_info_sub_.reset(); + discovery_info_pub_.reset(); + topics_.clear(); + + if (participant_ != nullptr) + { + participant_->delete_contained_entities(); + factory_->delete_participant(participant_); + } + } + + DomainParticipant* participant() const + { + return participant_; + } + + Publisher* publisher() const + { + return publisher_; + } + + Subscriber* subscriber() const + { + return subscriber_; + } + + void create_topic( + std::shared_ptr<TopicHolder>& topic_holder, + const std::string& topic_name, + const std::string& type_name, + const TypeSupport& type_support) + { + std::lock_guard<std::mutex> lock(mutex_); + + topic_holder = topics_[topic_name]; + if (!topic_holder) + { + EXPECT_EQ(RETCODE_OK, type_support.register_type(participant_, type_name)); + auto topic = participant_->create_topic("testing/" + topic_name, type_name, TOPIC_QOS_DEFAULT); + ASSERT_NE(nullptr, topic); + topic_holder = std::make_shared<TopicHolder>(participant_, topic); + topics_[topic_name] = topic_holder; + } + else + { + EXPECT_EQ(type_name, topic_holder->topic()->get_type_name()); + } + } + + void create_publication( + std::shared_ptr<DataWriterHolder>& publication, + const std::shared_ptr<TopicHolder>& topic_holder, + const DataWriterQos& qos, + DataWriterListener* listener, + bool notify = true) + { + std::lock_guard<std::mutex> lock(mutex_); + + ASSERT_NE(nullptr, publisher_); + DataWriter* writer = publisher_->create_datawriter(topic_holder->topic(), qos, listener); + ASSERT_NE(nullptr, writer); + publication = std::make_shared<DataWriterHolder>(publisher_, writer); + if (notify) + { + notify_publication_creation(publication); + } + } + + void delete_publication( + std::shared_ptr<DataWriterHolder>& publication) + { + if (publication) + { + std::lock_guard<std::mutex> lock(mutex_); + + notify_publication_deletion(publication); + publication.reset(); + } + } + + void create_subscription( + std::shared_ptr<DataReaderHolder>& subscription, + const std::shared_ptr<TopicHolder>& topic_holder, + const DataReaderQos& qos, + DataReaderListener* listener, + bool notify = true) + { + std::lock_guard<std::mutex> lock(mutex_); + + ASSERT_NE(nullptr, subscriber_); + DataReader* reader = subscriber_->create_datareader(topic_holder->topic(), qos, listener); + ASSERT_NE(nullptr, reader); + subscription = std::make_shared<DataReaderHolder>(subscriber_, reader); + if (notify) + { + notify_subscription_creation(subscription); + } + } + + void delete_subscription( + std::shared_ptr<DataReaderHolder>& subscription) + { + if (subscription) + { + std::lock_guard<std::mutex> lock(mutex_); + + notify_subscription_deletion(subscription); + subscription.reset(); + } + } + +private: + + void notify_publication_creation( + const std::shared_ptr<DataWriterHolder>& publication) + { + if (nullptr != discovery_info_pub_) + { + RosDiscoveryInfoPubSubType::type discovery_info; + std::stringstream ss; + ss << "Publication " << publication->writer()->guid() << " created on topic " << + publication->writer()->get_topic()->get_name(); + discovery_info.message(ss.str()); + discovery_info_pub_->writer()->write(&discovery_info); + } + } + + void notify_publication_deletion( + const std::shared_ptr<DataWriterHolder>& publication) + { + if (nullptr != discovery_info_pub_) + { + RosDiscoveryInfoPubSubType::type discovery_info; + std::stringstream ss; + ss << "Publication " << publication->writer()->guid() << " deleted on topic " << + publication->writer()->get_topic()->get_name(); + discovery_info.message(ss.str()); + discovery_info_pub_->writer()->write(&discovery_info); + } + } + + void notify_subscription_creation( + const std::shared_ptr<DataReaderHolder>& subscription) + { + if (nullptr != discovery_info_pub_) + { + RosDiscoveryInfoPubSubType::type discovery_info; + std::stringstream ss; + ss << "Subscription " << subscription->reader()->guid() << " created on topic " << + subscription->reader()->get_topicdescription()->get_name(); + discovery_info.message(ss.str()); + discovery_info_pub_->writer()->write(&discovery_info); + } + } + + void notify_subscription_deletion( + const std::shared_ptr<DataReaderHolder>& subscription) + { + if (nullptr != discovery_info_pub_) + { + RosDiscoveryInfoPubSubType::type discovery_info; + std::stringstream ss; + ss << "Subscription " << subscription->reader()->guid() << " deleted on topic " << + subscription->reader()->get_topicdescription()->get_name(); + discovery_info.message(ss.str()); + discovery_info_pub_->writer()->write(&discovery_info); + } + } + + std::mutex mutex_; + std::shared_ptr<DomainParticipantFactory> factory_{}; + DomainParticipant* participant_ = nullptr; + Publisher* publisher_ = nullptr; + Subscriber* subscriber_ = nullptr; + std::map<std::string, std::shared_ptr<TopicHolder>> topics_{}; + std::shared_ptr<DataWriterHolder> discovery_info_pub_{}; + std::shared_ptr<DataReaderHolder> discovery_info_sub_{}; +}; + +} // namespace ros2 +} // namespace testing +} // namespace eprosima + +#endif // FASTDDS_TEST_BLACKBOX_COMMON_ROS2__CONTEXT_HPP diff --git a/test/blackbox/common/ros2/DataReaderHolder.hpp b/test/blackbox/common/ros2/DataReaderHolder.hpp new file mode 100644 index 00000000000..47b5af81cc1 --- /dev/null +++ b/test/blackbox/common/ros2/DataReaderHolder.hpp @@ -0,0 +1,38 @@ +// Copyright 2024 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef FASTDDS_TEST_BLACKBOX_COMMON_ROS2__DATAREADERHOLDER_HPP +#define FASTDDS_TEST_BLACKBOX_COMMON_ROS2__DATAREADERHOLDER_HPP + +#include <gtest/gtest.h> + +#include <fastdds/dds/core/detail/DDSReturnCode.hpp> +#include <fastdds/dds/subscriber/Subscriber.hpp> +#include <fastdds/dds/subscriber/DataReader.hpp> + +#include "./GenericHolder.hpp" + +namespace eprosima { +namespace testing { +namespace ros2 { + +using namespace eprosima::fastdds::dds; + +GENERIC_HOLDER_CLASS(Subscriber, DataReader, delete_datareader, reader) + +} // namespace ros2 +} // namespace testing +} // namespace eprosima + +#endif // FASTDDS_TEST_BLACKBOX_COMMON_ROS2__DATAREADERHOLDER_HPP diff --git a/test/blackbox/common/ros2/DataWriterHolder.hpp b/test/blackbox/common/ros2/DataWriterHolder.hpp new file mode 100644 index 00000000000..60a52df9ad9 --- /dev/null +++ b/test/blackbox/common/ros2/DataWriterHolder.hpp @@ -0,0 +1,38 @@ +// Copyright 2024 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef FASTDDS_TEST_BLACKBOX_COMMON_ROS2__DATAWRITERHOLDER_HPP +#define FASTDDS_TEST_BLACKBOX_COMMON_ROS2__DATAWRITERHOLDER_HPP + +#include <gtest/gtest.h> + +#include <fastdds/dds/core/detail/DDSReturnCode.hpp> +#include <fastdds/dds/publisher/Publisher.hpp> +#include <fastdds/dds/publisher/DataWriter.hpp> + +#include "./GenericHolder.hpp" + +namespace eprosima { +namespace testing { +namespace ros2 { + +using namespace eprosima::fastdds::dds; + +GENERIC_HOLDER_CLASS(Publisher, DataWriter, delete_datawriter, writer) + +} // namespace ros2 +} // namespace testing +} // namespace eprosima + +#endif // FASTDDS_TEST_BLACKBOX_COMMON_ROS2__DATAWRITERHOLDER_HPP diff --git a/test/blackbox/common/ros2/GenericHolder.hpp b/test/blackbox/common/ros2/GenericHolder.hpp new file mode 100644 index 00000000000..ffa93e07da8 --- /dev/null +++ b/test/blackbox/common/ros2/GenericHolder.hpp @@ -0,0 +1,77 @@ +// Copyright 2024 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef FASTDDS_TEST_BLACKBOX_COMMON_ROS2__GENERICHOLDER_HPP +#define FASTDDS_TEST_BLACKBOX_COMMON_ROS2__GENERICHOLDER_HPP + +#include <fastdds/dds/core/detail/DDSReturnCode.hpp> + +#include <gtest/gtest.h> + +// *INDENT-OFF* Uncrustify makes a mess with this kind of macros +/** + * @brief Generic holder class for a DDS entity. + * This macro generates a holder class for a DDS entity along with it's factory so that the entity is automatically + * released when the holder is destroyed. + * The generated class has a custom-named getter method to access the entity. + * The macro allows to specify the factory class, the entity class, the factory's method to release the entity and the + * getter method name. + * + * @param _Factory The class of the factory that created the entity (e.g. Publisher). + * @param _Entity The class of the entity (e.g., DataWriter). + * @param _Release The method of the factory to release the entity (e.g., delete_datawriter). + * @param _Getter The name of the getter method to access the entity (for instance, writer). + * + * Examples: + * GENERIC_HOLDER_CLASS(Publisher, DataWriter, delete_datawriter, writer) generates DataWriterHolder. + * GENERIC_HOLDER_CLASS(Subscriber, DataReader, delete_datareader, reader) generates DataReaderHolder. + * GENERIC_HOLDER_CLASS(DomainParticipant, Publisher, delete_publisher, publisher) generates PublisherHolder. + * GENERIC_HOLDER_CLASS(DomainParticipant, Subscriber, delete_subscriber, subscriber) generates SubscriberHolder. + * GENERIC_HOLDER_CLASS(DomainParticipant, Topic, delete_topic, topic) generates TopicHolder. + * GENERIC_HOLDER_CLASS(DomainParticipantFactory, DomainParticipant, delete_participant, participant) generates DomainParticipantHolder. + */ +#define GENERIC_HOLDER_CLASS(_Factory, _Entity, _Release, _Getter) \ +class _Entity##Holder \ +{ \ +public: \ + _Entity##Holder( \ + _Factory* factory, \ + _Entity* entity) \ + : factory_(factory) \ + , entity_(entity) \ + { \ + } \ + \ + ~_Entity##Holder() \ + { \ + if (nullptr != factory_ && nullptr != entity_) \ + { \ + EXPECT_EQ(RETCODE_OK, factory_->_Release(entity_)); \ + } \ + } \ + \ + _Entity* _Getter() \ + { \ + return entity_; \ + } \ + \ +private: \ + \ + _Factory* factory_ = nullptr; \ + _Entity* entity_ = nullptr; \ + \ +}; +// *INDENT-ON* + +#endif // FASTDDS_TEST_BLACKBOX_COMMON_ROS2__GENERICHOLDER_HPP diff --git a/test/blackbox/common/ros2/Node.hpp b/test/blackbox/common/ros2/Node.hpp new file mode 100644 index 00000000000..57146a43c5b --- /dev/null +++ b/test/blackbox/common/ros2/Node.hpp @@ -0,0 +1,204 @@ +// Copyright 2024 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef FASTDDS_TEST_BLACKBOX_COMMON_ROS2__NODE_HPP +#define FASTDDS_TEST_BLACKBOX_COMMON_ROS2__NODE_HPP + +#include <memory> +#include <mutex> +#include <string> +#include <vector> + +#include "./Context.hpp" +#include "./DataReaderHolder.hpp" +#include "./DataWriterHolder.hpp" +#include "./TopicHolder.hpp" +#include "../../types/HelloWorldPubSubTypes.hpp" +#include <fastdds/dds/core/policy/QosPolicies.hpp> +#include <fastdds/dds/topic/TypeSupport.hpp> + +namespace eprosima { +namespace testing { +namespace ros2 { + +using namespace eprosima::fastdds::dds; + +class Node +{ + using BuiltinPubSubType = HelloWorldPubSubType; + +public: + + Node( + const std::shared_ptr<Context>& context, + const std::string& node_name) + : context_(context) + , node_name_(node_name) + { + } + + virtual ~Node() = default; + + void start() + { + std::lock_guard<std::mutex> _(mutex_); + + if (started_) + { + return; + } + + started_ = true; + create_builtin(); + do_start(); + } + + void stop() + { + std::lock_guard<std::mutex> _(mutex_); + + if (!started_) + { + return; + } + + started_ = false; + do_stop(); + destroy_builtin(); + } + +protected: + + std::shared_ptr<Context> context_{}; + std::string node_name_{}; + + mutable std::mutex mutex_{}; + bool started_ = false; + + virtual void do_start() = 0; + + virtual void do_stop() = 0; + +private: + + enum class EndpointKind + { + PUB_ONLY, + SUB_ONLY, + PUB_AND_SUB + }; + + void create_builtin() + { + create_rosout_pub(); + // "rt/rosout", "rcl_interfaces::msg::dds_::Log_", KEEP_LAST(1000), RELIABLE, TRANSIENT_LOCAL, WRITER_ONLY + create_parameters_server(); + create_type_description_server(); + } + + void create_rosout_pub() + { + create_builtin_topic("rt/rosout", "rcl_interfaces::msg::dds_::Log_", + RELIABLE_RELIABILITY_QOS, TRANSIENT_LOCAL_DURABILITY_QOS, EndpointKind::PUB_ONLY); + } + + void create_parameters_server() + { + create_service("get_parameters", "rcl_interfaces::srv::dds_::GetParameters"); + create_service("get_parameter_types", "rcl_interfaces::srv::dds_::GetParameterTypes"); + create_service("set_parameters", "rcl_interfaces::srv::dds_::SetParameters"); + create_service("set_parameters_atomically", "rcl_interfaces::srv::dds_::SetParametersAtomically"); + create_service("describe_parameters", "rcl_interfaces::srv::dds_::DescribeParameters"); + create_service("list_parameters", "rcl_interfaces::srv::dds_::ListParameters"); + create_builtin_topic("rt/parameter_events", "rcl_interfaces::msg::dds_::ParameterEvent_", + RELIABLE_RELIABILITY_QOS, VOLATILE_DURABILITY_QOS, EndpointKind::PUB_AND_SUB); + } + + void create_type_description_server() + { + create_service("get_type_description", "type_description_interfaces::srv::dds_::GetTypeDescription"); + } + + void create_service( + const std::string& service_name, + const std::string& service_type) + { + create_builtin_topic("rq/" + node_name_ + "/" + service_name + "Request", service_type + "_Request_", + RELIABLE_RELIABILITY_QOS, VOLATILE_DURABILITY_QOS, EndpointKind::SUB_ONLY); + create_builtin_topic("rr/" + node_name_ + "/" + service_name + "Reply", service_type + "_Response_", + RELIABLE_RELIABILITY_QOS, VOLATILE_DURABILITY_QOS, EndpointKind::PUB_ONLY); + } + + void create_builtin_topic( + const std::string& topic_name, + const std::string& type_name, + ReliabilityQosPolicyKind reliability, + DurabilityQosPolicyKind durability, + EndpointKind kind) + { + TypeSupport type_support(new BuiltinPubSubType()); + std::shared_ptr<TopicHolder> topic_holder; + context_->create_topic(topic_holder, topic_name, type_name, type_support); + if (kind == EndpointKind::PUB_ONLY || kind == EndpointKind::PUB_AND_SUB) + { + DataWriterQos qos = context_->publisher()->get_default_datawriter_qos(); + qos.reliability().kind = reliability; + qos.durability().kind = durability; + qos.history().kind = KEEP_LAST_HISTORY_QOS; + qos.history().depth = 1000; + std::shared_ptr<DataWriterHolder> writer; + context_->create_publication(writer, topic_holder, qos, nullptr, true); + builtin_writers_.push_back(writer); + } + if (kind == EndpointKind::SUB_ONLY || kind == EndpointKind::PUB_AND_SUB) + { + DataReaderQos qos = context_->subscriber()->get_default_datareader_qos(); + qos.reliability().kind = reliability; + qos.durability().kind = durability; + qos.history().kind = KEEP_LAST_HISTORY_QOS; + qos.history().depth = 1000; + std::shared_ptr<DataReaderHolder> reader; + context_->create_subscription(reader, topic_holder, qos, nullptr, true); + builtin_readers_.push_back(reader); + } + builtin_topics_.push_back(topic_holder); + } + + void destroy_builtin() + { + for (auto& reader : builtin_readers_) + { + context_->delete_subscription(reader); + } + builtin_readers_.clear(); + + for (auto& writer : builtin_writers_) + { + context_->delete_publication(writer); + } + builtin_writers_.clear(); + + builtin_topics_.clear(); + } + + std::vector<std::shared_ptr<DataReaderHolder>> builtin_readers_; + std::vector<std::shared_ptr<DataWriterHolder>> builtin_writers_; + std::vector<std::shared_ptr<TopicHolder>> builtin_topics_; +}; + +} // namespace ros2 +} // namespace testing +} // namespace eprosima + +#endif // FASTDDS_TEST_BLACKBOX_COMMON_ROS2__NODE_HPP diff --git a/test/blackbox/common/ros2/PublicationNode.hpp b/test/blackbox/common/ros2/PublicationNode.hpp new file mode 100644 index 00000000000..a2d6632369c --- /dev/null +++ b/test/blackbox/common/ros2/PublicationNode.hpp @@ -0,0 +1,123 @@ +// Copyright 2024 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef FASTDDS_TEST_BLACKBOX_COMMON_ROS2__PUBLICATIONNODE_HPP +#define FASTDDS_TEST_BLACKBOX_COMMON_ROS2__PUBLICATIONNODE_HPP + +#include <cstdint> +#include <memory> +#include <mutex> +#include <string> + +#include <gtest/gtest.h> + +#include <fastdds/dds/core/detail/DDSReturnCode.hpp> +#include <fastdds/dds/core/policy/QosPolicies.hpp> +#include <fastdds/dds/publisher/DataWriter.hpp> +#include <fastdds/dds/publisher/DataWriterListener.hpp> +#include <fastdds/dds/publisher/Publisher.hpp> +#include <fastdds/dds/publisher/qos/DataWriterQos.hpp> +#include <fastdds/dds/topic/Topic.hpp> +#include <fastdds/dds/topic/TypeSupport.hpp> + +#include "./Context.hpp" +#include "./DataWriterHolder.hpp" +#include "./Node.hpp" +#include "./TopicHolder.hpp" + +namespace eprosima { +namespace testing { +namespace ros2 { + +using namespace eprosima::fastdds::dds; + +struct PublicationListener : public DataWriterListener +{ +}; + +struct PublicationNode : public Node +{ + PublicationNode( + const std::shared_ptr<Context>& context, + const std::string& node_name, + const std::string& topic_name, + const TypeSupport& type_support) + : Node(context, node_name) + , topic_name_(topic_name) + , type_support_(type_support) + , qos_(context->publisher()->get_default_datawriter_qos()) + { + } + + ~PublicationNode() override + { + stop(); + } + + void set_qos( + const DataWriterQos& qos) + { + qos_ = qos; + } + + void publish( + void* data) + { + std::lock_guard<std::mutex> _(mutex_); + + if (!started_) + { + return; + } + + if (!publication_) + { + std::cout << "Publication not created yet" << std::endl; + return; + } + + auto writer = publication_->writer(); + ASSERT_NE(nullptr, writer); + writer->write(data); + } + +protected: + + void do_start() override + { + context_->create_topic(topic_holder_, topic_name_, type_support_.get_type_name(), type_support_); + context_->create_publication(publication_, topic_holder_, qos_, listener_.get()); + ASSERT_NE(nullptr, publication_); + } + + void do_stop() override + { + context_->delete_publication(publication_); + publication_.reset(); + topic_holder_.reset(); + } + + std::string topic_name_{}; + TypeSupport type_support_{}; + DataWriterQos qos_{}; + std::shared_ptr<TopicHolder> topic_holder_{}; + std::shared_ptr<PublicationListener> listener_ = std::make_shared<PublicationListener>(); + std::shared_ptr<DataWriterHolder> publication_{}; +}; + +} // namespace ros2 +} // namespace testing +} // namespace eprosima + +#endif // FASTDDS_TEST_BLACKBOX_COMMON_ROS2__PUBLICATIONNODE_HPP diff --git a/test/blackbox/common/ros2/SubscriptionNode.hpp b/test/blackbox/common/ros2/SubscriptionNode.hpp new file mode 100644 index 00000000000..43b5941f981 --- /dev/null +++ b/test/blackbox/common/ros2/SubscriptionNode.hpp @@ -0,0 +1,122 @@ +// Copyright 2024 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef FASTDDS_TEST_BLACKBOX_COMMON_ROS2__SUBSCRIPTIONNODE_HPP +#define FASTDDS_TEST_BLACKBOX_COMMON_ROS2__SUBSCRIPTIONNODE_HPP + +#include <cstdint> +#include <functional> +#include <memory> +#include <mutex> +#include <string> + +#include <gtest/gtest.h> + +#include <fastdds/dds/core/detail/DDSReturnCode.hpp> +#include <fastdds/dds/core/policy/QosPolicies.hpp> +#include <fastdds/dds/core/status/LivelinessChangedStatus.hpp> +#include <fastdds/dds/subscriber/DataReader.hpp> +#include <fastdds/dds/subscriber/DataReaderListener.hpp> +#include <fastdds/dds/subscriber/qos/DataReaderQos.hpp> +#include <fastdds/dds/subscriber/Subscriber.hpp> +#include <fastdds/dds/topic/Topic.hpp> +#include <fastdds/dds/topic/TypeSupport.hpp> + +#include "./Context.hpp" +#include "./DataReaderHolder.hpp" +#include "./Node.hpp" +#include "./TopicHolder.hpp" + +namespace eprosima { +namespace testing { +namespace ros2 { + +using namespace eprosima::fastdds::dds; + +struct SubscriptionListener : public DataReaderListener +{ + void on_liveliness_changed( + DataReader* reader, + const LivelinessChangedStatus& status) override + { + static_cast<void>(reader); + + if (liveliness_callback) + { + liveliness_callback(status); + } + } + + std::function<void(const LivelinessChangedStatus&)> liveliness_callback; +}; + +struct SubscriptionNode : public Node +{ + SubscriptionNode( + const std::shared_ptr<Context>& context, + const std::string& node_name, + const std::string& topic_name, + const TypeSupport& type_support) + : Node(context, node_name) + , topic_name_(topic_name) + , type_support_(type_support) + , qos_(context->subscriber()->get_default_datareader_qos()) + { + } + + ~SubscriptionNode() override + { + stop(); + } + + void set_listener( + const std::shared_ptr<SubscriptionListener>& listener) + { + listener_ = listener; + } + + void set_qos( + const DataReaderQos& qos) + { + qos_ = qos; + } + +protected: + + void do_start() override + { + context_->create_topic(topic_holder_, topic_name_, type_support_.get_type_name(), type_support_); + context_->create_subscription(subscription_, topic_holder_, qos_, listener_.get()); + } + + void do_stop() override + { + context_->delete_subscription(subscription_); + subscription_.reset(); + topic_holder_.reset(); + } + + std::string topic_name_{}; + TypeSupport type_support_{}; + DataReaderQos qos_{}; + std::shared_ptr<TopicHolder> topic_holder_{}; + std::shared_ptr<SubscriptionListener> listener_ = std::make_shared<SubscriptionListener>(); + std::shared_ptr<DataReaderHolder> subscription_{}; +}; + +} // namespace ros2 +} // namespace testing +} // namespace eprosima + +#endif // FASTDDS_TEST_BLACKBOX_COMMON_ROS2__SUBSCRIPTIONNODE_HPP diff --git a/test/blackbox/common/ros2/TopicHolder.hpp b/test/blackbox/common/ros2/TopicHolder.hpp new file mode 100644 index 00000000000..13e206ef8b2 --- /dev/null +++ b/test/blackbox/common/ros2/TopicHolder.hpp @@ -0,0 +1,38 @@ +// Copyright 2024 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef FASTDDS_TEST_BLACKBOX_COMMON_ROS2__TOPICHOLDER_HPP +#define FASTDDS_TEST_BLACKBOX_COMMON_ROS2__TOPICHOLDER_HPP + +#include <gtest/gtest.h> + +#include <fastdds/dds/core/detail/DDSReturnCode.hpp> +#include <fastdds/dds/domain/DomainParticipant.hpp> +#include <fastdds/dds/topic/Topic.hpp> + +#include "./GenericHolder.hpp" + +namespace eprosima { +namespace testing { +namespace ros2 { + +using namespace eprosima::fastdds::dds; + +GENERIC_HOLDER_CLASS(DomainParticipant, Topic, delete_topic, topic) + +} // namespace ros2 +} // namespace testing +} // namespace eprosima + +#endif // FASTDDS_TEST_BLACKBOX_COMMON_ROS2__TOPICHOLDER_HPP From 8c0beb26ed30e7814248743ef7468ccfeedbad0c Mon Sep 17 00:00:00 2001 From: Miguel Company <miguelcompany@eprosima.com> Date: Fri, 5 Jul 2024 07:29:58 +0200 Subject: [PATCH 2/3] Fix conflicts Signed-off-by: Miguel Company <miguelcompany@eprosima.com> --- src/cpp/rtps/reader/StatefulReader.cpp | 39 +------------------ src/cpp/rtps/reader/StatelessReader.cpp | 22 +---------- .../common/BlackboxTestsLivelinessQos.cpp | 7 +--- 3 files changed, 6 insertions(+), 62 deletions(-) diff --git a/src/cpp/rtps/reader/StatefulReader.cpp b/src/cpp/rtps/reader/StatefulReader.cpp index 2fc3e364f33..3c53ea19efd 100644 --- a/src/cpp/rtps/reader/StatefulReader.cpp +++ b/src/cpp/rtps/reader/StatefulReader.cpp @@ -373,40 +373,6 @@ bool StatefulReader::matched_writer_remove( const GUID_t& writer_guid, bool removed_by_lease) { -<<<<<<< HEAD - - if (is_alive_ && liveliness_lease_duration_ < c_TimeInfinite) - { - auto wlp = this->mp_RTPSParticipant->wlp(); - if ( wlp != nullptr) - { - LivelinessData::WriterStatus writer_liveliness_status; - wlp->sub_liveliness_manager_->remove_writer( - writer_guid, - liveliness_kind_, - liveliness_lease_duration_, - writer_liveliness_status); - - if (writer_liveliness_status == LivelinessData::WriterStatus::ALIVE) - { - wlp->update_liveliness_changed_status(writer_guid, this, -1, 0); - } - else if (writer_liveliness_status == LivelinessData::WriterStatus::NOT_ALIVE) - { - wlp->update_liveliness_changed_status(writer_guid, this, 0, -1); - } - - } - else - { - EPROSIMA_LOG_ERROR(RTPS_LIVELINESS, - "Finite liveliness lease duration but WLP not enabled, cannot remove writer"); - } - } - - std::unique_lock<RecursiveTimedMutex> lock(mp_mutex); -======= ->>>>>>> 9243eadae (Fix topic interference on `liveliness_changed` status (#4988)) WriterProxy* wproxy = nullptr; if (is_alive_) { @@ -488,13 +454,12 @@ bool StatefulReader::matched_writer_remove( if (writer_liveliness_status == LivelinessData::WriterStatus::ALIVE) { - update_liveliness_changed_status(writer_guid, -1, 0); + wlp->update_liveliness_changed_status(writer_guid, this, -1, 0); } else if (writer_liveliness_status == LivelinessData::WriterStatus::NOT_ALIVE) { - update_liveliness_changed_status(writer_guid, 0, -1); + wlp->update_liveliness_changed_status(writer_guid, this, 0, -1); } - } else { diff --git a/src/cpp/rtps/reader/StatelessReader.cpp b/src/cpp/rtps/reader/StatelessReader.cpp index 4c1326cf370..7eda0ff2057 100644 --- a/src/cpp/rtps/reader/StatelessReader.cpp +++ b/src/cpp/rtps/reader/StatelessReader.cpp @@ -225,24 +225,6 @@ bool StatelessReader::matched_writer_remove( { bool ret_val = false; -<<<<<<< HEAD - if (writer_liveliness_status == LivelinessData::WriterStatus::ALIVE) - { - wlp->update_liveliness_changed_status(writer_guid, this, -1, 0); - } - else if (writer_liveliness_status == LivelinessData::WriterStatus::NOT_ALIVE) - { - wlp->update_liveliness_changed_status(writer_guid, this, 0, -1); - } - } - else - { - EPROSIMA_LOG_ERROR(RTPS_LIVELINESS, - "Finite liveliness lease duration but WLP not enabled, cannot remove writer"); - } - } -======= ->>>>>>> 9243eadae (Fix topic interference on `liveliness_changed` status (#4988)) { std::unique_lock<RecursiveTimedMutex> guard(mp_mutex); @@ -302,11 +284,11 @@ bool StatelessReader::matched_writer_remove( if (writer_liveliness_status == LivelinessData::WriterStatus::ALIVE) { - update_liveliness_changed_status(writer_guid, -1, 0); + wlp->update_liveliness_changed_status(writer_guid, this, -1, 0); } else if (writer_liveliness_status == LivelinessData::WriterStatus::NOT_ALIVE) { - update_liveliness_changed_status(writer_guid, 0, -1); + wlp->update_liveliness_changed_status(writer_guid, this, 0, -1); } } else diff --git a/test/blackbox/common/BlackboxTestsLivelinessQos.cpp b/test/blackbox/common/BlackboxTestsLivelinessQos.cpp index 70a63ea133b..5d71425a5d8 100644 --- a/test/blackbox/common/BlackboxTestsLivelinessQos.cpp +++ b/test/blackbox/common/BlackboxTestsLivelinessQos.cpp @@ -12,12 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -<<<<<<< HEAD #include "BlackboxTests.hpp" -======= #include <string> ->>>>>>> 9243eadae (Fix topic interference on `liveliness_changed` status (#4988)) #include <thread> #include "PubSubReader.hpp" @@ -2058,8 +2055,8 @@ static void test_liveliness_qos_independent_topics( eprosima::fastdds::dds::ReliabilityQosPolicyKind reliability_kind) { const auto lease_dutation_time = std::chrono::seconds(1); - const eprosima::fastdds::Duration_t lease_duration(1, 0); - const eprosima::fastdds::Duration_t announcement_period(0, 250000000); + const eprosima::fastrtps::Duration_t lease_duration(1, 0); + const eprosima::fastrtps::Duration_t announcement_period(0, 250000000); PubSubReader<HelloWorldPubSubType> reader1(topic_name + "1"); PubSubReader<HelloWorldPubSubType> reader2(topic_name + "2"); From 856c8f3f465a06799818cdb8d94e6f7951c6529a Mon Sep 17 00:00:00 2001 From: Miguel Company <miguelcompany@eprosima.com> Date: Fri, 5 Jul 2024 09:39:48 +0200 Subject: [PATCH 3/3] Fix build after backport. Signed-off-by: Miguel Company <miguelcompany@eprosima.com> --- .../common/BlackboxTestsLivelinessQos.cpp | 24 +++---- test/blackbox/common/DDSBlackboxTestsROS2.cpp | 22 ++++--- test/blackbox/common/ros2/Context.hpp | 8 +-- .../blackbox/common/ros2/DataReaderHolder.hpp | 2 +- .../blackbox/common/ros2/DataWriterHolder.hpp | 2 +- test/blackbox/common/ros2/GenericHolder.hpp | 62 +++++++++---------- test/blackbox/common/ros2/Node.hpp | 2 +- test/blackbox/common/ros2/PublicationNode.hpp | 2 +- .../blackbox/common/ros2/SubscriptionNode.hpp | 2 +- test/blackbox/common/ros2/TopicHolder.hpp | 2 +- 10 files changed, 66 insertions(+), 62 deletions(-) diff --git a/test/blackbox/common/BlackboxTestsLivelinessQos.cpp b/test/blackbox/common/BlackboxTestsLivelinessQos.cpp index 5d71425a5d8..4d17d8b5f7a 100644 --- a/test/blackbox/common/BlackboxTestsLivelinessQos.cpp +++ b/test/blackbox/common/BlackboxTestsLivelinessQos.cpp @@ -2100,13 +2100,13 @@ static void test_liveliness_qos_independent_topics( // Check liveliness changed status on both readers { - auto liveliness = reader1.get_liveliness_changed_status(); + auto liveliness = reader1.liveliness_changed_status(); EXPECT_EQ(liveliness.alive_count, 1); EXPECT_EQ(liveliness.not_alive_count, 0); } { - auto liveliness = reader2.get_liveliness_changed_status(); + auto liveliness = reader2.liveliness_changed_status(); EXPECT_EQ(liveliness.alive_count, 0); EXPECT_EQ(liveliness.not_alive_count, 0); } @@ -2117,13 +2117,13 @@ static void test_liveliness_qos_independent_topics( // Check liveliness changed status on both readers { - auto liveliness = reader1.get_liveliness_changed_status(); + auto liveliness = reader1.liveliness_changed_status(); EXPECT_EQ(liveliness.alive_count, 1); EXPECT_EQ(liveliness.not_alive_count, 0); } { - auto liveliness = reader2.get_liveliness_changed_status(); + auto liveliness = reader2.liveliness_changed_status(); EXPECT_EQ(liveliness.alive_count, 1); EXPECT_EQ(liveliness.not_alive_count, 0); } @@ -2134,13 +2134,13 @@ static void test_liveliness_qos_independent_topics( // Check liveliness changed status on both readers { - auto liveliness = reader1.get_liveliness_changed_status(); + auto liveliness = reader1.liveliness_changed_status(); EXPECT_EQ(liveliness.alive_count, 1); EXPECT_EQ(liveliness.not_alive_count, 0); } { - auto liveliness = reader2.get_liveliness_changed_status(); + auto liveliness = reader2.liveliness_changed_status(); EXPECT_EQ(liveliness.alive_count, 0); EXPECT_EQ(liveliness.not_alive_count, 0); } @@ -2153,13 +2153,13 @@ static void test_liveliness_qos_independent_topics( // Check liveliness changed status on both readers { - auto liveliness = reader1.get_liveliness_changed_status(); + auto liveliness = reader1.liveliness_changed_status(); EXPECT_EQ(liveliness.alive_count, 1); EXPECT_EQ(liveliness.not_alive_count, 0); } { - auto liveliness = reader2.get_liveliness_changed_status(); + auto liveliness = reader2.liveliness_changed_status(); EXPECT_EQ(liveliness.alive_count, 1); EXPECT_EQ(liveliness.not_alive_count, 0); } @@ -2170,13 +2170,13 @@ static void test_liveliness_qos_independent_topics( // Check liveliness changed status on both readers { - auto liveliness = reader1.get_liveliness_changed_status(); + auto liveliness = reader1.liveliness_changed_status(); EXPECT_EQ(liveliness.alive_count, 0); EXPECT_EQ(liveliness.not_alive_count, 0); } { - auto liveliness = reader2.get_liveliness_changed_status(); + auto liveliness = reader2.liveliness_changed_status(); EXPECT_EQ(liveliness.alive_count, 1); EXPECT_EQ(liveliness.not_alive_count, 0); } @@ -2187,13 +2187,13 @@ static void test_liveliness_qos_independent_topics( // Check liveliness changed status on both readers { - auto liveliness = reader1.get_liveliness_changed_status(); + auto liveliness = reader1.liveliness_changed_status(); EXPECT_EQ(liveliness.alive_count, 0); EXPECT_EQ(liveliness.not_alive_count, 0); } { - auto liveliness = reader2.get_liveliness_changed_status(); + auto liveliness = reader2.liveliness_changed_status(); EXPECT_EQ(liveliness.alive_count, 0); EXPECT_EQ(liveliness.not_alive_count, 0); } diff --git a/test/blackbox/common/DDSBlackboxTestsROS2.cpp b/test/blackbox/common/DDSBlackboxTestsROS2.cpp index d04dfbc3005..43ea22f5032 100644 --- a/test/blackbox/common/DDSBlackboxTestsROS2.cpp +++ b/test/blackbox/common/DDSBlackboxTestsROS2.cpp @@ -23,7 +23,6 @@ #include <gtest/gtest.h> -#include <fastdds/dds/core/detail/DDSReturnCode.hpp> #include <fastdds/dds/core/policy/QosPolicies.hpp> #include <fastdds/dds/core/status/LivelinessChangedStatus.hpp> #include <fastdds/dds/domain/DomainParticipant.hpp> @@ -42,7 +41,10 @@ #include <fastdds/dds/topic/qos/TopicQos.hpp> #include <fastdds/dds/topic/Topic.hpp> #include <fastdds/dds/topic/TypeSupport.hpp> -#include <fastdds/rtps/common/Time_t.hpp> +#include <fastdds/rtps/common/Time_t.h> +#include <fastrtps/attributes/LibrarySettingsAttributes.h> +#include <fastrtps/types/TypesBase.h> +#include <fastrtps/xmlparser/XMLProfileManager.h> #include "./ros2/Context.hpp" #include "./ros2/DataReaderHolder.hpp" @@ -53,7 +55,7 @@ #include "./ros2/TopicHolder.hpp" #include "BlackboxTests.hpp" -#include "../types/HelloWorldPubSubTypes.hpp" +#include "../types/HelloWorldPubSubTypes.h" namespace eprosima { namespace fastdds { @@ -69,14 +71,16 @@ namespace ros2 = eprosima::testing::ros2; */ TEST(DDS_ROS2, test_automatic_liveliness_changed) { + using namespace eprosima::fastrtps; + // Force intraprocess - auto factory = DomainParticipantFactory::get_shared_instance(); - LibrarySettings old_library_settings; - factory->get_library_settings(old_library_settings); + LibrarySettingsAttributes old_library_settings; + old_library_settings = xmlparser::XMLProfileManager::library_settings(); + { - LibrarySettings library_settings; + LibrarySettingsAttributes library_settings; library_settings.intraprocess_delivery = IntraprocessDeliveryType::INTRAPROCESS_FULL; - factory->set_library_settings(library_settings); + xmlparser::XMLProfileManager::library_settings(library_settings); } { @@ -159,7 +163,7 @@ TEST(DDS_ROS2, test_automatic_liveliness_changed) sub->stop(); } - factory->set_library_settings(old_library_settings); + xmlparser::XMLProfileManager::library_settings(old_library_settings); } } // namespace dds diff --git a/test/blackbox/common/ros2/Context.hpp b/test/blackbox/common/ros2/Context.hpp index 7d1644d1f5c..3a467efa839 100644 --- a/test/blackbox/common/ros2/Context.hpp +++ b/test/blackbox/common/ros2/Context.hpp @@ -26,7 +26,6 @@ #include <gtest/gtest.h> -#include <fastdds/dds/core/detail/DDSReturnCode.hpp> #include <fastdds/dds/core/policy/QosPolicies.hpp> #include <fastdds/dds/core/status/LivelinessChangedStatus.hpp> #include <fastdds/dds/domain/DomainParticipant.hpp> @@ -45,13 +44,14 @@ #include <fastdds/dds/topic/qos/TopicQos.hpp> #include <fastdds/dds/topic/Topic.hpp> #include <fastdds/dds/topic/TypeSupport.hpp> -#include <fastdds/rtps/common/Time_t.hpp> +#include <fastdds/rtps/common/Time_t.h> +#include <fastrtps/types/TypesBase.h> #include "./DataReaderHolder.hpp" #include "./DataWriterHolder.hpp" #include "./TopicHolder.hpp" #include "../BlackboxTests.hpp" -#include "../../types/HelloWorldPubSubTypes.hpp" +#include "../../types/HelloWorldPubSubTypes.h" namespace eprosima { namespace testing { @@ -146,7 +146,7 @@ class Context topic_holder = topics_[topic_name]; if (!topic_holder) { - EXPECT_EQ(RETCODE_OK, type_support.register_type(participant_, type_name)); + EXPECT_EQ(ReturnCode_t::RETCODE_OK, type_support.register_type(participant_, type_name)); auto topic = participant_->create_topic("testing/" + topic_name, type_name, TOPIC_QOS_DEFAULT); ASSERT_NE(nullptr, topic); topic_holder = std::make_shared<TopicHolder>(participant_, topic); diff --git a/test/blackbox/common/ros2/DataReaderHolder.hpp b/test/blackbox/common/ros2/DataReaderHolder.hpp index 47b5af81cc1..548f8450b9f 100644 --- a/test/blackbox/common/ros2/DataReaderHolder.hpp +++ b/test/blackbox/common/ros2/DataReaderHolder.hpp @@ -17,9 +17,9 @@ #include <gtest/gtest.h> -#include <fastdds/dds/core/detail/DDSReturnCode.hpp> #include <fastdds/dds/subscriber/Subscriber.hpp> #include <fastdds/dds/subscriber/DataReader.hpp> +#include <fastrtps/types/TypesBase.h> #include "./GenericHolder.hpp" diff --git a/test/blackbox/common/ros2/DataWriterHolder.hpp b/test/blackbox/common/ros2/DataWriterHolder.hpp index 60a52df9ad9..8499a0d36a0 100644 --- a/test/blackbox/common/ros2/DataWriterHolder.hpp +++ b/test/blackbox/common/ros2/DataWriterHolder.hpp @@ -17,9 +17,9 @@ #include <gtest/gtest.h> -#include <fastdds/dds/core/detail/DDSReturnCode.hpp> #include <fastdds/dds/publisher/Publisher.hpp> #include <fastdds/dds/publisher/DataWriter.hpp> +#include <fastrtps/types/TypesBase.h> #include "./GenericHolder.hpp" diff --git a/test/blackbox/common/ros2/GenericHolder.hpp b/test/blackbox/common/ros2/GenericHolder.hpp index ffa93e07da8..2a449e83b9d 100644 --- a/test/blackbox/common/ros2/GenericHolder.hpp +++ b/test/blackbox/common/ros2/GenericHolder.hpp @@ -15,7 +15,7 @@ #ifndef FASTDDS_TEST_BLACKBOX_COMMON_ROS2__GENERICHOLDER_HPP #define FASTDDS_TEST_BLACKBOX_COMMON_ROS2__GENERICHOLDER_HPP -#include <fastdds/dds/core/detail/DDSReturnCode.hpp> +#include <fastrtps/types/TypesBase.h> #include <gtest/gtest.h> @@ -41,36 +41,36 @@ * GENERIC_HOLDER_CLASS(DomainParticipant, Topic, delete_topic, topic) generates TopicHolder. * GENERIC_HOLDER_CLASS(DomainParticipantFactory, DomainParticipant, delete_participant, participant) generates DomainParticipantHolder. */ -#define GENERIC_HOLDER_CLASS(_Factory, _Entity, _Release, _Getter) \ -class _Entity##Holder \ -{ \ -public: \ - _Entity##Holder( \ - _Factory* factory, \ - _Entity* entity) \ - : factory_(factory) \ - , entity_(entity) \ - { \ - } \ - \ - ~_Entity##Holder() \ - { \ - if (nullptr != factory_ && nullptr != entity_) \ - { \ - EXPECT_EQ(RETCODE_OK, factory_->_Release(entity_)); \ - } \ - } \ - \ - _Entity* _Getter() \ - { \ - return entity_; \ - } \ - \ -private: \ - \ - _Factory* factory_ = nullptr; \ - _Entity* entity_ = nullptr; \ - \ +#define GENERIC_HOLDER_CLASS(_Factory, _Entity, _Release, _Getter) \ +class _Entity##Holder \ +{ \ +public: \ + _Entity##Holder( \ + _Factory* factory, \ + _Entity* entity) \ + : factory_(factory) \ + , entity_(entity) \ + { \ + } \ + \ + ~_Entity##Holder() \ + { \ + if (nullptr != factory_ && nullptr != entity_) \ + { \ + EXPECT_EQ(ReturnCode_t::RETCODE_OK, factory_->_Release(entity_)); \ + } \ + } \ + \ + _Entity* _Getter() \ + { \ + return entity_; \ + } \ + \ +private: \ + \ + _Factory* factory_ = nullptr; \ + _Entity* entity_ = nullptr; \ + \ }; // *INDENT-ON* diff --git a/test/blackbox/common/ros2/Node.hpp b/test/blackbox/common/ros2/Node.hpp index 57146a43c5b..4cd9d870a9e 100644 --- a/test/blackbox/common/ros2/Node.hpp +++ b/test/blackbox/common/ros2/Node.hpp @@ -24,7 +24,7 @@ #include "./DataReaderHolder.hpp" #include "./DataWriterHolder.hpp" #include "./TopicHolder.hpp" -#include "../../types/HelloWorldPubSubTypes.hpp" +#include "../../types/HelloWorldPubSubTypes.h" #include <fastdds/dds/core/policy/QosPolicies.hpp> #include <fastdds/dds/topic/TypeSupport.hpp> diff --git a/test/blackbox/common/ros2/PublicationNode.hpp b/test/blackbox/common/ros2/PublicationNode.hpp index a2d6632369c..388f05bb58d 100644 --- a/test/blackbox/common/ros2/PublicationNode.hpp +++ b/test/blackbox/common/ros2/PublicationNode.hpp @@ -22,7 +22,6 @@ #include <gtest/gtest.h> -#include <fastdds/dds/core/detail/DDSReturnCode.hpp> #include <fastdds/dds/core/policy/QosPolicies.hpp> #include <fastdds/dds/publisher/DataWriter.hpp> #include <fastdds/dds/publisher/DataWriterListener.hpp> @@ -30,6 +29,7 @@ #include <fastdds/dds/publisher/qos/DataWriterQos.hpp> #include <fastdds/dds/topic/Topic.hpp> #include <fastdds/dds/topic/TypeSupport.hpp> +#include <fastrtps/types/TypesBase.h> #include "./Context.hpp" #include "./DataWriterHolder.hpp" diff --git a/test/blackbox/common/ros2/SubscriptionNode.hpp b/test/blackbox/common/ros2/SubscriptionNode.hpp index 43b5941f981..2943dd66e55 100644 --- a/test/blackbox/common/ros2/SubscriptionNode.hpp +++ b/test/blackbox/common/ros2/SubscriptionNode.hpp @@ -23,7 +23,6 @@ #include <gtest/gtest.h> -#include <fastdds/dds/core/detail/DDSReturnCode.hpp> #include <fastdds/dds/core/policy/QosPolicies.hpp> #include <fastdds/dds/core/status/LivelinessChangedStatus.hpp> #include <fastdds/dds/subscriber/DataReader.hpp> @@ -32,6 +31,7 @@ #include <fastdds/dds/subscriber/Subscriber.hpp> #include <fastdds/dds/topic/Topic.hpp> #include <fastdds/dds/topic/TypeSupport.hpp> +#include <fastrtps/types/TypesBase.h> #include "./Context.hpp" #include "./DataReaderHolder.hpp" diff --git a/test/blackbox/common/ros2/TopicHolder.hpp b/test/blackbox/common/ros2/TopicHolder.hpp index 13e206ef8b2..0be359e1c51 100644 --- a/test/blackbox/common/ros2/TopicHolder.hpp +++ b/test/blackbox/common/ros2/TopicHolder.hpp @@ -17,9 +17,9 @@ #include <gtest/gtest.h> -#include <fastdds/dds/core/detail/DDSReturnCode.hpp> #include <fastdds/dds/domain/DomainParticipant.hpp> #include <fastdds/dds/topic/Topic.hpp> +#include <fastrtps/types/TypesBase.h> #include "./GenericHolder.hpp"