From 828d67c15ba259a05189769e28a1b88ceb1121ef Mon Sep 17 00:00:00 2001 From: Miguel Company Date: Thu, 4 Mar 2021 15:22:29 +0100 Subject: [PATCH 1/6] Refs 10756. Add method on DataReaderImpl. Signed-off-by: Miguel Company --- src/cpp/fastdds/subscriber/DataReaderImpl.cpp | 5 +++++ src/cpp/fastdds/subscriber/DataReaderImpl.hpp | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/cpp/fastdds/subscriber/DataReaderImpl.cpp b/src/cpp/fastdds/subscriber/DataReaderImpl.cpp index c3e833f5cf5..b935b61230c 100644 --- a/src/cpp/fastdds/subscriber/DataReaderImpl.cpp +++ b/src/cpp/fastdds/subscriber/DataReaderImpl.cpp @@ -657,6 +657,11 @@ ReturnCode_t DataReaderImpl::get_first_untaken_info( return ReturnCode_t::RETCODE_NO_DATA; } +uint64_t DataReaderImpl::get_unread_count() const +{ + return reader_ ? reader_->get_unread_count() : 0; +} + const GUID_t& DataReaderImpl::guid() const { return reader_ ? reader_->getGuid() : c_Guid_Unknown; diff --git a/src/cpp/fastdds/subscriber/DataReaderImpl.hpp b/src/cpp/fastdds/subscriber/DataReaderImpl.hpp index 1221af0dd01..362e99c7a1c 100644 --- a/src/cpp/fastdds/subscriber/DataReaderImpl.hpp +++ b/src/cpp/fastdds/subscriber/DataReaderImpl.hpp @@ -193,6 +193,11 @@ class DataReaderImpl ReturnCode_t get_first_untaken_info( SampleInfo* info); + /** + * @return the number of samples pending to be read. + */ + uint64_t get_unread_count() const; + /** * Get associated GUID * @return Associated GUID From f34f18769381646019dc4871fa3b7a90bd5cf73e Mon Sep 17 00:00:00 2001 From: Miguel Company Date: Thu, 4 Mar 2021 15:22:56 +0100 Subject: [PATCH 2/6] Refs 10756. Add method on DataReader. Signed-off-by: Miguel Company --- include/fastdds/dds/subscriber/DataReader.hpp | 9 +++++++++ src/cpp/fastdds/subscriber/DataReader.cpp | 5 +++++ 2 files changed, 14 insertions(+) diff --git a/include/fastdds/dds/subscriber/DataReader.hpp b/include/fastdds/dds/subscriber/DataReader.hpp index c72c96f0b42..c64a7541b44 100644 --- a/include/fastdds/dds/subscriber/DataReader.hpp +++ b/include/fastdds/dds/subscriber/DataReader.hpp @@ -765,6 +765,15 @@ class DataReader : public DomainEntity RTPS_DllAPI ReturnCode_t get_first_untaken_info( SampleInfo* info); + /** + * Get the number of samples pending to be read. + * The number includes samples that may not yet be available to be read or taken by the user, due to samples + * being received out of order. + * + * @return the number of samples on the reader history that have never been read. + */ + RTPS_DllAPI uint64_t get_unread_count() const; + /** * Get associated GUID. * diff --git a/src/cpp/fastdds/subscriber/DataReader.cpp b/src/cpp/fastdds/subscriber/DataReader.cpp index da83cc7b09c..e8be250bfde 100644 --- a/src/cpp/fastdds/subscriber/DataReader.cpp +++ b/src/cpp/fastdds/subscriber/DataReader.cpp @@ -252,6 +252,11 @@ ReturnCode_t DataReader::get_first_untaken_info( return impl_->get_first_untaken_info(info); } +uint64_t DataReader::get_unread_count() const +{ + return impl_->get_unread_count(); +} + const GUID_t& DataReader::guid() { return impl_->guid(); From 5d82fc1da1e04b11cd4c48e985373a17cce5d309 Mon Sep 17 00:00:00 2001 From: Miguel Company Date: Thu, 4 Mar 2021 15:24:36 +0100 Subject: [PATCH 3/6] Refs 10756. Add new feature on versions.md. Signed-off-by: Miguel Company --- versions.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/versions.md b/versions.md index f915d662b3b..920c071d937 100644 --- a/versions.md +++ b/versions.md @@ -1,6 +1,8 @@ Forthcoming ----------- +* Added eprosima::fastdds::dds::DataReader::get_unread_count (ABI break) + Version 2.2.0 ------------- From ec5b8174bc9275b5601a584eca6e04231d17c433 Mon Sep 17 00:00:00 2001 From: Miguel Company Date: Thu, 4 Mar 2021 16:27:47 +0100 Subject: [PATCH 4/6] Refs 10756. Add get_unread_count to RTPSReader mock. Signed-off-by: Miguel Company --- test/mock/rtps/RTPSReader/fastdds/rtps/reader/RTPSReader.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/mock/rtps/RTPSReader/fastdds/rtps/reader/RTPSReader.h b/test/mock/rtps/RTPSReader/fastdds/rtps/reader/RTPSReader.h index bf6c5d0d774..f955ca73a0e 100644 --- a/test/mock/rtps/RTPSReader/fastdds/rtps/reader/RTPSReader.h +++ b/test/mock/rtps/RTPSReader/fastdds/rtps/reader/RTPSReader.h @@ -93,6 +93,8 @@ class RTPSReader : public Endpoint MOCK_METHOD1(wait_for_unread_cache, bool (const eprosima::fastrtps::Duration_t& timeout)); + MOCK_METHOD0(get_unread_count, uint64_t()); + // *INDENT-ON* From a1e31aabcab13884506b471aee76286c10d08b66 Mon Sep 17 00:00:00 2001 From: Miguel Company Date: Thu, 4 Mar 2021 16:28:32 +0100 Subject: [PATCH 5/6] Refs 10756. Added checks for get_unread_count to DataReaderTests. Signed-off-by: Miguel Company --- .../dds/subscriber/DataReaderTests.cpp | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/test/unittest/dds/subscriber/DataReaderTests.cpp b/test/unittest/dds/subscriber/DataReaderTests.cpp index 50de0004eff..92d5971b364 100644 --- a/test/unittest/dds/subscriber/DataReaderTests.cpp +++ b/test/unittest/dds/subscriber/DataReaderTests.cpp @@ -497,6 +497,7 @@ class DataReaderTests : public ::testing::Test create_entities(nullptr, reader_qos, subscriber_qos); EXPECT_FALSE(data_reader_->is_enabled()); + EXPECT_EQ(0, data_reader_->get_unread_count()); // Read / take operations should all return NOT_ENABLED basic_read_apis_check(ReturnCode_t::RETCODE_NOT_ENABLED, data_reader_); @@ -1240,6 +1241,7 @@ TEST_F(DataReaderTests, read_unread) // There are unread samples, so wait_for_unread should be ok EXPECT_TRUE(data_reader_->wait_for_unread_message(time_to_wait)); + EXPECT_EQ(num_samples, data_reader_->get_unread_count()); // Trying to get READ samples should return NO_DATA { @@ -1268,36 +1270,49 @@ TEST_F(DataReaderTests, read_unread) FooSeq data_seq[6]; SampleInfoSeq info_seq[6]; + // Current state: {R, N, N, N, N, N, N, N, N, N} + EXPECT_EQ(num_samples, data_reader_->get_unread_count()); + // This should return the first sample EXPECT_EQ(ok_code, data_reader_->read(data_seq[0], info_seq[0], 1, NOT_READ_SAMPLE_STATE)); check_collection(data_seq[0], false, 1, 1); check_sample_values(data_seq[0], "0"); // Current state: {R, N, N, N, N, N, N, N, N, N} + EXPECT_EQ(num_samples - 1, data_reader_->get_unread_count()); + // This should return the first sample EXPECT_EQ(ok_code, data_reader_->read(data_seq[1], info_seq[1], 1, READ_SAMPLE_STATE)); check_collection(data_seq[1], false, 1, 1); check_sample_values(data_seq[1], "0"); // Current state: {R, N, N, N, N, N, N, N, N, N} + EXPECT_EQ(num_samples - 1, data_reader_->get_unread_count()); + // This should return the first sample EXPECT_EQ(ok_code, data_reader_->read(data_seq[2], info_seq[2], LENGTH_UNLIMITED, READ_SAMPLE_STATE)); check_collection(data_seq[2], false, 1, 1); check_sample_values(data_seq[2], "0"); // Current state: {R, N, N, N, N, N, N, N, N, N} + EXPECT_EQ(num_samples - 1, data_reader_->get_unread_count()); + // This should return the second sample EXPECT_EQ(ok_code, data_reader_->read(data_seq[3], info_seq[3], 1, NOT_READ_SAMPLE_STATE)); check_collection(data_seq[3], false, 1, 1); check_sample_values(data_seq[3], "1"); // Current state: {R, R, N, N, N, N, N, N, N, N} + EXPECT_EQ(num_samples - 2, data_reader_->get_unread_count()); + // This should return the first sample EXPECT_EQ(ok_code, data_reader_->read(data_seq[4], info_seq[4], 1, READ_SAMPLE_STATE)); check_collection(data_seq[4], false, 1, 1); check_sample_values(data_seq[4], "0"); // Current state: {R, R, N, N, N, N, N, N, N, N} + EXPECT_EQ(num_samples - 2, data_reader_->get_unread_count()); + // This should return the first and second samples EXPECT_EQ(ok_code, data_reader_->read(data_seq[5], info_seq[5], LENGTH_UNLIMITED, READ_SAMPLE_STATE)); check_collection(data_seq[5], false, 2, 2); @@ -1319,45 +1334,61 @@ TEST_F(DataReaderTests, read_unread) SampleInfoSeq info_seq[6]; // Current state: {R, R, N, N, N, N, N, N, N, N} + EXPECT_EQ(num_samples - 2, data_reader_->get_unread_count()); + // This should return the third sample EXPECT_EQ(ok_code, data_reader_->take(data_seq[0], info_seq[0], 1, NOT_READ_SAMPLE_STATE)); check_collection(data_seq[0], false, 1, 1); check_sample_values(data_seq[0], "2"); // Current state: {R, R, /, N, N, N, N, N, N, N} + EXPECT_EQ(num_samples - 3, data_reader_->get_unread_count()); + // This should return the first sample EXPECT_EQ(ok_code, data_reader_->take(data_seq[1], info_seq[1], 1, READ_SAMPLE_STATE)); check_collection(data_seq[1], false, 1, 1); check_sample_values(data_seq[1], "0"); // Current state: {/, R, /, N, N, N, N, N, N, N} + EXPECT_EQ(num_samples - 3, data_reader_->get_unread_count()); + // This should return samples 2 and 4 EXPECT_EQ(ok_code, data_reader_->take(data_seq[2], info_seq[2], 2)); check_collection(data_seq[2], false, 2, 2); check_sample_values(data_seq[2], "13"); // Current state: {/, /, /, /, N, N, N, N, N, N} + EXPECT_EQ(num_samples - 4, data_reader_->get_unread_count()); + // This should return no data EXPECT_EQ(no_data_code, data_reader_->take(data_seq[3], info_seq[3], LENGTH_UNLIMITED, READ_SAMPLE_STATE)); check_collection(data_seq[3], true, 0, 0); // Current state: {/, /, /, /, N, N, N, N, N, N} + EXPECT_EQ(num_samples - 4, data_reader_->get_unread_count()); + // This should return samples 5 and 6 EXPECT_EQ(ok_code, data_reader_->read(data_seq[3], info_seq[3], 2)); check_collection(data_seq[3], false, 2, 2); check_sample_values(data_seq[3], "45"); // Current state: {/, /, /, /, R, R, N, N, N, N} + EXPECT_EQ(num_samples - 6, data_reader_->get_unread_count()); + // This should return samples 7, ... num_samples EXPECT_EQ(ok_code, data_reader_->take(data_seq[4], info_seq[4], LENGTH_UNLIMITED, NOT_READ_SAMPLE_STATE)); check_collection(data_seq[4], false, num_samples - 6, num_samples - 6); check_sample_values(data_seq[4], "6789"); // Current state: {/, /, /, /, R, R, /, /, /, /} + EXPECT_EQ(num_samples - 10, data_reader_->get_unread_count()); + // There are not unread samples, so wait_for_unread should return false EXPECT_FALSE(data_reader_->wait_for_unread_message(time_to_wait)); // Current state: {/, /, /, /, R, R, /, /, /, /} + EXPECT_EQ(num_samples - 10, data_reader_->get_unread_count()); + // Add a new sample to have a NOT_READ one data.message()[0] = 'A'; EXPECT_EQ(ok_code, data_writer_->write(&data, handle_ok_)); @@ -1366,12 +1397,16 @@ TEST_F(DataReaderTests, read_unread) EXPECT_TRUE(data_reader_->wait_for_unread_message(time_to_wait)); // Current state: {/, /, /, /, R, R, /, /, /, /, N} + EXPECT_EQ(num_samples - 10 + 1, data_reader_->get_unread_count()); + // This should return samples 5, 6 and new EXPECT_EQ(ok_code, data_reader_->take(data_seq[5], info_seq[5])); check_collection(data_seq[5], false, 3, 3); check_sample_values(data_seq[5], "45A"); // Current state: {/, /, /, /, /, /, /, /, /, /, /} + EXPECT_EQ(num_samples - 10 + 1 - 1, data_reader_->get_unread_count()); + // There are not unread samples, so wait_for_unread should return false EXPECT_FALSE(data_reader_->wait_for_unread_message(time_to_wait)); From 45d16b64d317df2085cff2ef8fa27384610f562c Mon Sep 17 00:00:00 2001 From: Miguel Company Date: Fri, 5 Mar 2021 07:30:57 +0100 Subject: [PATCH 6/6] Refs 10756. Fix warnings on Mac. Signed-off-by: Miguel Company --- .../dds/subscriber/DataReaderTests.cpp | 37 ++++++++++--------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/test/unittest/dds/subscriber/DataReaderTests.cpp b/test/unittest/dds/subscriber/DataReaderTests.cpp index 92d5971b364..53fdb3a8755 100644 --- a/test/unittest/dds/subscriber/DataReaderTests.cpp +++ b/test/unittest/dds/subscriber/DataReaderTests.cpp @@ -497,7 +497,7 @@ class DataReaderTests : public ::testing::Test create_entities(nullptr, reader_qos, subscriber_qos); EXPECT_FALSE(data_reader_->is_enabled()); - EXPECT_EQ(0, data_reader_->get_unread_count()); + EXPECT_EQ(0ull, data_reader_->get_unread_count()); // Read / take operations should all return NOT_ENABLED basic_read_apis_check(ReturnCode_t::RETCODE_NOT_ENABLED, data_reader_); @@ -1205,6 +1205,7 @@ TEST_F(DataReaderTests, read_unread) { static const Duration_t time_to_wait(0, 100 * 1000 * 1000); static constexpr int32_t num_samples = 10; + static constexpr uint64_t num_samples_check = static_cast(num_samples); const ReturnCode_t& ok_code = ReturnCode_t::RETCODE_OK; const ReturnCode_t& no_data_code = ReturnCode_t::RETCODE_NO_DATA; @@ -1241,7 +1242,7 @@ TEST_F(DataReaderTests, read_unread) // There are unread samples, so wait_for_unread should be ok EXPECT_TRUE(data_reader_->wait_for_unread_message(time_to_wait)); - EXPECT_EQ(num_samples, data_reader_->get_unread_count()); + EXPECT_EQ(num_samples_check, data_reader_->get_unread_count()); // Trying to get READ samples should return NO_DATA { @@ -1271,7 +1272,7 @@ TEST_F(DataReaderTests, read_unread) SampleInfoSeq info_seq[6]; // Current state: {R, N, N, N, N, N, N, N, N, N} - EXPECT_EQ(num_samples, data_reader_->get_unread_count()); + EXPECT_EQ(num_samples_check, data_reader_->get_unread_count()); // This should return the first sample EXPECT_EQ(ok_code, data_reader_->read(data_seq[0], info_seq[0], 1, NOT_READ_SAMPLE_STATE)); @@ -1279,7 +1280,7 @@ TEST_F(DataReaderTests, read_unread) check_sample_values(data_seq[0], "0"); // Current state: {R, N, N, N, N, N, N, N, N, N} - EXPECT_EQ(num_samples - 1, data_reader_->get_unread_count()); + EXPECT_EQ(num_samples_check - 1, data_reader_->get_unread_count()); // This should return the first sample EXPECT_EQ(ok_code, data_reader_->read(data_seq[1], info_seq[1], 1, READ_SAMPLE_STATE)); @@ -1287,7 +1288,7 @@ TEST_F(DataReaderTests, read_unread) check_sample_values(data_seq[1], "0"); // Current state: {R, N, N, N, N, N, N, N, N, N} - EXPECT_EQ(num_samples - 1, data_reader_->get_unread_count()); + EXPECT_EQ(num_samples_check - 1, data_reader_->get_unread_count()); // This should return the first sample EXPECT_EQ(ok_code, data_reader_->read(data_seq[2], info_seq[2], LENGTH_UNLIMITED, READ_SAMPLE_STATE)); @@ -1295,7 +1296,7 @@ TEST_F(DataReaderTests, read_unread) check_sample_values(data_seq[2], "0"); // Current state: {R, N, N, N, N, N, N, N, N, N} - EXPECT_EQ(num_samples - 1, data_reader_->get_unread_count()); + EXPECT_EQ(num_samples_check - 1, data_reader_->get_unread_count()); // This should return the second sample EXPECT_EQ(ok_code, data_reader_->read(data_seq[3], info_seq[3], 1, NOT_READ_SAMPLE_STATE)); @@ -1303,7 +1304,7 @@ TEST_F(DataReaderTests, read_unread) check_sample_values(data_seq[3], "1"); // Current state: {R, R, N, N, N, N, N, N, N, N} - EXPECT_EQ(num_samples - 2, data_reader_->get_unread_count()); + EXPECT_EQ(num_samples_check - 2, data_reader_->get_unread_count()); // This should return the first sample EXPECT_EQ(ok_code, data_reader_->read(data_seq[4], info_seq[4], 1, READ_SAMPLE_STATE)); @@ -1311,7 +1312,7 @@ TEST_F(DataReaderTests, read_unread) check_sample_values(data_seq[4], "0"); // Current state: {R, R, N, N, N, N, N, N, N, N} - EXPECT_EQ(num_samples - 2, data_reader_->get_unread_count()); + EXPECT_EQ(num_samples_check - 2, data_reader_->get_unread_count()); // This should return the first and second samples EXPECT_EQ(ok_code, data_reader_->read(data_seq[5], info_seq[5], LENGTH_UNLIMITED, READ_SAMPLE_STATE)); @@ -1334,7 +1335,7 @@ TEST_F(DataReaderTests, read_unread) SampleInfoSeq info_seq[6]; // Current state: {R, R, N, N, N, N, N, N, N, N} - EXPECT_EQ(num_samples - 2, data_reader_->get_unread_count()); + EXPECT_EQ(num_samples_check - 2, data_reader_->get_unread_count()); // This should return the third sample EXPECT_EQ(ok_code, data_reader_->take(data_seq[0], info_seq[0], 1, NOT_READ_SAMPLE_STATE)); @@ -1342,7 +1343,7 @@ TEST_F(DataReaderTests, read_unread) check_sample_values(data_seq[0], "2"); // Current state: {R, R, /, N, N, N, N, N, N, N} - EXPECT_EQ(num_samples - 3, data_reader_->get_unread_count()); + EXPECT_EQ(num_samples_check - 3, data_reader_->get_unread_count()); // This should return the first sample EXPECT_EQ(ok_code, data_reader_->take(data_seq[1], info_seq[1], 1, READ_SAMPLE_STATE)); @@ -1350,7 +1351,7 @@ TEST_F(DataReaderTests, read_unread) check_sample_values(data_seq[1], "0"); // Current state: {/, R, /, N, N, N, N, N, N, N} - EXPECT_EQ(num_samples - 3, data_reader_->get_unread_count()); + EXPECT_EQ(num_samples_check - 3, data_reader_->get_unread_count()); // This should return samples 2 and 4 EXPECT_EQ(ok_code, data_reader_->take(data_seq[2], info_seq[2], 2)); @@ -1358,14 +1359,14 @@ TEST_F(DataReaderTests, read_unread) check_sample_values(data_seq[2], "13"); // Current state: {/, /, /, /, N, N, N, N, N, N} - EXPECT_EQ(num_samples - 4, data_reader_->get_unread_count()); + EXPECT_EQ(num_samples_check - 4, data_reader_->get_unread_count()); // This should return no data EXPECT_EQ(no_data_code, data_reader_->take(data_seq[3], info_seq[3], LENGTH_UNLIMITED, READ_SAMPLE_STATE)); check_collection(data_seq[3], true, 0, 0); // Current state: {/, /, /, /, N, N, N, N, N, N} - EXPECT_EQ(num_samples - 4, data_reader_->get_unread_count()); + EXPECT_EQ(num_samples_check - 4, data_reader_->get_unread_count()); // This should return samples 5 and 6 EXPECT_EQ(ok_code, data_reader_->read(data_seq[3], info_seq[3], 2)); @@ -1373,7 +1374,7 @@ TEST_F(DataReaderTests, read_unread) check_sample_values(data_seq[3], "45"); // Current state: {/, /, /, /, R, R, N, N, N, N} - EXPECT_EQ(num_samples - 6, data_reader_->get_unread_count()); + EXPECT_EQ(num_samples_check - 6, data_reader_->get_unread_count()); // This should return samples 7, ... num_samples EXPECT_EQ(ok_code, data_reader_->take(data_seq[4], info_seq[4], LENGTH_UNLIMITED, NOT_READ_SAMPLE_STATE)); @@ -1381,13 +1382,13 @@ TEST_F(DataReaderTests, read_unread) check_sample_values(data_seq[4], "6789"); // Current state: {/, /, /, /, R, R, /, /, /, /} - EXPECT_EQ(num_samples - 10, data_reader_->get_unread_count()); + EXPECT_EQ(num_samples_check - 10, data_reader_->get_unread_count()); // There are not unread samples, so wait_for_unread should return false EXPECT_FALSE(data_reader_->wait_for_unread_message(time_to_wait)); // Current state: {/, /, /, /, R, R, /, /, /, /} - EXPECT_EQ(num_samples - 10, data_reader_->get_unread_count()); + EXPECT_EQ(num_samples_check - 10, data_reader_->get_unread_count()); // Add a new sample to have a NOT_READ one data.message()[0] = 'A'; @@ -1397,7 +1398,7 @@ TEST_F(DataReaderTests, read_unread) EXPECT_TRUE(data_reader_->wait_for_unread_message(time_to_wait)); // Current state: {/, /, /, /, R, R, /, /, /, /, N} - EXPECT_EQ(num_samples - 10 + 1, data_reader_->get_unread_count()); + EXPECT_EQ(num_samples_check - 10 + 1, data_reader_->get_unread_count()); // This should return samples 5, 6 and new EXPECT_EQ(ok_code, data_reader_->take(data_seq[5], info_seq[5])); @@ -1405,7 +1406,7 @@ TEST_F(DataReaderTests, read_unread) check_sample_values(data_seq[5], "45A"); // Current state: {/, /, /, /, /, /, /, /, /, /, /} - EXPECT_EQ(num_samples - 10 + 1 - 1, data_reader_->get_unread_count()); + EXPECT_EQ(num_samples_check - 10 + 1 - 1, data_reader_->get_unread_count()); // There are not unread samples, so wait_for_unread should return false EXPECT_FALSE(data_reader_->wait_for_unread_message(time_to_wait));