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"