Skip to content

Commit

Permalink
Select correct listener for on_requested_deadline_missed (#3423)
Browse files Browse the repository at this point in the history
* Refs #17961: Regression test for segfault

Signed-off-by: Eduardo Ponz <[email protected]>

* Refs #17961: Use the correct listener for deadline

Signed-off-by: Eduardo Ponz <[email protected]>

* Refs #17961: Fixed Windows warning regarding double to uint32 cast

Signed-off-by: Javier Santiago <[email protected]>

* Refs #17961: Test fix

Signed-off-by: Mario Dominguez <[email protected]>

---------

Signed-off-by: Eduardo Ponz <[email protected]>
Signed-off-by: Javier Santiago <[email protected]>
Signed-off-by: Mario Dominguez <[email protected]>
Co-authored-by: Javier Santiago <[email protected]>
Co-authored-by: Mario Dominguez <[email protected]>
(cherry picked from commit 40411d9)

# Conflicts:
#	test/blackbox/common/DDSBlackboxTestsDataWriter.cpp
  • Loading branch information
EduPonz authored and mergify[bot] committed Apr 14, 2023
1 parent d3fcd58 commit a17b324
Show file tree
Hide file tree
Showing 2 changed files with 176 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/cpp/fastdds/publisher/DataWriterImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1304,7 +1304,7 @@ bool DataWriterImpl::deadline_missed()
auto listener = get_listener_for(notify_status);
if (nullptr != listener)
{
listener_->on_offered_deadline_missed(user_datawriter_, deadline_missed_status_);
listener->on_offered_deadline_missed(user_datawriter_, deadline_missed_status_);
deadline_missed_status_.total_count_change = 0;
}
user_datawriter_->get_statuscondition().get_impl()->set_status(notify_status, true);
Expand Down
175 changes: 175 additions & 0 deletions test/blackbox/common/DDSBlackboxTestsDataWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.

#include <chrono>

#include "BlackboxTests.hpp"

#include "PubSubReader.hpp"
Expand Down Expand Up @@ -197,6 +199,179 @@ TEST_P(DDSDataWriter, GetKeyValue)
EXPECT_EQ(valid_data.key(), data.key());
}

<<<<<<< HEAD
=======
TEST_P(DDSDataWriter, WithTimestampOperations)
{
using namespace eprosima::fastdds::dds;

// Test variables
eprosima::fastrtps::Time_t ts;

KeyedHelloWorld valid_data;
valid_data.key(27);
valid_data.index(1);
valid_data.message("HelloWorld");

// Create and initialize reader
PubSubReader<KeyedHelloWorldPubSubType> reader(TEST_TOPIC_NAME);
reader.durability_kind(eprosima::fastrtps::TRANSIENT_LOCAL_DURABILITY_QOS)
.reliability(eprosima::fastrtps::RELIABLE_RELIABILITY_QOS)
.history_depth(10)
.init();
ASSERT_TRUE(reader.isInitialized());
DataReader& datareader = reader.get_native_reader();

// Create and initialize writer
PubSubWriter<KeyedHelloWorldPubSubType> writer(TEST_TOPIC_NAME);
writer.durability_kind(eprosima::fastrtps::TRANSIENT_LOCAL_DURABILITY_QOS)
.reliability(eprosima::fastrtps::RELIABLE_RELIABILITY_QOS)
.history_depth(10)
.init();
ASSERT_TRUE(writer.isInitialized());
DataWriter& datawriter = writer.get_native_writer();
DataWriterQos qos = datawriter.get_qos();
qos.writer_data_lifecycle().autodispose_unregistered_instances = false;
EXPECT_EQ(ReturnCode_t::RETCODE_OK, datawriter.set_qos(qos));

// Wait discovery, since we are going to unregister an instance
reader.wait_discovery();
writer.wait_discovery();

ts.seconds = 0;
ts.nanosec = 1;
// Register with custom timestamp
EXPECT_NE(HANDLE_NIL, datawriter.register_instance_w_timestamp(&valid_data, ts));
// TODO(MiguelCompay): Remove the following line when register_instance operation gets propagated to the reader.
// See redmine issue #14494
ts.nanosec--;
// Write with custom timestamp
ts.nanosec++;
EXPECT_EQ(ReturnCode_t::RETCODE_OK, datawriter.write_w_timestamp(&valid_data, HANDLE_NIL, ts));
// Dispose with custom timestamp
ts.nanosec++;
EXPECT_EQ(ReturnCode_t::RETCODE_OK, datawriter.dispose_w_timestamp(&valid_data, HANDLE_NIL, ts));
// Write with custom timestamp
ts.nanosec++;
EXPECT_EQ(ReturnCode_t::RETCODE_OK, datawriter.write_w_timestamp(&valid_data, HANDLE_NIL, ts));
// Unregister with custom timestamp
ts.nanosec++;
EXPECT_EQ(ReturnCode_t::RETCODE_OK, datawriter.unregister_instance_w_timestamp(&valid_data, HANDLE_NIL, ts));

// Wait and take all data
auto num_samples = ts.nanosec;
while (num_samples != datareader.get_unread_count())
{
EXPECT_TRUE(datareader.wait_for_unread_message({ 10, 0 }));
}

FASTDDS_CONST_SEQUENCE(DataSeq, KeyedHelloWorld);
SampleInfoSeq infos;
DataSeq datas;
EXPECT_EQ(ReturnCode_t::RETCODE_OK, datareader.take(datas, infos));

// Check received timestamps
ts.seconds = 0;
ts.nanosec = 1;
EXPECT_EQ(static_cast<decltype(num_samples)>(infos.length()), num_samples);
for (SampleInfoSeq::size_type n = 0; n < infos.length(); ++n)
{
EXPECT_EQ(ts, infos[n].source_timestamp);
ts.nanosec++;
}

EXPECT_EQ(ReturnCode_t::RETCODE_OK, datareader.return_loan(datas, infos));
}

