From 3721e60662a544f8eb7782b039a00762fa0e0d87 Mon Sep 17 00:00:00 2001 From: Mario Dominguez Date: Wed, 9 Oct 2024 10:12:32 +0200 Subject: [PATCH 1/6] Refs #21808: DataWriter/Reader get_matched_publication/subscription() Test implementation 3.x Signed-off-by: Mario Dominguez --- .../rtps/participant/RTPSParticipant.hpp | 24 ++ include/fastdds/rtps/reader/RTPSReader.hpp | 9 + include/fastdds/rtps/writer/RTPSWriter.hpp | 9 + .../api/dds-pim/PubSubParticipant.hpp | 12 + test/blackbox/api/dds-pim/PubSubReader.hpp | 2 +- test/blackbox/api/dds-pim/PubSubWriter.hpp | 2 +- test/blackbox/common/BlackboxTests.cpp | 31 ++ test/blackbox/common/BlackboxTests.hpp | 21 ++ .../common/BlackboxTestsDiscovery.cpp | 2 +- .../common/BlackboxTestsPubSubBasic.cpp | 6 +- .../blackbox/common/BlackboxTestsSecurity.cpp | 2 +- .../common/DDSBlackboxTestsDataReader.cpp | 283 +++++++++++++++++ .../common/DDSBlackboxTestsDataWriter.cpp | 290 ++++++++++++++++++ .../common/DDSBlackboxTestsPersistence.cpp | 4 +- test/blackbox/common/RTPSBlackboxTests.cpp | 31 ++ .../common/RTPSBlackboxTestsBasic.cpp | 164 ++++++++++ .../common/RTPSBlackboxTestsReader.cpp | 156 ++++++++++ .../common/RTPSBlackboxTestsWriter.cpp | 156 ++++++++++ .../common/RTPSWithRegistrationReader.hpp | 18 ++ .../common/RTPSWithRegistrationWriter.hpp | 23 ++ .../rtps/participant/RTPSParticipant.hpp | 10 + .../fastdds/rtps/reader/RTPSReader.hpp | 6 + .../fastdds/rtps/writer/RTPSWriter.hpp | 6 + 23 files changed, 1258 insertions(+), 9 deletions(-) create mode 100644 test/blackbox/common/RTPSBlackboxTestsReader.cpp create mode 100644 test/blackbox/common/RTPSBlackboxTestsWriter.cpp diff --git a/include/fastdds/rtps/participant/RTPSParticipant.hpp b/include/fastdds/rtps/participant/RTPSParticipant.hpp index 30f27ac906d..aaac3d1bcc8 100644 --- a/include/fastdds/rtps/participant/RTPSParticipant.hpp +++ b/include/fastdds/rtps/participant/RTPSParticipant.hpp @@ -291,6 +291,30 @@ class FASTDDS_EXPORTED_API RTPSParticipant */ std::vector get_netmask_filter_info() const; + /** + * @brief Fills the provided publication discovery data with the information of the + * writer identified by writer_guid. + * + * @param[out] data publication discovery data to fill. + * @param[in] writer_guid GUID of the writer to get the information from. + * @return True if the writer was found and the data was filled. + */ + bool get_publication_info( + fastdds::rtps::PublicationBuiltinTopicData& data, + const GUID_t& writer_guid) const; + + /** + * @brief Fills the provided subscription discovery data with the information of the + * reader identified by reader_guid. + * + * @param[out] data subscription discovery data to fill. + * @param[in] reader_guid GUID of the reader to get the information from. + * @return True if the reader was found and the data was filled. + */ + bool get_subscription_info( + fastdds::rtps::SubscriptionBuiltinTopicData& data, + const GUID_t& reader_guid) const; + #if HAVE_SECURITY /** diff --git a/include/fastdds/rtps/reader/RTPSReader.hpp b/include/fastdds/rtps/reader/RTPSReader.hpp index 467d8310d34..19628e6b32a 100644 --- a/include/fastdds/rtps/reader/RTPSReader.hpp +++ b/include/fastdds/rtps/reader/RTPSReader.hpp @@ -141,6 +141,15 @@ class RTPSReader : public Endpoint FASTDDS_EXPORTED_API virtual void set_content_filter( eprosima::fastdds::rtps::IReaderDataFilter* filter) = 0; + /** + * @brief Fills the provided vector with the GUIDs of the matched writers. + * + * @param[out] guids Vector to be filled with the GUIDs of the matched writers. + * @return True if the operation was successful. + */ + FASTDDS_EXPORTED_API virtual bool matched_writers_guids( + std::vector& guids) const = 0; + /** * @brief Read the next unread CacheChange_t from the history. * diff --git a/include/fastdds/rtps/writer/RTPSWriter.hpp b/include/fastdds/rtps/writer/RTPSWriter.hpp index 1bd409cacfd..b65635b7f7e 100644 --- a/include/fastdds/rtps/writer/RTPSWriter.hpp +++ b/include/fastdds/rtps/writer/RTPSWriter.hpp @@ -183,6 +183,15 @@ class RTPSWriter : public Endpoint */ FASTDDS_EXPORTED_API virtual bool get_disable_positive_acks() const = 0; + /** + * @brief Fills the provided vector with the GUIDs of the matched readers. + * + * @param[out] guids Vector to be filled with the GUIDs of the matched readers. + * @return True if the operation was successful. + */ + FASTDDS_EXPORTED_API virtual bool matched_readers_guids( + std::vector& guids) const = 0; + #ifdef FASTDDS_STATISTICS /** diff --git a/test/blackbox/api/dds-pim/PubSubParticipant.hpp b/test/blackbox/api/dds-pim/PubSubParticipant.hpp index 08ed7058866..4fcf93ff8db 100644 --- a/test/blackbox/api/dds-pim/PubSubParticipant.hpp +++ b/test/blackbox/api/dds-pim/PubSubParticipant.hpp @@ -340,6 +340,12 @@ class PubSubParticipant return false; } + if (publisher_topicname_.empty()) + { + EPROSIMA_LOG_ERROR(PUBSUBPARTICIPANT, "Publisher topic name not set"); + return false; + } + eprosima::fastdds::dds::Topic* topic = dynamic_cast(participant_->lookup_topicdescription( publisher_topicname_)); @@ -377,6 +383,12 @@ class PubSubParticipant return false; } + if (subscriber_topicname_.empty()) + { + EPROSIMA_LOG_ERROR(PUBSUBPARTICIPANT, "Subscriber topic name not set"); + return false; + } + eprosima::fastdds::dds::Topic* topic = dynamic_cast(participant_->lookup_topicdescription( subscriber_topicname_)); diff --git a/test/blackbox/api/dds-pim/PubSubReader.hpp b/test/blackbox/api/dds-pim/PubSubReader.hpp index b2257d83250..b7e267c1724 100644 --- a/test/blackbox/api/dds-pim/PubSubReader.hpp +++ b/test/blackbox/api/dds-pim/PubSubReader.hpp @@ -1464,7 +1464,7 @@ class PubSubReader return *this; } - PubSubReader& userData( + PubSubReader& user_data( std::vector user_data) { participant_qos_.user_data() = user_data; diff --git a/test/blackbox/api/dds-pim/PubSubWriter.hpp b/test/blackbox/api/dds-pim/PubSubWriter.hpp index 3dbe22f59b3..61bffb036b8 100644 --- a/test/blackbox/api/dds-pim/PubSubWriter.hpp +++ b/test/blackbox/api/dds-pim/PubSubWriter.hpp @@ -1404,7 +1404,7 @@ class PubSubWriter return *this; } - PubSubWriter& userData( + PubSubWriter& user_data( std::vector user_data) { participant_qos_.user_data() = user_data; diff --git a/test/blackbox/common/BlackboxTests.cpp b/test/blackbox/common/BlackboxTests.cpp index 167f1ac0b07..c8a407b2f9c 100644 --- a/test/blackbox/common/BlackboxTests.cpp +++ b/test/blackbox/common/BlackboxTests.cpp @@ -21,6 +21,7 @@ #include +#include #include #include #include @@ -86,6 +87,36 @@ class BlackboxEnvironment : public ::testing::Environment }; +void entity_id_to_builtin_topic_key( + eprosima::fastdds::rtps::BuiltinTopicKey_t& bt_key, + const eprosima::fastdds::rtps::EntityId_t& entity_id) +{ + bt_key.value[0] = 0; + bt_key.value[1] = 0; + bt_key.value[2] = static_cast(entity_id.value[0]) << 24 + | static_cast(entity_id.value[1]) << 16 + | static_cast(entity_id.value[2]) << 8 + | static_cast(entity_id.value[3]); +} + +void guid_prefix_to_builtin_topic_key( + eprosima::fastdds::rtps::BuiltinTopicKey_t& bt_key, + const eprosima::fastdds::rtps::GuidPrefix_t& guid_prefix) +{ + bt_key.value[0] = static_cast(guid_prefix.value[0]) << 24 + | static_cast(guid_prefix.value[1]) << 16 + | static_cast(guid_prefix.value[2]) << 8 + | static_cast(guid_prefix.value[3]); + bt_key.value[1] = static_cast(guid_prefix.value[4]) << 24 + | static_cast(guid_prefix.value[5]) << 16 + | static_cast(guid_prefix.value[6]) << 8 + | static_cast(guid_prefix.value[7]); + bt_key.value[2] = static_cast(guid_prefix.value[8]) << 24 + | static_cast(guid_prefix.value[9]) << 16 + | static_cast(guid_prefix.value[10]) << 8 + | static_cast(guid_prefix.value[11]); +} + int main( int argc, char** argv) diff --git a/test/blackbox/common/BlackboxTests.hpp b/test/blackbox/common/BlackboxTests.hpp index a44174cab67..5eae751b1b4 100644 --- a/test/blackbox/common/BlackboxTests.hpp +++ b/test/blackbox/common/BlackboxTests.hpp @@ -47,6 +47,16 @@ #include #include +namespace eprosima { +namespace fastdds { +namespace rtps { + +struct BuiltinTopicKey_t; + +} // namespace rtps +} // namespace fastdds +} // namespace eprosima + #if HAVE_SECURITY extern void blackbox_security_init(); #endif // if HAVE_SECURITY @@ -203,4 +213,15 @@ void print_non_received_messages( /***** End auxiliary lambda function *****/ +/****** Auxiliary conversion helpers *******/ +void entity_id_to_builtin_topic_key( + eprosima::fastdds::rtps::BuiltinTopicKey_t& bt_key, + const eprosima::fastdds::rtps::EntityId_t& entity_id); + +void guid_prefix_to_builtin_topic_key( + eprosima::fastdds::rtps::BuiltinTopicKey_t& bt_key, + const eprosima::fastdds::rtps::GuidPrefix_t& guid_prefix); + +/****** End Auxiliary conversion helpers *******/ + #endif // __BLACKBOX_BLACKBOXTESTS_HPP__ diff --git a/test/blackbox/common/BlackboxTestsDiscovery.cpp b/test/blackbox/common/BlackboxTestsDiscovery.cpp index ad8f29561ce..1123d338a9d 100644 --- a/test/blackbox/common/BlackboxTestsDiscovery.cpp +++ b/test/blackbox/common/BlackboxTestsDiscovery.cpp @@ -933,7 +933,7 @@ TEST_P(Discovery, PubSubAsReliableHelloworldUserData) PubSubWriter writer(TEST_TOPIC_NAME); writer.history_depth(100). - userData({'a', 'b', 'c', 'd'}).init(); + user_data({'a', 'b', 'c', 'd'}).init(); ASSERT_TRUE(writer.isInitialized()); diff --git a/test/blackbox/common/BlackboxTestsPubSubBasic.cpp b/test/blackbox/common/BlackboxTestsPubSubBasic.cpp index 9f2c1fff622..d62b7dccc47 100644 --- a/test/blackbox/common/BlackboxTestsPubSubBasic.cpp +++ b/test/blackbox/common/BlackboxTestsPubSubBasic.cpp @@ -384,7 +384,7 @@ TEST_P(PubSubBasic, ReceivedDynamicDataWithNoSizeLimit) writer.history_depth(100) .partition("A").partition("B").partition("C") - .userData({'a', 'b', 'c', 'd'}).init(); + .user_data({'a', 'b', 'c', 'd'}).init(); ASSERT_TRUE(writer.isInitialized()); @@ -417,7 +417,7 @@ TEST_P(PubSubBasic, ReceivedDynamicDataWithinSizeLimit) writer.history_depth(100) .partition("A").partition("B").partition("C") - .userData({'a', 'b', 'c', 'd'}).init(); + .user_data({'a', 'b', 'c', 'd'}).init(); ASSERT_TRUE(writer.isInitialized()); @@ -451,7 +451,7 @@ TEST_P(PubSubBasic, ReceivedUserDataExceedsSizeLimit) PubSubWriter writer(TEST_TOPIC_NAME); writer.history_depth(100) - .userData({'a', 'b', 'c', 'd', 'e', 'f'}).init(); + .user_data({'a', 'b', 'c', 'd', 'e', 'f'}).init(); ASSERT_TRUE(writer.isInitialized()); diff --git a/test/blackbox/common/BlackboxTestsSecurity.cpp b/test/blackbox/common/BlackboxTestsSecurity.cpp index 6dac5477660..18fc959a0d6 100644 --- a/test/blackbox/common/BlackboxTestsSecurity.cpp +++ b/test/blackbox/common/BlackboxTestsSecurity.cpp @@ -2705,7 +2705,7 @@ TEST_P(Security, BuiltinAuthenticationAndCryptoPlugin_user_data) pub_property_policy.properties().emplace_back("rtps.endpoint.payload_protection_kind", "ENCRYPT"); writer.history_depth(100). - userData({ 'a', 'b', 'c', 'd', 'e' }). + user_data({ 'a', 'b', 'c', 'd', 'e' }). property_policy(pub_part_property_policy). entity_property_policy(pub_property_policy).init(); diff --git a/test/blackbox/common/DDSBlackboxTestsDataReader.cpp b/test/blackbox/common/DDSBlackboxTestsDataReader.cpp index 5337576f7df..76e5bee9c6c 100644 --- a/test/blackbox/common/DDSBlackboxTestsDataReader.cpp +++ b/test/blackbox/common/DDSBlackboxTestsDataReader.cpp @@ -544,6 +544,289 @@ TEST(DDSDataReader, datareader_qos_use_topic_qos) ASSERT_EQ(control_qos, test_qos); } +bool validate_publication_builtin_topic_data( + const eprosima::fastdds::rtps::PublicationBuiltinTopicData& pubdata, + const eprosima::fastdds::dds::DataWriter& datawriter) +{ + bool ret = true; + + auto dw_qos = datawriter.get_qos(); + auto pub_qos = datawriter.get_publisher()->get_qos(); + + eprosima::fastdds::rtps::BuiltinTopicKey_t dw_key, part_key; + + entity_id_to_builtin_topic_key(dw_key, datawriter.guid().entityId); + guid_prefix_to_builtin_topic_key(part_key, datawriter.get_publisher()->get_participant()->guid().guidPrefix); + + ret &= (0 == memcmp(pubdata.key.value, dw_key.value, sizeof(eprosima::fastdds::rtps::BuiltinTopicKey_t))); + ret &= + (0 == + memcmp(pubdata.participant_key.value, part_key.value, + sizeof(eprosima::fastdds::rtps::BuiltinTopicKey_t))); + + ret &= (pubdata.topic_name.to_string() == datawriter.get_topic()->get_name()); + ret &= (pubdata.type_name.to_string() == datawriter.get_topic()->get_type_name()); + + // DataWriter Qos + ret &= (pubdata.durability == dw_qos.durability()); + ret &= (pubdata.durability_service == dw_qos.durability_service()); + ret &= (pubdata.deadline == dw_qos.deadline()); + ret &= (pubdata.latency_budget == dw_qos.latency_budget()); + ret &= (pubdata.liveliness == dw_qos.liveliness()); + ret &= (pubdata.reliability == dw_qos.reliability()); + ret &= (pubdata.lifespan == dw_qos.lifespan()); + ret &= ( + (pubdata.user_data.size() == dw_qos.user_data().size()) && + (0 == memcmp(pubdata.user_data.data(), dw_qos.user_data().data(), pubdata.user_data.size()))); + ret &= (pubdata.ownership == dw_qos.ownership()); + ret &= (pubdata.ownership_strength == dw_qos.ownership_strength()); + ret &= (pubdata.destination_order == dw_qos.destination_order()); + + // Publisher Qos + ret &= (pubdata.presentation == pub_qos.presentation()); + ret &= (pubdata.partition.getNames() == pub_qos.partition().getNames()); + // topic_data not implemented + // group_data too + + return ret; +} + +/** + * @test DDS-DR-API-GMPD-01 + * + * get_matched_publication_data() must return RETCODE_BAD_PARAMETER + * if the publication is not matched. + */ +TEST(DDSDataReader, datareader_get_matched_publication_data_bad_parameter) +{ + PubSubReader reader(TEST_TOPIC_NAME); + PubSubWriter writer_1(TEST_TOPIC_NAME); + PubSubWriter writer_2(TEST_TOPIC_NAME); + + eprosima::fastdds::rtps::PublicationBuiltinTopicData pubdata; + + reader.reliability(eprosima::fastdds::dds::RELIABLE_RELIABILITY_QOS) + .init(); + + writer_1.reliability(eprosima::fastdds::dds::BEST_EFFORT_RELIABILITY_QOS) + .init(); + writer_2.ownership_strength(10) + .init(); + + ASSERT_TRUE(reader.isInitialized()); + ASSERT_TRUE(writer_1.isInitialized()); + ASSERT_TRUE(writer_2.isInitialized()); + + // Reader should not be matched with any writer + reader.wait_discovery(std::chrono::seconds(2), 2); + + ASSERT_TRUE(!reader.is_matched()); + + auto& native_reader = reader.get_native_reader(); + + InstanceHandle_t w1_handle = writer_1.get_native_writer().get_instance_handle(); + ReturnCode_t ret = native_reader.get_matched_publication_data(pubdata, w1_handle); + + ASSERT_EQ(ret, eprosima::fastdds::dds::RETCODE_BAD_PARAMETER); + + InstanceHandle_t w2_handle = writer_2.get_native_writer().get_instance_handle(); + ret = native_reader.get_matched_publication_data(pubdata, w2_handle); + + ASSERT_EQ(ret, eprosima::fastdds::dds::RETCODE_BAD_PARAMETER); +} + +/** + * @test DDS-DR-API-GMPD-02 + * + * The operation must succeed when the publication is matched and correctly + * retrieve the publication data. Parameterize the test for different transports. + */ +TEST_P(DDSDataReader, datareader_get_matched_publication_data_correctly_behaves) +{ + PubSubReader reader(TEST_TOPIC_NAME); + PubSubWriter writer_1(TEST_TOPIC_NAME); + PubSubWriter writer_2(TEST_TOPIC_NAME); + + eprosima::fastdds::rtps::PublicationBuiltinTopicData w1_pubdata, w2_pubdata; + + reader.partition("*") + .init(); + + writer_1.partition("*") + .init(); + writer_2.user_data({'u', 's', 'e', 'r', 'd', 'a', 't', 'a'}) + .partition("*") + .reliability(eprosima::fastdds::dds::BEST_EFFORT_RELIABILITY_QOS) + .init(); + + ASSERT_TRUE(reader.isInitialized()); + ASSERT_TRUE(writer_1.isInitialized()); + ASSERT_TRUE(writer_2.isInitialized()); + + // Reader must match with both writers + reader.wait_discovery(std::chrono::seconds::zero(), 2); + + ASSERT_EQ(reader.get_matched(), 2u); + + auto& native_reader = reader.get_native_reader(); + + InstanceHandle_t w1_handle = writer_1.get_native_writer().get_instance_handle(); + ReturnCode_t ret = native_reader.get_matched_publication_data(w1_pubdata, w1_handle); + + ASSERT_EQ(ret, eprosima::fastdds::dds::RETCODE_OK); + ASSERT_TRUE(validate_publication_builtin_topic_data(w1_pubdata, writer_1.get_native_writer())); + + InstanceHandle_t w2_handle = writer_2.get_native_writer().get_instance_handle(); + ret = native_reader.get_matched_publication_data(w2_pubdata, w2_handle); + + ASSERT_EQ(ret, eprosima::fastdds::dds::RETCODE_OK); + ASSERT_TRUE(validate_publication_builtin_topic_data(w2_pubdata, writer_2.get_native_writer())); +} + +/** + * @test DDS-DR-API-GMP-01 + * + * get_matched_publications() must return RETCODE_OK + * with an empty list if no DataWriters are matched. + */ +TEST(DDSDataReader, datareader_get_matched_publications_ok_empty_list) +{ + PubSubReader reader(TEST_TOPIC_NAME); + PubSubWriter writer_1(TEST_TOPIC_NAME); + PubSubWriter writer_2(TEST_TOPIC_NAME); + + std::vector pub_handles; + + reader.reliability(eprosima::fastdds::dds::RELIABLE_RELIABILITY_QOS) + .init(); + + writer_1.reliability(eprosima::fastdds::dds::BEST_EFFORT_RELIABILITY_QOS) + .init(); + + writer_2.ownership_strength(10) + .init(); + + ASSERT_TRUE(reader.isInitialized()); + ASSERT_TRUE(writer_1.isInitialized()); + ASSERT_TRUE(writer_2.isInitialized()); + + // Reader should not be matched with any writer + reader.wait_discovery(std::chrono::seconds(2), 2); + ASSERT_FALSE(reader.is_matched()); + + auto& native_reader = reader.get_native_reader(); + ReturnCode_t ret = native_reader.get_matched_publications(pub_handles); + + ASSERT_EQ(ret, eprosima::fastdds::dds::RETCODE_OK); + ASSERT_EQ(pub_handles.size(), 0u); +} + +/** + * @test DDS-DR-API-GMP-02 + * + * get_matched_publications() must provide the correct list of matched publication handles. + * Parameterize the test for different transports. + */ +TEST_P(DDSDataReader, datareader_get_matched_publications_correctly_behaves) +{ + const size_t num_writers = 5; + + PubSubReader reader(TEST_TOPIC_NAME); + std::vector>> writers; + std::vector expected_pub_handles; + std::vector pub_handles; + + writers.reserve(num_writers); + pub_handles.reserve(num_writers); + + reader.reliability(eprosima::fastdds::dds::RELIABLE_RELIABILITY_QOS) + .init(); + + ASSERT_TRUE(reader.isInitialized()); + + for (size_t i = 0; i < num_writers; ++i) + { + writers.emplace_back(new PubSubWriter(TEST_TOPIC_NAME)); + writers.back()->init(); + ASSERT_TRUE(writers.back()->isInitialized()); + expected_pub_handles.emplace_back(writers.back()->get_native_writer().get_instance_handle()); + } + + // Wait for discovery + reader.wait_discovery(std::chrono::seconds::zero(), num_writers); + ASSERT_EQ(reader.get_matched(), num_writers); + + auto& native_reader = reader.get_native_reader(); + ReturnCode_t ret = native_reader.get_matched_publications(pub_handles); + + // Check that the list of matched publication handles is correct + ASSERT_EQ(ret, eprosima::fastdds::dds::RETCODE_OK); + ASSERT_EQ(pub_handles.size(), num_writers); + ASSERT_TRUE(std::is_permutation(pub_handles.begin(), pub_handles.end(), expected_pub_handles.begin())); + + // Remove two writers and check that the list of matched publication handles is updated + writers.pop_back(); + writers.pop_back(); + expected_pub_handles.pop_back(); + expected_pub_handles.pop_back(); + + // Wait for undiscovery + reader.wait_writer_undiscovery(static_cast(num_writers - 2)); + + pub_handles.clear(); + ret = native_reader.get_matched_publications(pub_handles); + ASSERT_EQ(ret, eprosima::fastdds::dds::RETCODE_OK); + ASSERT_EQ(pub_handles.size(), static_cast(num_writers - 2)); + ASSERT_TRUE(std::is_permutation(pub_handles.begin(), pub_handles.end(), expected_pub_handles.begin())); +} + +/** + * @test DDS-DR-API-GMP-03 + * + * The operation must provide the correct list of matched publication handles in multiple + * participants scenario. Parameterize the test for different transports. + */ +TEST_P(DDSDataReader, datareader_get_matched_publications_multiple_participants_correctly_behave) +{ + PubSubParticipant part_1(1, 1, 1, 1); + PubSubParticipant part_2(1, 1, 1, 1); + + part_1.pub_topic_name(TEST_TOPIC_NAME); + part_1.sub_topic_name(TEST_TOPIC_NAME + "_1"); + part_2.pub_topic_name(TEST_TOPIC_NAME + "_1"); + part_2.sub_topic_name(TEST_TOPIC_NAME); + + ASSERT_TRUE(part_1.init_participant()); + ASSERT_TRUE(part_1.init_publisher(0)); + ASSERT_TRUE(part_1.init_subscriber(0)); + + ASSERT_TRUE(part_2.init_participant()); + ASSERT_TRUE(part_2.init_subscriber(0)); + ASSERT_TRUE(part_2.init_publisher(0)); + + part_1.pub_wait_discovery(); + part_1.sub_wait_discovery(); + + part_2.pub_wait_discovery(); + part_2.sub_wait_discovery(); + + auto& reader_p1 = part_1.get_native_reader(0); + auto& reader_p2 = part_2.get_native_reader(0); + + std::vector pub_handles_p1; + std::vector pub_handles_p2; + + ReturnCode_t ret = reader_p1.get_matched_publications(pub_handles_p1); + ASSERT_EQ(ret, eprosima::fastdds::dds::RETCODE_OK); + ASSERT_EQ(pub_handles_p1.size(), 1u); + ASSERT_EQ(pub_handles_p1[0], part_2.get_native_writer(0).get_instance_handle()); + + ret = reader_p2.get_matched_publications(pub_handles_p2); + ASSERT_EQ(ret, eprosima::fastdds::dds::RETCODE_OK); + ASSERT_EQ(pub_handles_p2.size(), 1u); + ASSERT_EQ(pub_handles_p2[0], part_1.get_native_writer(0).get_instance_handle()); +} + #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/DDSBlackboxTestsDataWriter.cpp b/test/blackbox/common/DDSBlackboxTestsDataWriter.cpp index 08163a0091b..121c1e6d433 100644 --- a/test/blackbox/common/DDSBlackboxTestsDataWriter.cpp +++ b/test/blackbox/common/DDSBlackboxTestsDataWriter.cpp @@ -33,6 +33,7 @@ #include #include "BlackboxTests.hpp" +#include "PubSubParticipant.hpp" #include "PubSubReader.hpp" #include "PubSubWriter.hpp" @@ -531,6 +532,295 @@ TEST(DDSDataWriter, datawriter_qos_use_topic_qos) ASSERT_EQ(control_qos, test_qos); } +bool validate_subscription_builtin_topic_data( + const eprosima::fastdds::rtps::SubscriptionBuiltinTopicData& subdata, + const eprosima::fastdds::dds::DataReader& datareader) +{ + bool ret = true; + + auto dr_qos = datareader.get_qos(); + auto sub_qos = datareader.get_subscriber()->get_qos(); + + eprosima::fastdds::rtps::BuiltinTopicKey_t dr_key, part_key; + + entity_id_to_builtin_topic_key(dr_key, datareader.guid().entityId); + guid_prefix_to_builtin_topic_key(part_key, datareader.get_subscriber()->get_participant()->guid().guidPrefix); + + ret &= (0 == memcmp(subdata.key.value, dr_key.value, sizeof(eprosima::fastdds::rtps::BuiltinTopicKey_t))); + ret &= + (0 == + memcmp(subdata.participant_key.value, part_key.value, + sizeof(eprosima::fastdds::rtps::BuiltinTopicKey_t))); + ret &= (subdata.topic_name == datareader.get_topicdescription()->get_name()); + ret &= (subdata.type_name == datareader.get_topicdescription()->get_type_name()); + + // DataReader Qos + ret &= (subdata.durability == dr_qos.durability()); + ret &= (subdata.deadline == dr_qos.deadline()); + ret &= (subdata.latency_budget == dr_qos.latency_budget()); + ret &= (subdata.liveliness == dr_qos.liveliness()); + ret &= (subdata.reliability == dr_qos.reliability()); + ret &= (subdata.ownership == dr_qos.ownership()); + ret &= (subdata.destination_order == dr_qos.destination_order()); + ret &= ( + (subdata.user_data.size() == dr_qos.user_data().size()) && + (0 == memcmp(subdata.user_data.data(), dr_qos.user_data().data(), subdata.user_data.size()))); + // time based filter not implemented + + // Subscriber Qos + ret &= (subdata.presentation == sub_qos.presentation()); + ret &= (subdata.partition.getNames() == sub_qos.partition().getNames()); + // topic_data not implemented + // group_data too + + return ret; +} + +/** + * @test DDS-DW-API-GMSD-01 + * + * get_matched_subscription_data() must return RETCODE_BAD_PARAMETER + * if the subscription is not matched. + */ +TEST(DDSDataWriter, datawriter_get_matched_subscription_data_bad_parameter) +{ + using InstanceHandle_t = eprosima::fastdds::rtps::InstanceHandle_t; + + PubSubWriter writer(TEST_TOPIC_NAME); + PubSubReader reader_1(TEST_TOPIC_NAME); + PubSubReader reader_2(TEST_TOPIC_NAME); + + eprosima::fastdds::rtps::SubscriptionBuiltinTopicData subdata; + + writer.reliability(eprosima::fastdds::dds::BEST_EFFORT_RELIABILITY_QOS) + .init(); + + reader_1.reliability(eprosima::fastdds::dds::RELIABLE_RELIABILITY_QOS) + .init(); + reader_2.ownership_exclusive() + .init(); + + ASSERT_TRUE(writer.isInitialized()); + ASSERT_TRUE(reader_1.isInitialized()); + ASSERT_TRUE(reader_2.isInitialized()); + + // Writer should not be matched with any reader + writer.wait_discovery(2, std::chrono::seconds(1)); + + ASSERT_TRUE(!writer.is_matched()); + + auto& native_writer = writer.get_native_writer(); + + InstanceHandle_t r1_handle = reader_1.get_native_reader().get_instance_handle(); + ReturnCode_t ret = native_writer.get_matched_subscription_data(subdata, r1_handle); + + ASSERT_EQ(ret, eprosima::fastdds::dds::RETCODE_BAD_PARAMETER); + + InstanceHandle_t r2_handle = reader_2.get_native_reader().get_instance_handle(); + ret = native_writer.get_matched_subscription_data(subdata, r2_handle); + + ASSERT_EQ(ret, eprosima::fastdds::dds::RETCODE_BAD_PARAMETER); +} + +/** + * @test DDS-DW-API-GMSD-02 + * + * The operation must succeed when the subscription is matched and correctly + * retrieve the publication data. Parameterize the test for different transports. + */ +TEST_P(DDSDataWriter, datawriter_get_matched_subscription_data_correctly_behaves) +{ + using InstanceHandle_t = eprosima::fastdds::rtps::InstanceHandle_t; + + PubSubWriter writer(TEST_TOPIC_NAME); + PubSubReader reader_1(TEST_TOPIC_NAME); + PubSubReader reader_2(TEST_TOPIC_NAME); + + eprosima::fastdds::rtps::SubscriptionBuiltinTopicData r1_subdata, r2_subdata; + + writer.partition("*") + .init(); + + reader_1.partition("*") + .init(); + reader_2.user_data({'u', 's', 'e', 'r', 'd', 'a', 't', 'a'}) + .partition("*") + .reliability(eprosima::fastdds::dds::RELIABLE_RELIABILITY_QOS) + .init(); + + ASSERT_TRUE(writer.isInitialized()); + ASSERT_TRUE(reader_1.isInitialized()); + ASSERT_TRUE(reader_2.isInitialized()); + + // Writer must match with both readers + writer.wait_discovery(2, std::chrono::seconds::zero()); + + ASSERT_EQ(writer.get_matched(), 2u); + + auto& native_writer = writer.get_native_writer(); + + InstanceHandle_t r1_handle = reader_1.get_native_reader().get_instance_handle(); + ReturnCode_t ret = native_writer.get_matched_subscription_data(r1_subdata, r1_handle); + + ASSERT_EQ(ret, eprosima::fastdds::dds::RETCODE_OK); + ASSERT_TRUE(validate_subscription_builtin_topic_data(r1_subdata, reader_1.get_native_reader())); + + InstanceHandle_t r2_handle = reader_2.get_native_reader().get_instance_handle(); + ret = native_writer.get_matched_subscription_data(r2_subdata, r2_handle); + + ASSERT_EQ(ret, eprosima::fastdds::dds::RETCODE_OK); + ASSERT_TRUE(validate_subscription_builtin_topic_data(r2_subdata, reader_2.get_native_reader())); +} + +/** + * @test DDS-DW-API-GMS-01 + * + * get_matched_subscriptions() must return RETCODE_OK + * with an empty list if no DataWriters are matched. + */ +TEST(DDSDataWriter, datawriter_get_matched_subscriptions_ok_empty_list) +{ + using InstanceHandle_t = eprosima::fastdds::rtps::InstanceHandle_t; + + PubSubWriter writer(TEST_TOPIC_NAME); + PubSubReader reader_1(TEST_TOPIC_NAME); + PubSubReader reader_2(TEST_TOPIC_NAME); + + std::vector sub_handles; + + writer.reliability(eprosima::fastdds::dds::BEST_EFFORT_RELIABILITY_QOS) + .init(); + + reader_1.reliability(eprosima::fastdds::dds::RELIABLE_RELIABILITY_QOS) + .init(); + + reader_2.ownership_exclusive() + .init(); + + ASSERT_TRUE(writer.isInitialized()); + ASSERT_TRUE(reader_1.isInitialized()); + ASSERT_TRUE(reader_2.isInitialized()); + + // Writer should not be matched with any reader + writer.wait_discovery(2, std::chrono::seconds(2)); + ASSERT_FALSE(writer.is_matched()); + + auto& native_writer = writer.get_native_writer(); + ReturnCode_t ret = native_writer.get_matched_subscriptions(sub_handles); + + ASSERT_EQ(ret, eprosima::fastdds::dds::RETCODE_OK); + ASSERT_EQ(sub_handles.size(), 0u); +} + +/** + * @test DDS-DW-API-GMS-02 + * + * get_matched_subscriptions() must provide the correct list of matched subscription handles. + * Parameterize the test for different transports. + */ +TEST_P(DDSDataWriter, datawriter_get_matched_subscriptions_correctly_behaves) +{ + using InstanceHandle_t = eprosima::fastdds::rtps::InstanceHandle_t; + + const size_t num_readers = 5; + + PubSubWriter writer(TEST_TOPIC_NAME); + std::vector>> readers; + std::vector expected_sub_handles; + std::vector sub_handles; + + readers.reserve(num_readers); + sub_handles.reserve(num_readers); + + writer.init(); + + ASSERT_TRUE(writer.isInitialized()); + + for (size_t i = 0; i < num_readers; ++i) + { + readers.emplace_back(new PubSubReader(TEST_TOPIC_NAME)); + readers.back()->init(); + ASSERT_TRUE(readers.back()->isInitialized()); + expected_sub_handles.emplace_back(readers.back()->get_native_reader().get_instance_handle()); + } + + // Wait for discovery + writer.wait_discovery(num_readers, std::chrono::seconds::zero()); + ASSERT_EQ(writer.get_matched(), num_readers); + + auto& native_writer = writer.get_native_writer(); + ReturnCode_t ret = native_writer.get_matched_subscriptions(sub_handles); + + // Check that the list of matched publication handles is correct + ASSERT_EQ(ret, eprosima::fastdds::dds::RETCODE_OK); + ASSERT_EQ(sub_handles.size(), num_readers); + ASSERT_TRUE(std::is_permutation(sub_handles.begin(), sub_handles.end(), expected_sub_handles.begin())); + + // Remove two readers and check that the list of matched publication handles is updated + readers.pop_back(); + readers.pop_back(); + expected_sub_handles.pop_back(); + expected_sub_handles.pop_back(); + + // Wait for undiscovery + writer.wait_reader_undiscovery(static_cast(num_readers - 2)); + + sub_handles.clear(); + ret = native_writer.get_matched_subscriptions(sub_handles); + ASSERT_EQ(ret, eprosima::fastdds::dds::RETCODE_OK); + ASSERT_EQ(sub_handles.size(), static_cast(num_readers - 2)); + ASSERT_TRUE(std::is_permutation(sub_handles.begin(), sub_handles.end(), expected_sub_handles.begin())); +} + +/** + * @test DDS-DW-API-GMS-03 + * + * The operation must provide the correct list of matched subscription handles in multiple + * participants scenario. Parameterize the test for different transports. + */ +TEST_P(DDSDataWriter, datawriter_get_matched_subscriptions_multiple_participants_correctly_behave) +{ + using InstanceHandle_t = eprosima::fastdds::rtps::InstanceHandle_t; + + PubSubParticipant part_1(1, 1, 1, 1); + PubSubParticipant part_2(1, 1, 1, 1); + + part_1.pub_topic_name(TEST_TOPIC_NAME); + part_1.sub_topic_name(TEST_TOPIC_NAME + "_1"); + part_2.pub_topic_name(TEST_TOPIC_NAME + "_1"); + part_2.sub_topic_name(TEST_TOPIC_NAME); + + ASSERT_TRUE(part_1.init_participant()); + ASSERT_TRUE(part_1.init_publisher(0)); + ASSERT_TRUE(part_1.init_subscriber(0)); + + ASSERT_TRUE(part_2.init_participant()); + ASSERT_TRUE(part_2.init_subscriber(0)); + ASSERT_TRUE(part_2.init_publisher(0)); + + part_1.pub_wait_discovery(); + part_1.sub_wait_discovery(); + + part_2.pub_wait_discovery(); + part_2.sub_wait_discovery(); + + auto& writer_p1 = part_1.get_native_writer(0); + auto& writer_p2 = part_2.get_native_writer(0); + + std::vector sub_handles_p1; + std::vector sub_handles_p2; + + ReturnCode_t ret = writer_p1.get_matched_subscriptions(sub_handles_p1); + ASSERT_EQ(ret, eprosima::fastdds::dds::RETCODE_OK); + ASSERT_EQ(sub_handles_p1.size(), 1u); + ASSERT_EQ(sub_handles_p1[0], part_2.get_native_reader(0).get_instance_handle()); + + ret = writer_p2.get_matched_subscriptions(sub_handles_p2); + ASSERT_EQ(ret, eprosima::fastdds::dds::RETCODE_OK); + ASSERT_EQ(sub_handles_p2.size(), 1u); + ASSERT_EQ(sub_handles_p2[0], part_1.get_native_reader(0).get_instance_handle()); +} + #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/DDSBlackboxTestsPersistence.cpp b/test/blackbox/common/DDSBlackboxTestsPersistence.cpp index 30d62ce42b1..2d2881fb930 100644 --- a/test/blackbox/common/DDSBlackboxTestsPersistence.cpp +++ b/test/blackbox/common/DDSBlackboxTestsPersistence.cpp @@ -404,8 +404,8 @@ TEST_P(DDSPersistenceTests, PubSubAsReliablePubTransientWithStaticDiscovery) .multicastLocatorList(WriterMulticastLocators) .setPublisherIDs(1, 2) .setManualTopicName(std::string("BlackBox_StaticDiscovery_") + TOPIC_RANDOM_NUMBER) - .userData({'V', 'G', 'W', 0x78, 0x73, 0x69, 0x74, 0x65, 0x72, 0x5f, 0x70, 0x65, 0x72, 0x73, 0x5f, 0x67, - 0x75, 0x69}) + .user_data({'V', 'G', 'W', 0x78, 0x73, 0x69, 0x74, 0x65, 0x72, 0x5f, 0x70, 0x65, 0x72, 0x73, 0x5f, 0x67, + 0x75, 0x69}) .init(); ASSERT_TRUE(writer.isInitialized()); diff --git a/test/blackbox/common/RTPSBlackboxTests.cpp b/test/blackbox/common/RTPSBlackboxTests.cpp index e5bf3ac2595..6918b34f5be 100644 --- a/test/blackbox/common/RTPSBlackboxTests.cpp +++ b/test/blackbox/common/RTPSBlackboxTests.cpp @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -81,6 +82,36 @@ class BlackboxEnvironment : public ::testing::Environment }; +void entity_id_to_builtin_topic_key( + eprosima::fastdds::rtps::BuiltinTopicKey_t& bt_key, + const eprosima::fastdds::rtps::EntityId_t& entity_id) +{ + bt_key.value[0] = 0; + bt_key.value[1] = 0; + bt_key.value[2] = static_cast(entity_id.value[0]) << 24 + | static_cast(entity_id.value[1]) << 16 + | static_cast(entity_id.value[2]) << 8 + | static_cast(entity_id.value[3]); +} + +void guid_prefix_to_builtin_topic_key( + eprosima::fastdds::rtps::BuiltinTopicKey_t& bt_key, + const eprosima::fastdds::rtps::GuidPrefix_t& guid_prefix) +{ + bt_key.value[0] = static_cast(guid_prefix.value[0]) << 24 + | static_cast(guid_prefix.value[1]) << 16 + | static_cast(guid_prefix.value[2]) << 8 + | static_cast(guid_prefix.value[3]); + bt_key.value[1] = static_cast(guid_prefix.value[4]) << 24 + | static_cast(guid_prefix.value[5]) << 16 + | static_cast(guid_prefix.value[6]) << 8 + | static_cast(guid_prefix.value[7]); + bt_key.value[2] = static_cast(guid_prefix.value[8]) << 24 + | static_cast(guid_prefix.value[9]) << 16 + | static_cast(guid_prefix.value[10]) << 8 + | static_cast(guid_prefix.value[11]); +} + int main( int argc, char** argv) diff --git a/test/blackbox/common/RTPSBlackboxTestsBasic.cpp b/test/blackbox/common/RTPSBlackboxTestsBasic.cpp index c77e7731e34..a2f2c860b3e 100644 --- a/test/blackbox/common/RTPSBlackboxTestsBasic.cpp +++ b/test/blackbox/common/RTPSBlackboxTestsBasic.cpp @@ -1470,6 +1470,170 @@ TEST(RTPS, endpoint_creation_fails_with_incoherent_entity_id) ASSERT_FALSE(wrong_keyed_reader.isInitialized()); } +bool validate_publication_builtin_topic_data( + const eprosima::fastdds::rtps::PublicationBuiltinTopicData& pubdata, + const EntityId_t& writer_id, + const dds::WriterQos& writer_qos, + const TopicDescription& topic_desc, + const GUID_t& participant_guid) +{ + bool ret = true; + + eprosima::fastdds::rtps::BuiltinTopicKey_t w_key, part_key; + + entity_id_to_builtin_topic_key(w_key, writer_id); + guid_prefix_to_builtin_topic_key(part_key, participant_guid.guidPrefix); + + ret &= (0 == memcmp(pubdata.key.value, w_key.value, sizeof(eprosima::fastdds::rtps::BuiltinTopicKey_t))); + ret &= + (0 == + memcmp(pubdata.participant_key.value, part_key.value, + sizeof(eprosima::fastdds::rtps::BuiltinTopicKey_t))); + ret &= (pubdata.topic_name == topic_desc.topic_name); + ret &= (pubdata.type_name == topic_desc.type_name); + + // Writer Qos + ret &= (pubdata.durability == writer_qos.m_durability); + ret &= (pubdata.durability_service == writer_qos.m_durabilityService); + ret &= (pubdata.deadline == writer_qos.m_deadline); + ret &= (pubdata.latency_budget == writer_qos.m_latencyBudget); + ret &= (pubdata.liveliness == writer_qos.m_liveliness); + ret &= (pubdata.reliability == writer_qos.m_reliability); + ret &= (pubdata.lifespan == writer_qos.m_lifespan); + ret &= ( + (pubdata.user_data.size() == writer_qos.m_userData.size()) && + (0 == memcmp(pubdata.user_data.data(), writer_qos.m_userData.data(), pubdata.user_data.size()))); + ret &= (pubdata.ownership == writer_qos.m_ownership); + ret &= (pubdata.ownership_strength == writer_qos.m_ownershipStrength); + ret &= (pubdata.destination_order == writer_qos.m_destinationOrder); + + // Publisher Qos + ret &= (pubdata.presentation == writer_qos.m_presentation); + ret &= (pubdata.partition.getNames() == writer_qos.m_partition.getNames()); + // ignore topic_data not implemented + // ignore group_data + + return ret; +} + +bool validate_subscription_builtin_topic_data( + const eprosima::fastdds::rtps::SubscriptionBuiltinTopicData& subdata, + const EntityId_t& reader_id, + const dds::ReaderQos& reader_qos, + const TopicDescription& topic_desc, + const GUID_t& participant_guid) +{ + bool ret = true; + + eprosima::fastdds::rtps::BuiltinTopicKey_t r_key, part_key; + + entity_id_to_builtin_topic_key(r_key, reader_id); + guid_prefix_to_builtin_topic_key(part_key, participant_guid.guidPrefix); + + ret &= (0 == memcmp(subdata.key.value, r_key.value, sizeof(eprosima::fastdds::rtps::BuiltinTopicKey_t))); + ret &= + (0 == + memcmp(subdata.participant_key.value, part_key.value, + sizeof(eprosima::fastdds::rtps::BuiltinTopicKey_t))); + ret &= (subdata.topic_name == topic_desc.topic_name); + ret &= (subdata.type_name == topic_desc.type_name); + + // RTPS Reader + ret &= (subdata.durability == reader_qos.m_durability); + ret &= (subdata.deadline == reader_qos.m_deadline); + ret &= (subdata.latency_budget == reader_qos.m_latencyBudget); + ret &= (subdata.liveliness == reader_qos.m_liveliness); + ret &= (subdata.reliability == reader_qos.m_reliability); + ret &= (subdata.ownership == reader_qos.m_ownership); + ret &= (subdata.destination_order == reader_qos.m_destinationOrder); + ret &= ( + (subdata.user_data.size() == reader_qos.m_userData.size()) && + (0 == memcmp(subdata.user_data.data(), reader_qos.m_userData.data(), subdata.user_data.size()))); + // time based filter not implemented + + // Subscriber Qos + ret &= (subdata.presentation == reader_qos.m_presentation); + ret &= (subdata.partition.getNames() == reader_qos.m_partition.getNames()); + // ignore topic_data not implemented + // ignore group_data + + return ret; +} + +/** + * @test RTPS-PART-API-GSI-GPI-01 + * + * get_subscription/publication_info() must return false if the entity is not found. + */ +TEST(RTPS, rtps_participant_get_pubsub_info_negative) +{ + RTPSWithRegistrationWriter writer(TEST_TOPIC_NAME); + RTPSWithRegistrationReader reader(TEST_TOPIC_NAME); + + writer.init(); + reader.init(); + + ASSERT_TRUE(writer.isInitialized()); + ASSERT_TRUE(reader.isInitialized()); + + eprosima::fastdds::rtps::PublicationBuiltinTopicData pubdata; + eprosima::fastdds::rtps::SubscriptionBuiltinTopicData subdata; + + // Get publication info from the reader participant and validate it + GUID_t unknown_writer_guid = writer.guid(); + unknown_writer_guid.entityId.value[3] = 0x44; + bool ret = reader.get_rtps_participant()->get_publication_info(pubdata, unknown_writer_guid); + ASSERT_FALSE(ret); + + GUID_t unknown_reader_guid = reader.guid(); + unknown_reader_guid.entityId.value[3] = 0x44; + // Get subscription info from the reader participant and validate it + ret = writer.get_rtps_participant()->get_subscription_info(subdata, unknown_reader_guid); + ASSERT_FALSE(ret); +} + +/** + * @test RTPS-PART-API-GSI-GPI-02 + * + * get_subscription/publication_info() must succeed when the guid is known and correctly retrieve the publication/subscription data. + * Parameterize the test for different transports (Transport, Datasharing and Intraprocess). + */ +TEST_P(RTPS, rtps_participant_get_pubsub_info) +{ + RTPSWithRegistrationWriter writer(TEST_TOPIC_NAME); + RTPSWithRegistrationReader reader(TEST_TOPIC_NAME); + + std::vector partitions{"*"}; + + writer.user_data({'u', 's', 'e', 'r', 'd', 'a', 't', 'a'}) + .partitions(partitions) + .init(); + reader.user_data({'u', 's', 'e', 'r', 'd', 'a', 't', 'a'}) + .partitions(partitions) + .init(); + + ASSERT_TRUE(writer.isInitialized()); + ASSERT_TRUE(reader.isInitialized()); + + writer.wait_discovery(); + reader.wait_discovery(); + + eprosima::fastdds::rtps::PublicationBuiltinTopicData pubdata; + eprosima::fastdds::rtps::SubscriptionBuiltinTopicData subdata; + + // Get publication info from the reader participant and validate it + bool ret = reader.get_rtps_participant()->get_publication_info(pubdata, writer.guid()); + ASSERT_TRUE(ret); + ASSERT_TRUE(validate_publication_builtin_topic_data(pubdata, writer.guid().entityId, + writer.get_writer_qos(), writer.get_topic_description(), writer.get_rtps_participant()->getGuid())); + + // Get subscription info from the reader participant and validate it + ret = writer.get_rtps_participant()->get_subscription_info(subdata, reader.guid()); + ASSERT_TRUE(ret); + ASSERT_TRUE(validate_subscription_builtin_topic_data(subdata, reader.guid().entityId, + reader.get_reader_qos(), reader.get_topic_description(), reader.get_rtps_participant()->getGuid())); +} + #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/RTPSBlackboxTestsReader.cpp b/test/blackbox/common/RTPSBlackboxTestsReader.cpp new file mode 100644 index 00000000000..fa721adc37d --- /dev/null +++ b/test/blackbox/common/RTPSBlackboxTestsReader.cpp @@ -0,0 +1,156 @@ +// 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 "BlackboxTests.hpp" + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "RTPSWithRegistrationReader.hpp" +#include "RTPSWithRegistrationWriter.hpp" + +using namespace eprosima::fastdds; +using namespace eprosima::fastdds::rtps; + +enum communication_type +{ + TRANSPORT, + INTRAPROCESS +}; + +class RTPSReaderTests : public testing::TestWithParam +{ +public: + + void SetUp() override + { + eprosima::fastdds::LibrarySettings library_settings; + switch (GetParam()) + { + case INTRAPROCESS: + library_settings.intraprocess_delivery = eprosima::fastdds::IntraprocessDeliveryType::INTRAPROCESS_FULL; + eprosima::fastdds::rtps::RTPSDomain::set_library_settings(library_settings); + break; + case TRANSPORT: + default: + break; + } + } + + void TearDown() override + { + eprosima::fastdds::LibrarySettings library_settings; + switch (GetParam()) + { + case INTRAPROCESS: + library_settings.intraprocess_delivery = eprosima::fastdds::IntraprocessDeliveryType::INTRAPROCESS_OFF; + eprosima::fastdds::rtps::RTPSDomain::set_library_settings(library_settings); + break; + case TRANSPORT: + default: + break; + } + } + +}; + +/** + * @test RTPS-READER-API-MWG-01 + * + * matched_writers_guids() must return true with empty list when the entitiy is not matched. + * matched_writers_guids() must return true with a correct list when the entitiy is matched. + */ +TEST_P(RTPSReaderTests, rtpsreader_matched_writers_guids) +{ + RTPSWithRegistrationReader reader(TEST_TOPIC_NAME); + RTPSWithRegistrationWriter writer(TEST_TOPIC_NAME); + + reader.reliability(eprosima::fastdds::rtps::RELIABLE) + .init(); + + writer.reliability(eprosima::fastdds::rtps::BEST_EFFORT) + .init(); + + ASSERT_TRUE(reader.isInitialized()); + ASSERT_TRUE(writer.isInitialized()); + + // Expect not to discover + reader.wait_discovery(std::chrono::seconds(1)); + ASSERT_FALSE(reader.get_matched()); + + std::vector matched_guids; + auto& native_rtps_reader = reader.get_native_reader(); + ASSERT_TRUE(native_rtps_reader.matched_writers_guids(matched_guids)); + ASSERT_TRUE(matched_guids.empty()); + + writer.destroy(); + reader.wait_undiscovery(); + + const size_t num_matched_writers = 3; + std::vector>> writers; + std::vector expected_matched_guids; + + writers.reserve(num_matched_writers); + expected_matched_guids.reserve(num_matched_writers); + + for (size_t i = 0; i < num_matched_writers; ++i) + { + writers.emplace_back(new RTPSWithRegistrationWriter(TEST_TOPIC_NAME)); + writers.back()->init(); + expected_matched_guids.emplace_back(writers.back()->guid()); + } + + reader.wait_discovery(num_matched_writers, std::chrono::seconds::zero()); + ASSERT_EQ(num_matched_writers, reader.get_matched()); + native_rtps_reader.matched_writers_guids(matched_guids); + ASSERT_EQ(expected_matched_guids.size(), matched_guids.size()); + ASSERT_TRUE(std::is_permutation(expected_matched_guids.begin(), expected_matched_guids.end(), + matched_guids.begin())); +} + +#ifdef INSTANTIATE_TEST_SUITE_P +#define GTEST_INSTANTIATE_TEST_MACRO(x, y, z, w) INSTANTIATE_TEST_SUITE_P(x, y, z, w) +#else +#define GTEST_INSTANTIATE_TEST_MACRO(x, y, z, w) INSTANTIATE_TEST_CASE_P(x, y, z, w) +#endif // ifdef INSTANTIATE_TEST_SUITE_P + +GTEST_INSTANTIATE_TEST_MACRO(RTPSReaderTests, + RTPSReaderTests, + testing::Values(TRANSPORT, INTRAPROCESS), + [](const testing::TestParamInfo& info) + { + switch (info.param) + { + case INTRAPROCESS: + return "Intraprocess"; + break; + case TRANSPORT: + default: + return "Transport"; + } + + }); diff --git a/test/blackbox/common/RTPSBlackboxTestsWriter.cpp b/test/blackbox/common/RTPSBlackboxTestsWriter.cpp new file mode 100644 index 00000000000..50de3428bc7 --- /dev/null +++ b/test/blackbox/common/RTPSBlackboxTestsWriter.cpp @@ -0,0 +1,156 @@ +// 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 "BlackboxTests.hpp" + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "RTPSWithRegistrationReader.hpp" +#include "RTPSWithRegistrationWriter.hpp" + +using namespace eprosima::fastdds; +using namespace eprosima::fastdds::rtps; + +enum communication_type +{ + TRANSPORT, + INTRAPROCESS +}; + +class RTPSWriterTests : public testing::TestWithParam +{ +public: + + void SetUp() override + { + eprosima::fastdds::LibrarySettings library_settings; + switch (GetParam()) + { + case INTRAPROCESS: + library_settings.intraprocess_delivery = eprosima::fastdds::IntraprocessDeliveryType::INTRAPROCESS_FULL; + eprosima::fastdds::rtps::RTPSDomain::set_library_settings(library_settings); + break; + case TRANSPORT: + default: + break; + } + } + + void TearDown() override + { + eprosima::fastdds::LibrarySettings library_settings; + switch (GetParam()) + { + case INTRAPROCESS: + library_settings.intraprocess_delivery = eprosima::fastdds::IntraprocessDeliveryType::INTRAPROCESS_OFF; + eprosima::fastdds::rtps::RTPSDomain::set_library_settings(library_settings); + break; + case TRANSPORT: + default: + break; + } + } + +}; + +/** + * @test RTPS-WRITER-API-MRG-01 + * + * matched_readers_guids() must return true with empty list when the entitiy is not matched. + * matched_readers_guids() must return true with a correct list when the entitiy is matched. + */ +TEST_P(RTPSWriterTests, rtpswriter_matched_readers_guids) +{ + RTPSWithRegistrationWriter writer(TEST_TOPIC_NAME); + RTPSWithRegistrationReader reader(TEST_TOPIC_NAME); + + writer.reliability(eprosima::fastdds::rtps::BEST_EFFORT) + .init(); + + reader.reliability(eprosima::fastdds::rtps::RELIABLE) + .init(); + + ASSERT_TRUE(writer.isInitialized()); + ASSERT_TRUE(reader.isInitialized()); + + // Expect not to discover + writer.wait_discovery(std::chrono::seconds(1)); + ASSERT_FALSE(writer.get_matched()); + + std::vector matched_guids; + auto& native_rtps_writer = writer.get_native_writer(); + ASSERT_TRUE(native_rtps_writer.matched_readers_guids(matched_guids)); + ASSERT_TRUE(matched_guids.empty()); + + reader.destroy(); + writer.wait_undiscovery(); + + const size_t num_matched_readers = 3; + std::vector>> readers; + std::vector expected_matched_guids; + + readers.reserve(num_matched_readers); + expected_matched_guids.reserve(num_matched_readers); + + for (size_t i = 0; i < num_matched_readers; ++i) + { + readers.emplace_back(new RTPSWithRegistrationReader(TEST_TOPIC_NAME)); + readers.back()->init(); + expected_matched_guids.emplace_back(readers.back()->guid()); + } + + writer.wait_discovery(num_matched_readers, std::chrono::seconds::zero()); + ASSERT_EQ(num_matched_readers, writer.get_matched()); + native_rtps_writer.matched_readers_guids(matched_guids); + ASSERT_EQ(expected_matched_guids.size(), matched_guids.size()); + ASSERT_TRUE(std::is_permutation(expected_matched_guids.begin(), expected_matched_guids.end(), + matched_guids.begin())); +} + +#ifdef INSTANTIATE_TEST_SUITE_P +#define GTEST_INSTANTIATE_TEST_MACRO(x, y, z, w) INSTANTIATE_TEST_SUITE_P(x, y, z, w) +#else +#define GTEST_INSTANTIATE_TEST_MACRO(x, y, z, w) INSTANTIATE_TEST_CASE_P(x, y, z, w) +#endif // ifdef INSTANTIATE_TEST_SUITE_P + +GTEST_INSTANTIATE_TEST_MACRO(RTPSWriterTests, + RTPSWriterTests, + testing::Values(TRANSPORT, INTRAPROCESS), + [](const testing::TestParamInfo& info) + { + switch (info.param) + { + case INTRAPROCESS: + return "Intraprocess"; + break; + case TRANSPORT: + default: + return "Transport"; + } + + }); diff --git a/test/blackbox/common/RTPSWithRegistrationReader.hpp b/test/blackbox/common/RTPSWithRegistrationReader.hpp index 75e366b0745..e39fb4f6859 100644 --- a/test/blackbox/common/RTPSWithRegistrationReader.hpp +++ b/test/blackbox/common/RTPSWithRegistrationReader.hpp @@ -602,6 +602,24 @@ class RTPSWithRegistrationReader return *reader_; } + const eprosima::fastdds::dds::ReaderQos& get_reader_qos() const + { + return reader_qos_; + } + + eprosima::fastdds::rtps::TopicDescription get_topic_description() const + { + eprosima::fastdds::rtps::TopicDescription topic_desc; + topic_desc.topic_name = sub_builtin_data_.topic_name; + topic_desc.type_name = sub_builtin_data_.type_name; + return topic_desc; + } + + const eprosima::fastdds::rtps::RTPSParticipant* get_rtps_participant() const + { + return participant_; + } + private: void receive_one( diff --git a/test/blackbox/common/RTPSWithRegistrationWriter.hpp b/test/blackbox/common/RTPSWithRegistrationWriter.hpp index 7f8f6eded75..a82781e5008 100644 --- a/test/blackbox/common/RTPSWithRegistrationWriter.hpp +++ b/test/blackbox/common/RTPSWithRegistrationWriter.hpp @@ -612,6 +612,29 @@ class RTPSWithRegistrationWriter return writer_->getGuid(); } + eprosima::fastdds::rtps::RTPSWriter& get_native_writer() const + { + return *writer_; + } + + const eprosima::fastdds::dds::WriterQos& get_writer_qos() const + { + return writer_qos_; + } + + eprosima::fastdds::rtps::TopicDescription get_topic_description() const + { + eprosima::fastdds::rtps::TopicDescription topic_desc; + topic_desc.topic_name = pub_builtin_data_.topic_name; + topic_desc.type_name = pub_builtin_data_.type_name; + return topic_desc; + } + + const eprosima::fastdds::rtps::RTPSParticipant* get_rtps_participant() const + { + return participant_; + } + private: void on_reader_discovery( diff --git a/test/mock/rtps/RTPSParticipant/fastdds/rtps/participant/RTPSParticipant.hpp b/test/mock/rtps/RTPSParticipant/fastdds/rtps/participant/RTPSParticipant.hpp index d56e0ed65dc..294aaf07a01 100644 --- a/test/mock/rtps/RTPSParticipant/fastdds/rtps/participant/RTPSParticipant.hpp +++ b/test/mock/rtps/RTPSParticipant/fastdds/rtps/participant/RTPSParticipant.hpp @@ -54,6 +54,8 @@ namespace dds { namespace builtin { class TypeLookupManager; +struct PublicationBuiltinTopicData; +struct SubscriptionBuiltinTopicData; } // namespace builtin } // namespace dds @@ -219,6 +221,14 @@ class FASTDDS_EXPORTED_API RTPSParticipant return attributes_; } + MOCK_METHOD(bool, get_publication_info, + (fastdds::rtps::PublicationBuiltinTopicData&, + const GUID_t&), (const)); + + MOCK_METHOD(bool, get_subscription_info, + (fastdds::rtps::SubscriptionBuiltinTopicData&, + const GUID_t&), (const)); + bool update_attributes( const RTPSParticipantAttributes& patt) { diff --git a/test/mock/rtps/RTPSReader/fastdds/rtps/reader/RTPSReader.hpp b/test/mock/rtps/RTPSReader/fastdds/rtps/reader/RTPSReader.hpp index 1638b53943c..9d865c5ed67 100644 --- a/test/mock/rtps/RTPSReader/fastdds/rtps/reader/RTPSReader.hpp +++ b/test/mock/rtps/RTPSReader/fastdds/rtps/reader/RTPSReader.hpp @@ -68,6 +68,12 @@ class RTPSReader : public Endpoint virtual void assert_writer_liveliness( const GUID_t& wguid) = 0; + virtual bool matched_writers_guids( + std::vector&) const + { + return false; + } + virtual bool is_in_clean_state() = 0; virtual ReaderListener* get_listener() const = 0; diff --git a/test/mock/rtps/RTPSWriter/fastdds/rtps/writer/RTPSWriter.hpp b/test/mock/rtps/RTPSWriter/fastdds/rtps/writer/RTPSWriter.hpp index d358f05988d..e3d73e4c1da 100644 --- a/test/mock/rtps/RTPSWriter/fastdds/rtps/writer/RTPSWriter.hpp +++ b/test/mock/rtps/RTPSWriter/fastdds/rtps/writer/RTPSWriter.hpp @@ -85,6 +85,12 @@ class RTPSWriter : public Endpoint return false; } + virtual bool matched_readers_guids( + std::vector&) const + { + return false; + } + virtual bool has_been_fully_delivered( const SequenceNumber_t& /*seq_num*/) const { From 3037151d2a97f90a106f105f9f5730c034d17e41 Mon Sep 17 00:00:00 2001 From: Mario Dominguez Date: Wed, 9 Oct 2024 10:12:54 +0200 Subject: [PATCH 2/6] Refs #21808: DataWriter/Reader get_matched_publication/subscription() Feature implementation 3.x Signed-off-by: Mario Dominguez --- src/cpp/fastdds/publisher/DataWriter.cpp | 13 +----- src/cpp/fastdds/publisher/DataWriterImpl.cpp | 42 +++++++++++++++++++ src/cpp/fastdds/publisher/DataWriterImpl.hpp | 25 +++++++++++ src/cpp/fastdds/subscriber/DataReader.cpp | 13 +----- src/cpp/fastdds/subscriber/DataReaderImpl.cpp | 42 +++++++++++++++++++ src/cpp/fastdds/subscriber/DataReaderImpl.hpp | 25 +++++++++++ src/cpp/rtps/participant/RTPSParticipant.cpp | 14 +++++++ .../rtps/participant/RTPSParticipantImpl.cpp | 34 +++++++++++++++ .../rtps/participant/RTPSParticipantImpl.h | 24 +++++++++++ src/cpp/rtps/reader/StatefulReader.cpp | 13 ++++++ src/cpp/rtps/reader/StatefulReader.hpp | 9 ++++ src/cpp/rtps/reader/StatelessReader.cpp | 13 ++++++ src/cpp/rtps/reader/StatelessReader.hpp | 9 ++++ src/cpp/rtps/writer/StatefulWriter.cpp | 16 +++++++ src/cpp/rtps/writer/StatefulWriter.hpp | 9 ++++ src/cpp/rtps/writer/StatelessWriter.cpp | 15 +++++++ src/cpp/rtps/writer/StatelessWriter.hpp | 9 ++++ .../mock/fastdds/publisher/DataWriterImpl.hpp | 19 +++++++++ 18 files changed, 322 insertions(+), 22 deletions(-) diff --git a/src/cpp/fastdds/publisher/DataWriter.cpp b/src/cpp/fastdds/publisher/DataWriter.cpp index 7ca2dbda822..1b05972eee9 100644 --- a/src/cpp/fastdds/publisher/DataWriter.cpp +++ b/src/cpp/fastdds/publisher/DataWriter.cpp @@ -270,22 +270,13 @@ ReturnCode_t DataWriter::get_matched_subscription_data( SubscriptionBuiltinTopicData& subscription_data, const InstanceHandle_t& subscription_handle) const { - static_cast (subscription_data); - static_cast (subscription_handle); - return RETCODE_UNSUPPORTED; - /* - return impl_->get_matched_subscription_data(subscription_data, subscription_handle); - */ + return impl_->get_matched_subscription_data(subscription_data, subscription_handle); } ReturnCode_t DataWriter::get_matched_subscriptions( std::vector& subscription_handles) const { - static_cast (subscription_handles); - return RETCODE_UNSUPPORTED; - /* - return impl_->get_matched_subscription_data(subscription_handles); - */ + return impl_->get_matched_subscriptions(subscription_handles); } ReturnCode_t DataWriter::clear_history( diff --git a/src/cpp/fastdds/publisher/DataWriterImpl.cpp b/src/cpp/fastdds/publisher/DataWriterImpl.cpp index f4d732ec723..21ddaf586a3 100644 --- a/src/cpp/fastdds/publisher/DataWriterImpl.cpp +++ b/src/cpp/fastdds/publisher/DataWriterImpl.cpp @@ -2335,6 +2335,48 @@ void DataWriterImpl::filter_is_being_removed( } } +ReturnCode_t DataWriterImpl::get_matched_subscription_data( + SubscriptionBuiltinTopicData& subscription_data, + const InstanceHandle_t& subscription_handle) const +{ + ReturnCode_t ret = RETCODE_BAD_PARAMETER; + fastdds::rtps::GUID_t reader_guid = iHandle2GUID(subscription_handle); + + if (writer_ && writer_->matched_reader_is_matched(reader_guid)) + { + if (publisher_) + { + RTPSParticipant* rtps_participant = publisher_->rtps_participant(); + if (rtps_participant && + rtps_participant->get_subscription_info(subscription_data, reader_guid)) + { + ret = RETCODE_OK; + } + } + } + + return ret; +} + +ReturnCode_t DataWriterImpl::get_matched_subscriptions( + std::vector& subscription_handles) const +{ + ReturnCode_t ret = RETCODE_ERROR; + std::vector matched_reader_guids; + subscription_handles.clear(); + + if (writer_ && writer_->matched_readers_guids(matched_reader_guids)) + { + for (const rtps::GUID_t& guid : matched_reader_guids) + { + subscription_handles.emplace_back(InstanceHandle_t(guid)); + } + ret = RETCODE_OK; + } + + return ret; +} + bool DataWriterImpl::is_relevant( const fastdds::rtps::CacheChange_t& change, const fastdds::rtps::GUID_t& reader_guid) const diff --git a/src/cpp/fastdds/publisher/DataWriterImpl.hpp b/src/cpp/fastdds/publisher/DataWriterImpl.hpp index 7ddd8927e24..346b80495ab 100644 --- a/src/cpp/fastdds/publisher/DataWriterImpl.hpp +++ b/src/cpp/fastdds/publisher/DataWriterImpl.hpp @@ -381,6 +381,31 @@ class DataWriterImpl : protected rtps::IReaderDataFilter void filter_is_being_removed( const char* filter_class_name); + /** + * @brief Retrieves in a subscription associated with the DataWriter + * + * @param[out] subscription_data subscription data struct + * @param subscription_handle InstanceHandle_t of the subscription + * @return RETCODE_BAD_PARAMETER if the DataWriter is not matched with + * the given subscription handle, RETCODE_OK otherwise. + * + */ + ReturnCode_t get_matched_subscription_data( + SubscriptionBuiltinTopicData& subscription_data, + const InstanceHandle_t& subscription_handle) const; + + /** + * @brief Fills the given vector with the InstanceHandle_t of matched DataReaders + * + * @param[out] subscription_handles Vector where the InstanceHandle_t are returned + * @return RETCODE_OK if the operation succeeds. + * + * @note Returning an empty list is not an error, it returns RETCODE_OK. + * + */ + ReturnCode_t get_matched_subscriptions( + std::vector& subscription_handles) const; + /** * Retrieve the publication data discovery information. * diff --git a/src/cpp/fastdds/subscriber/DataReader.cpp b/src/cpp/fastdds/subscriber/DataReader.cpp index 9e93b84ee03..5d4880f7dca 100644 --- a/src/cpp/fastdds/subscriber/DataReader.cpp +++ b/src/cpp/fastdds/subscriber/DataReader.cpp @@ -394,22 +394,13 @@ ReturnCode_t DataReader::get_matched_publication_data( PublicationBuiltinTopicData& publication_data, const fastdds::rtps::InstanceHandle_t& publication_handle) const { - static_cast (publication_data); - static_cast (publication_handle); - return RETCODE_UNSUPPORTED; - /* - return impl_->get_matched_publication_data(publication_data, publication_handle); - */ + return impl_->get_matched_publication_data(publication_data, publication_handle); } ReturnCode_t DataReader::get_matched_publications( std::vector& publication_handles) const { - static_cast (publication_handles); - return RETCODE_UNSUPPORTED; - /* - return impl_->get_matched_publication_data(publication_handles); - */ + return impl_->get_matched_publications(publication_handles); } ReadCondition* DataReader::create_readcondition( diff --git a/src/cpp/fastdds/subscriber/DataReaderImpl.cpp b/src/cpp/fastdds/subscriber/DataReaderImpl.cpp index 2ea8a902e88..a298a700d2d 100644 --- a/src/cpp/fastdds/subscriber/DataReaderImpl.cpp +++ b/src/cpp/fastdds/subscriber/DataReaderImpl.cpp @@ -1211,6 +1211,48 @@ ReturnCode_t DataReaderImpl::get_subscription_matched_status( return RETCODE_OK; } +ReturnCode_t DataReaderImpl::get_matched_publication_data( + PublicationBuiltinTopicData& publication_data, + const InstanceHandle_t& publication_handle) const +{ + ReturnCode_t ret = RETCODE_BAD_PARAMETER; + fastdds::rtps::GUID_t writer_guid = iHandle2GUID(publication_handle); + + if (reader_ && reader_->matched_writer_is_matched(writer_guid)) + { + if (subscriber_) + { + RTPSParticipant* rtps_participant = subscriber_->rtps_participant(); + if (rtps_participant && + rtps_participant->get_publication_info(publication_data, writer_guid)) + { + ret = RETCODE_OK; + } + } + } + + return ret; +} + +ReturnCode_t DataReaderImpl::get_matched_publications( + std::vector& publication_handles) const +{ + ReturnCode_t ret = RETCODE_ERROR; + std::vector matched_writers_guids; + publication_handles.clear(); + + if (reader_ && reader_->matched_writers_guids(matched_writers_guids)) + { + for (const rtps::GUID_t& guid : matched_writers_guids) + { + publication_handles.emplace_back(InstanceHandle_t(guid)); + } + ret = RETCODE_OK; + } + + return ret; +} + bool DataReaderImpl::deadline_timer_reschedule() { assert(qos_.deadline().period != dds::c_TimeInfinite); diff --git a/src/cpp/fastdds/subscriber/DataReaderImpl.hpp b/src/cpp/fastdds/subscriber/DataReaderImpl.hpp index 9b5856c4058..fba4ad91e09 100644 --- a/src/cpp/fastdds/subscriber/DataReaderImpl.hpp +++ b/src/cpp/fastdds/subscriber/DataReaderImpl.hpp @@ -234,6 +234,31 @@ class DataReaderImpl ReturnCode_t get_subscription_matched_status( SubscriptionMatchedStatus& status); + /** + * @brief Retrieves in a publication associated with the DataWriter + * + * @param[out] publication_data publication data struct + * @param publication_handle InstanceHandle_t of the publication + * @return RETCODE_BAD_PARAMETER if the DataReader is not matched with + * the given publication handle, RETCODE_OK otherwise. + * + */ + ReturnCode_t get_matched_publication_data( + rtps::PublicationBuiltinTopicData& publication_data, + const InstanceHandle_t& publication_handle) const; + + /** + * @brief Fills the given vector with the InstanceHandle_t of matched DataReaders + * + * @param[out] publication_handles Vector where the InstanceHandle_t are returned + * @return RETCODE_OK if the operation succeeds. + * + * @note Returning an empty list is not an error, it returns RETCODE_OK. + * + */ + ReturnCode_t get_matched_publications( + std::vector& publication_handles) const; + ReturnCode_t get_requested_deadline_missed_status( RequestedDeadlineMissedStatus& status); diff --git a/src/cpp/rtps/participant/RTPSParticipant.cpp b/src/cpp/rtps/participant/RTPSParticipant.cpp index 362f70f42da..3f6be299919 100644 --- a/src/cpp/rtps/participant/RTPSParticipant.cpp +++ b/src/cpp/rtps/participant/RTPSParticipant.cpp @@ -194,6 +194,20 @@ std::vector RTPSParticipant::get_netmask_filter_info return mp_impl->get_netmask_filter_info(); } +bool RTPSParticipant::get_publication_info( + PublicationBuiltinTopicData& data, + const GUID_t& writer_guid) const +{ + return mp_impl->get_publication_info(data, writer_guid); +} + +bool RTPSParticipant::get_subscription_info( + SubscriptionBuiltinTopicData& data, + const GUID_t& reader_guid) const +{ + return mp_impl->get_subscription_info(data, reader_guid); +} + #if HAVE_SECURITY bool RTPSParticipant::is_security_enabled_for_writer( diff --git a/src/cpp/rtps/participant/RTPSParticipantImpl.cpp b/src/cpp/rtps/participant/RTPSParticipantImpl.cpp index 4d2849a355a..bd6057fe309 100644 --- a/src/cpp/rtps/participant/RTPSParticipantImpl.cpp +++ b/src/cpp/rtps/participant/RTPSParticipantImpl.cpp @@ -2791,6 +2791,40 @@ std::vector RTPSParticipantImpl::get_netmask_filter_ return m_network_Factory.netmask_filter_info(); } +bool RTPSParticipantImpl::get_publication_info( + PublicationBuiltinTopicData& data, + const GUID_t& writer_guid) const +{ + bool ret = false; + WriterProxyData wproxy_data(m_att.allocation.locators.max_unicast_locators, + m_att.allocation.locators.max_multicast_locators); + + if (mp_builtinProtocols->mp_PDP->lookupWriterProxyData(writer_guid, wproxy_data)) + { + from_proxy_to_builtin(wproxy_data, data); + ret = true; + } + + return ret; +} + +bool RTPSParticipantImpl::get_subscription_info( + SubscriptionBuiltinTopicData& data, + const GUID_t& reader_guid) const +{ + bool ret = false; + ReaderProxyData rproxy_data(m_att.allocation.locators.max_unicast_locators, + m_att.allocation.locators.max_multicast_locators); + + if (mp_builtinProtocols->mp_PDP->lookupReaderProxyData(reader_guid, rproxy_data)) + { + from_proxy_to_builtin(rproxy_data, data); + ret = true; + } + + return ret; +} + #ifdef FASTDDS_STATISTICS bool RTPSParticipantImpl::register_in_writer( diff --git a/src/cpp/rtps/participant/RTPSParticipantImpl.h b/src/cpp/rtps/participant/RTPSParticipantImpl.h index b6477c99072..37310c75b7e 100644 --- a/src/cpp/rtps/participant/RTPSParticipantImpl.h +++ b/src/cpp/rtps/participant/RTPSParticipantImpl.h @@ -1120,6 +1120,30 @@ class RTPSParticipantImpl */ std::vector get_netmask_filter_info() const; + /** + * @brief Fills the provided PublicationBuiltinTopicData with the information of the + * writer identified by writer_guid. + * + * @param[out] data PublicationBuiltinTopicData to fill. + * @param[in] writer_guid GUID of the writer to get the information from. + * @return True if the writer was found and the data was filled. + */ + bool get_publication_info( + PublicationBuiltinTopicData& data, + const GUID_t& writer_guid) const; + + /** + * @brief Fills the provided SubscriptionBuiltinTopicData with the information of the + * reader identified by reader_guid. + * + * @param[out] data SubscriptionBuiltinTopicData to fill. + * @param[in] reader_guid GUID of the reader to get the information from. + * @return True if the reader was found and the data was filled. + */ + bool get_subscription_info( + SubscriptionBuiltinTopicData& data, + const GUID_t& reader_guid) const; + template static bool preprocess_endpoint_attributes( const EntityId_t& entity_id, diff --git a/src/cpp/rtps/reader/StatefulReader.cpp b/src/cpp/rtps/reader/StatefulReader.cpp index 854d7424dd8..403bf5b6bec 100644 --- a/src/cpp/rtps/reader/StatefulReader.cpp +++ b/src/cpp/rtps/reader/StatefulReader.cpp @@ -1492,6 +1492,19 @@ void StatefulReader::end_sample_access_nts( } } +bool StatefulReader::matched_writers_guids( + std::vector& guids) const +{ + std::lock_guard guard(mp_mutex); + guids.clear(); + guids.reserve(matched_writers_.size()); + for (WriterProxy* writer : matched_writers_) + { + guids.push_back(writer->guid()); + } + return true; +} + #ifdef FASTDDS_STATISTICS bool StatefulReader::get_connections( diff --git a/src/cpp/rtps/reader/StatefulReader.hpp b/src/cpp/rtps/reader/StatefulReader.hpp index 1a97d1a0375..fe2df2178a5 100644 --- a/src/cpp/rtps/reader/StatefulReader.hpp +++ b/src/cpp/rtps/reader/StatefulReader.hpp @@ -304,6 +304,15 @@ class StatefulReader : public fastdds::rtps::BaseReader WriterProxy*& writer, bool mark_as_read) override; + /** + * @brief Fills the provided vector with the GUIDs of the matched writers. + * + * @param[out] guids Vector to be filled with the GUIDs of the matched writers. + * @return True if the operation was successful. + */ + bool matched_writers_guids( + std::vector& guids) const final; + #ifdef FASTDDS_STATISTICS bool get_connections( fastdds::statistics::rtps::ConnectionList& connection_list) override; diff --git a/src/cpp/rtps/reader/StatelessReader.cpp b/src/cpp/rtps/reader/StatelessReader.cpp index 4afa3a32a1e..bc23381222c 100644 --- a/src/cpp/rtps/reader/StatelessReader.cpp +++ b/src/cpp/rtps/reader/StatelessReader.cpp @@ -521,6 +521,19 @@ void StatelessReader::end_sample_access_nts( } } +bool StatelessReader::matched_writers_guids( + std::vector& guids) const +{ + std::lock_guard guard(mp_mutex); + guids.clear(); + guids.reserve(matched_writers_.size()); + for (const RemoteWriterInfo_t& writer : matched_writers_) + { + guids.push_back(writer.guid); + } + return true; +} + #ifdef FASTDDS_STATISTICS bool StatelessReader::get_connections( diff --git a/src/cpp/rtps/reader/StatelessReader.hpp b/src/cpp/rtps/reader/StatelessReader.hpp index 0bfb9169363..cc198634efc 100644 --- a/src/cpp/rtps/reader/StatelessReader.hpp +++ b/src/cpp/rtps/reader/StatelessReader.hpp @@ -227,6 +227,15 @@ class StatelessReader : public fastdds::rtps::BaseReader WriterProxy*& writer, bool mark_as_read) override; + /** + * @brief Fills the provided vector with the GUIDs of the matched writers. + * + * @param[out] guids Vector to be filled with the GUIDs of the matched writers. + * @return True if the operation was successful. + */ + bool matched_writers_guids( + std::vector& guids) const final; + #ifdef FASTDDS_STATISTICS bool get_connections( fastdds::statistics::rtps::ConnectionList& connection_list) override; diff --git a/src/cpp/rtps/writer/StatefulWriter.cpp b/src/cpp/rtps/writer/StatefulWriter.cpp index 779a5c5394f..058536f5e14 100644 --- a/src/cpp/rtps/writer/StatefulWriter.cpp +++ b/src/cpp/rtps/writer/StatefulWriter.cpp @@ -1604,6 +1604,22 @@ void StatefulWriter::update_attributes( } } +bool StatefulWriter::matched_readers_guids( + std::vector& guids) const +{ + std::lock_guard guard(mp_mutex); + guids.clear(); + for_matched_readers(matched_local_readers_, matched_datasharing_readers_, matched_remote_readers_, + [&guids](const ReaderProxy* reader) + { + guids.push_back(reader->guid()); + return false; + } + ); + + return true; +} + void StatefulWriter::update_positive_acks_times( const WriterAttributes& att) { diff --git a/src/cpp/rtps/writer/StatefulWriter.hpp b/src/cpp/rtps/writer/StatefulWriter.hpp index 5181ea1e75f..c81de5af951 100644 --- a/src/cpp/rtps/writer/StatefulWriter.hpp +++ b/src/cpp/rtps/writer/StatefulWriter.hpp @@ -90,6 +90,15 @@ class StatefulWriter : public BaseWriter return disable_positive_acks_; } + /** + * @brief Fills the provided vector with the GUIDs of the matched readers. + * + * @param[out] guids Vector to be filled with the GUIDs of the matched readers. + * @return True if the operation was successful. + */ + bool matched_readers_guids( + std::vector& guids) const final; + #ifdef FASTDDS_STATISTICS bool get_connections( fastdds::statistics::rtps::ConnectionList& connection_list) final; diff --git a/src/cpp/rtps/writer/StatelessWriter.cpp b/src/cpp/rtps/writer/StatelessWriter.cpp index d1d61d938e3..3412f53a390 100644 --- a/src/cpp/rtps/writer/StatelessWriter.cpp +++ b/src/cpp/rtps/writer/StatelessWriter.cpp @@ -398,6 +398,21 @@ bool StatelessWriter::get_disable_positive_acks() const return false; } +bool StatelessWriter::matched_readers_guids( + std::vector& guids) const +{ + std::lock_guard guard(mp_mutex); + guids.clear(); + for_matched_readers(matched_local_readers_, matched_datasharing_readers_, matched_remote_readers_, + [&guids](const ReaderLocator& reader) + { + guids.push_back(reader.remote_guid()); + return false; + } + ); + return true; +} + bool StatelessWriter::try_remove_change( const std::chrono::steady_clock::time_point&, std::unique_lock&) diff --git a/src/cpp/rtps/writer/StatelessWriter.hpp b/src/cpp/rtps/writer/StatelessWriter.hpp index b3226f3ea71..214655af774 100644 --- a/src/cpp/rtps/writer/StatelessWriter.hpp +++ b/src/cpp/rtps/writer/StatelessWriter.hpp @@ -97,6 +97,15 @@ class StatelessWriter : public BaseWriter bool get_disable_positive_acks() const final; + /** + * @brief Fills the provided vector with the GUIDs of the matched readers. + * + * @param[out] guids Vector to be filled with the GUIDs of the matched readers. + * @return True if the operation was successful. + */ + bool matched_readers_guids( + std::vector& guids) const final; + #ifdef FASTDDS_STATISTICS bool get_connections( fastdds::statistics::rtps::ConnectionList& connection_list) final; diff --git a/test/unittest/statistics/dds/StatisticsDomainParticipantStatusQueryableTests/mock/fastdds/publisher/DataWriterImpl.hpp b/test/unittest/statistics/dds/StatisticsDomainParticipantStatusQueryableTests/mock/fastdds/publisher/DataWriterImpl.hpp index 72ef193bbf1..0c79e1f824f 100644 --- a/test/unittest/statistics/dds/StatisticsDomainParticipantStatusQueryableTests/mock/fastdds/publisher/DataWriterImpl.hpp +++ b/test/unittest/statistics/dds/StatisticsDomainParticipantStatusQueryableTests/mock/fastdds/publisher/DataWriterImpl.hpp @@ -423,6 +423,25 @@ class DataWriterImpl : protected rtps::IReaderDataFilter } + ReturnCode_t get_matched_subscription_data( + SubscriptionBuiltinTopicData&, + const InstanceHandle_t& ) const + { + return RETCODE_ERROR; + } + + ReturnCode_t get_matched_subscriptions( + std::vector&) const + { + return RETCODE_ERROR; + } + + ReturnCode_t get_matched_subscriptions( + std::vector&) const + { + return RETCODE_ERROR; + } + //! Pointer to the associated Data Writer. fastdds::rtps::RTPSWriter* writer_ = nullptr; Topic* topic_ = nullptr; From 19cf8234f3422e71244c9abe671686429639755d Mon Sep 17 00:00:00 2001 From: Mario Dominguez Date: Wed, 9 Oct 2024 10:19:00 +0200 Subject: [PATCH 3/6] Refs #21808: versions.md Signed-off-by: Mario Dominguez --- versions.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/versions.md b/versions.md index d1a58c9c0ca..6d1c710e167 100644 --- a/versions.md +++ b/versions.md @@ -1,6 +1,11 @@ Forthcoming ----------- +* Added implementation for: + * `DataWriter::get_matched_subscription_data()` + * `DataWriter::get_matched_subscriptions()` + * `DataReader::get_matched_publication_data()` + * `DataReader::get_matched_publications()` Version v3.1.0 -------------- From a9444cc6663d26192f9ed612247b61b49652de83 Mon Sep 17 00:00:00 2001 From: Mario Dominguez Date: Wed, 9 Oct 2024 14:55:17 +0200 Subject: [PATCH 4/6] Refs #21808: Update UnsupportedData*Methods Signed-off-by: Mario Dominguez --- test/unittest/dds/publisher/DataWriterTests.cpp | 13 +------------ .../unittest/dds/subscriber/DataReaderTests.cpp | 17 +++-------------- 2 files changed, 4 insertions(+), 26 deletions(-) diff --git a/test/unittest/dds/publisher/DataWriterTests.cpp b/test/unittest/dds/publisher/DataWriterTests.cpp index 33a96c5ba53..33531113292 100644 --- a/test/unittest/dds/publisher/DataWriterTests.cpp +++ b/test/unittest/dds/publisher/DataWriterTests.cpp @@ -1733,9 +1733,7 @@ class DataWriterUnsupportedTests : public ::testing::Test /* * This test checks that the DataWriter methods defined in the standard not yet implemented in FastDDS return * RETCODE_UNSUPPORTED. The following methods are checked: - * 1. get_matched_subscription_data - * 2. get_matched_subscriptions - * 3. lookup_instance + * 1. lookup_instance */ TEST_F(DataWriterUnsupportedTests, UnsupportedDataWriterMethods) { @@ -1755,15 +1753,6 @@ TEST_F(DataWriterUnsupportedTests, UnsupportedDataWriterMethods) DataWriter* data_writer = publisher->create_datawriter(topic, DATAWRITER_QOS_DEFAULT); ASSERT_NE(publisher, nullptr); - SubscriptionBuiltinTopicData subscription_data; - fastdds::rtps::InstanceHandle_t subscription_handle; - EXPECT_EQ( - RETCODE_UNSUPPORTED, - data_writer->get_matched_subscription_data(subscription_data, subscription_handle)); - - std::vector subscription_handles; - EXPECT_EQ(RETCODE_UNSUPPORTED, data_writer->get_matched_subscriptions(subscription_handles)); - EXPECT_EQ(HANDLE_NIL, data_writer->lookup_instance(nullptr /* instance */)); // Expected logWarnings: lookup_instance diff --git a/test/unittest/dds/subscriber/DataReaderTests.cpp b/test/unittest/dds/subscriber/DataReaderTests.cpp index eca15be972c..a88925674e2 100644 --- a/test/unittest/dds/subscriber/DataReaderTests.cpp +++ b/test/unittest/dds/subscriber/DataReaderTests.cpp @@ -2623,11 +2623,9 @@ class DataReaderUnsupportedTests : public ::testing::Test /* * This test checks that the DataReader methods defined in the standard not yet implemented in FastDDS return * RETCODE_UNSUPPORTED. The following methods are checked: - * 1. get_matched_publication_data - * 2. create_querycondition - * 3. get_matched_publications - * 4. get_key_value - * 5. wait_for_historical_data + * 1. create_querycondition + * 2. get_key_value + * 3. wait_for_historical_data */ TEST_F(DataReaderUnsupportedTests, UnsupportedDataReaderMethods) { @@ -2648,12 +2646,6 @@ TEST_F(DataReaderUnsupportedTests, UnsupportedDataReaderMethods) DataReader* data_reader = subscriber->create_datareader(topic, DATAREADER_QOS_DEFAULT); ASSERT_NE(data_reader, nullptr); - PublicationBuiltinTopicData publication_data; - InstanceHandle_t publication_handle; - EXPECT_EQ( - RETCODE_UNSUPPORTED, - data_reader->get_matched_publication_data(publication_data, publication_handle)); - { SampleStateMask sample_states = ANY_SAMPLE_STATE; ViewStateMask view_states = ANY_VIEW_STATE; @@ -2670,9 +2662,6 @@ TEST_F(DataReaderUnsupportedTests, UnsupportedDataReaderMethods) query_parameters)); } - std::vector publication_handles; - EXPECT_EQ(RETCODE_UNSUPPORTED, data_reader->get_matched_publications(publication_handles)); - InstanceHandle_t key_handle; EXPECT_EQ(RETCODE_UNSUPPORTED, data_reader->get_key_value(nullptr, key_handle)); From 7559328e31a210a567dd08a25887337030abbcd0 Mon Sep 17 00:00:00 2001 From: Mario Dominguez Date: Fri, 18 Oct 2024 09:16:14 +0200 Subject: [PATCH 5/6] Refs #21808: Apply Ricardo's rev Signed-off-by: Mario Dominguez --- src/cpp/fastdds/publisher/DataWriterImpl.hpp | 16 ++++++++-------- src/cpp/fastdds/subscriber/DataReaderImpl.hpp | 14 +++++++------- src/cpp/rtps/participant/RTPSParticipantImpl.h | 8 ++++---- src/cpp/rtps/reader/StatefulReader.cpp | 2 +- src/cpp/rtps/reader/StatelessReader.cpp | 2 +- src/cpp/rtps/writer/StatefulWriter.cpp | 4 +++- src/cpp/rtps/writer/StatelessWriter.cpp | 3 ++- 7 files changed, 26 insertions(+), 23 deletions(-) diff --git a/src/cpp/fastdds/publisher/DataWriterImpl.hpp b/src/cpp/fastdds/publisher/DataWriterImpl.hpp index 346b80495ab..a4a3f29d369 100644 --- a/src/cpp/fastdds/publisher/DataWriterImpl.hpp +++ b/src/cpp/fastdds/publisher/DataWriterImpl.hpp @@ -382,12 +382,12 @@ class DataWriterImpl : protected rtps::IReaderDataFilter const char* filter_class_name); /** - * @brief Retrieves in a subscription associated with the DataWriter + * @brief Retrieves in a subscription associated with the @ref DataWriter * * @param[out] subscription_data subscription data struct - * @param subscription_handle InstanceHandle_t of the subscription - * @return RETCODE_BAD_PARAMETER if the DataWriter is not matched with - * the given subscription handle, RETCODE_OK otherwise. + * @param subscription_handle @ref InstanceHandle_t of the subscription + * @return @ref RETCODE_BAD_PARAMETER if the DataWriter is not matched with + * the given subscription handle, @ref RETCODE_OK otherwise. * */ ReturnCode_t get_matched_subscription_data( @@ -395,12 +395,12 @@ class DataWriterImpl : protected rtps::IReaderDataFilter const InstanceHandle_t& subscription_handle) const; /** - * @brief Fills the given vector with the InstanceHandle_t of matched DataReaders + * @brief Fills the given vector with the @ref InstanceHandle_t of matched DataReaders * - * @param[out] subscription_handles Vector where the InstanceHandle_t are returned - * @return RETCODE_OK if the operation succeeds. + * @param[out] subscription_handles Vector where the @ref InstanceHandle_t are returned + * @return @ref RETCODE_OK if the operation succeeds. * - * @note Returning an empty list is not an error, it returns RETCODE_OK. + * @note Returning an empty list is not an error, it returns @ref RETCODE_OK. * */ ReturnCode_t get_matched_subscriptions( diff --git a/src/cpp/fastdds/subscriber/DataReaderImpl.hpp b/src/cpp/fastdds/subscriber/DataReaderImpl.hpp index fba4ad91e09..1bc28dbbe26 100644 --- a/src/cpp/fastdds/subscriber/DataReaderImpl.hpp +++ b/src/cpp/fastdds/subscriber/DataReaderImpl.hpp @@ -238,9 +238,9 @@ class DataReaderImpl * @brief Retrieves in a publication associated with the DataWriter * * @param[out] publication_data publication data struct - * @param publication_handle InstanceHandle_t of the publication - * @return RETCODE_BAD_PARAMETER if the DataReader is not matched with - * the given publication handle, RETCODE_OK otherwise. + * @param publication_handle @ref InstanceHandle_t of the publication + * @return @ref RETCODE_BAD_PARAMETER if the DataReader is not matched with + * the given publication handle, @ref RETCODE_OK otherwise. * */ ReturnCode_t get_matched_publication_data( @@ -248,12 +248,12 @@ class DataReaderImpl const InstanceHandle_t& publication_handle) const; /** - * @brief Fills the given vector with the InstanceHandle_t of matched DataReaders + * @brief Fills the given vector with the @ref InstanceHandle_t of matched DataReaders * - * @param[out] publication_handles Vector where the InstanceHandle_t are returned - * @return RETCODE_OK if the operation succeeds. + * @param[out] publication_handles Vector where the @ref InstanceHandle_t are returned + * @return @ref RETCODE_OK if the operation succeeds. * - * @note Returning an empty list is not an error, it returns RETCODE_OK. + * @note Returning an empty list is not an error, it returns @ref RETCODE_OK. * */ ReturnCode_t get_matched_publications( diff --git a/src/cpp/rtps/participant/RTPSParticipantImpl.h b/src/cpp/rtps/participant/RTPSParticipantImpl.h index 37310c75b7e..e79c0a947fc 100644 --- a/src/cpp/rtps/participant/RTPSParticipantImpl.h +++ b/src/cpp/rtps/participant/RTPSParticipantImpl.h @@ -1121,10 +1121,10 @@ class RTPSParticipantImpl std::vector get_netmask_filter_info() const; /** - * @brief Fills the provided PublicationBuiltinTopicData with the information of the + * @brief Fills the provided @ref PublicationBuiltinTopicData with the information of the * writer identified by writer_guid. * - * @param[out] data PublicationBuiltinTopicData to fill. + * @param[out] data @ref PublicationBuiltinTopicData to fill. * @param[in] writer_guid GUID of the writer to get the information from. * @return True if the writer was found and the data was filled. */ @@ -1133,10 +1133,10 @@ class RTPSParticipantImpl const GUID_t& writer_guid) const; /** - * @brief Fills the provided SubscriptionBuiltinTopicData with the information of the + * @brief Fills the provided @ref SubscriptionBuiltinTopicData with the information of the * reader identified by reader_guid. * - * @param[out] data SubscriptionBuiltinTopicData to fill. + * @param[out] data @ref SubscriptionBuiltinTopicData to fill. * @param[in] reader_guid GUID of the reader to get the information from. * @return True if the reader was found and the data was filled. */ diff --git a/src/cpp/rtps/reader/StatefulReader.cpp b/src/cpp/rtps/reader/StatefulReader.cpp index 403bf5b6bec..cf7a201da7b 100644 --- a/src/cpp/rtps/reader/StatefulReader.cpp +++ b/src/cpp/rtps/reader/StatefulReader.cpp @@ -1500,7 +1500,7 @@ bool StatefulReader::matched_writers_guids( guids.reserve(matched_writers_.size()); for (WriterProxy* writer : matched_writers_) { - guids.push_back(writer->guid()); + guids.emplace_back(writer->guid()); } return true; } diff --git a/src/cpp/rtps/reader/StatelessReader.cpp b/src/cpp/rtps/reader/StatelessReader.cpp index bc23381222c..91b5bd0ad33 100644 --- a/src/cpp/rtps/reader/StatelessReader.cpp +++ b/src/cpp/rtps/reader/StatelessReader.cpp @@ -529,7 +529,7 @@ bool StatelessReader::matched_writers_guids( guids.reserve(matched_writers_.size()); for (const RemoteWriterInfo_t& writer : matched_writers_) { - guids.push_back(writer.guid); + guids.emplace_back(writer.guid); } return true; } diff --git a/src/cpp/rtps/writer/StatefulWriter.cpp b/src/cpp/rtps/writer/StatefulWriter.cpp index 058536f5e14..a8c8881a774 100644 --- a/src/cpp/rtps/writer/StatefulWriter.cpp +++ b/src/cpp/rtps/writer/StatefulWriter.cpp @@ -1609,10 +1609,12 @@ bool StatefulWriter::matched_readers_guids( { std::lock_guard guard(mp_mutex); guids.clear(); + guids.reserve(guids.size() + matched_local_readers_.size() + matched_datasharing_readers_.size() + + matched_remote_readers_.size()); for_matched_readers(matched_local_readers_, matched_datasharing_readers_, matched_remote_readers_, [&guids](const ReaderProxy* reader) { - guids.push_back(reader->guid()); + guids.emplace_back(reader->guid()); return false; } ); diff --git a/src/cpp/rtps/writer/StatelessWriter.cpp b/src/cpp/rtps/writer/StatelessWriter.cpp index 3412f53a390..be63703897f 100644 --- a/src/cpp/rtps/writer/StatelessWriter.cpp +++ b/src/cpp/rtps/writer/StatelessWriter.cpp @@ -403,10 +403,11 @@ bool StatelessWriter::matched_readers_guids( { std::lock_guard guard(mp_mutex); guids.clear(); + guids.reserve(matched_local_readers_.size() + matched_datasharing_readers_.size() + matched_remote_readers_.size()); for_matched_readers(matched_local_readers_, matched_datasharing_readers_, matched_remote_readers_, [&guids](const ReaderLocator& reader) { - guids.push_back(reader.remote_guid()); + guids.emplace_back(reader.remote_guid()); return false; } ); From e15e72e100902bb85c56a0c2d844e14001dc77f0 Mon Sep 17 00:00:00 2001 From: Mario-DL Date: Thu, 24 Oct 2024 10:06:32 +0200 Subject: [PATCH 6/6] Refs #21808: Apply last suggestion Signed-off-by: Mario-DL --- src/cpp/rtps/writer/StatefulWriter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpp/rtps/writer/StatefulWriter.cpp b/src/cpp/rtps/writer/StatefulWriter.cpp index a8c8881a774..8e5574c2679 100644 --- a/src/cpp/rtps/writer/StatefulWriter.cpp +++ b/src/cpp/rtps/writer/StatefulWriter.cpp @@ -1609,7 +1609,7 @@ bool StatefulWriter::matched_readers_guids( { std::lock_guard guard(mp_mutex); guids.clear(); - guids.reserve(guids.size() + matched_local_readers_.size() + matched_datasharing_readers_.size() + + guids.reserve(matched_local_readers_.size() + matched_datasharing_readers_.size() + matched_remote_readers_.size()); for_matched_readers(matched_local_readers_, matched_datasharing_readers_, matched_remote_readers_, [&guids](const ReaderProxy* reader)