/**
* Regression test for EasyRedmine issue https://eprosima.easyredmine.com/issues/17961
*
* The test:
* 1. Creates a DomainParticipant with a listener which captures the offered_deadline_missed
* events.
* 2. Creates a DataWriter with a 1 ms deadline period, without any listener and that never
* publishes data.
* 3. Wait for the deadline callback to be triggered at least once within a second.
* 4. Checks that the callback was indeed triggered.
*/

TEST(DDSDataWriter, OfferedDeadlineMissedListener)
{
using namespace eprosima::fastdds::dds;

class WriterWrapper : public DomainParticipantListener
{
public:

WriterWrapper(
std::condition_variable& cv,
std::atomic_bool& deadline_called)
: cv_(cv)
, deadline_called_(deadline_called)
{
StatusMask status_mask = StatusMask::none();
status_mask << StatusMask::offered_deadline_missed();
participant_ = DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT,
this, status_mask);

type_support_.reset(new HelloWorldPubSubType());
type_support_.register_type(participant_, "DeadlineListenerTest");

topic_ = participant_->create_topic("deadline_listener_test", "DeadlineListenerTest", TOPIC_QOS_DEFAULT);

publisher_ = participant_->create_publisher(PUBLISHER_QOS_DEFAULT);

DataWriterQos dw_qos = DATAWRITER_QOS_DEFAULT;
dw_qos.deadline().period = Time_t(0, 1000000);
datawriter_ = publisher_->create_datawriter(
topic_,
dw_qos);

// Apparently the time is not started until the first data is published
HelloWorld data;
datawriter_->write(&data);
}

virtual ~WriterWrapper()
{
participant_->delete_contained_entities();
DomainParticipantFactory::get_instance()->delete_participant(participant_);
}

void on_offered_deadline_missed(
DataWriter* /* writer */,
const OfferedDeadlineMissedStatus& /* status */) override
{
deadline_called_.store(true);
cv_.notify_one();
}

protected:

std::condition_variable& cv_;
std::atomic_bool& deadline_called_;
DomainParticipant* participant_;
TypeSupport type_support_;
Topic* topic_;
Publisher* publisher_;
DataWriter* datawriter_;
};

std::mutex mtx;
std::condition_variable cv;
std::atomic_bool deadline_called{false};
std::unique_lock<std::mutex> lck(mtx);

WriterWrapper writer_w(cv, deadline_called);

auto ret = cv.wait_for(lck, std::chrono::seconds(1), [&]()
{
return deadline_called.load();
});
ASSERT_TRUE(ret);
}

>>>>>>> 40411d968 (Select correct listener for on_requested_deadline_missed (#3423))
#ifdef INSTANTIATE_TEST_SUITE_P
#define GTEST_INSTANTIATE_TEST_MACRO(x, y, z, w) INSTANTIATE_TEST_SUITE_P(x, y, z, w)
#else
Expand Down

0 comments on commit a17b324

Please sign in to comment.