-
Notifications
You must be signed in to change notification settings - Fork 166
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Methods to retrieve matched counts on pub/sub. #326
Changes from 5 commits
a2ac134
8bacb00
f3c7ada
b06f0ef
ab3988c
297ed60
3087ec2
503825b
52c2328
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -407,6 +407,33 @@ RCL_PUBLIC | |
bool | ||
rcl_subscription_is_valid(const rcl_subscription_t * subscription); | ||
|
||
/// Get the number of publishers matched to a subscription. | ||
/** | ||
* Used to get the internal count of publishers matched to a subscription. | ||
* | ||
* <hr> | ||
* Attribute | Adherence | ||
* ------------------ | ------------- | ||
* Allocates Memory | No | ||
* Thread-Safe | Yes | ||
* Uses Atomics | Maybe [1] | ||
* Lock-Free | Maybe [1] | ||
* <i>[1] only if the underlying rmw doesn't make use of this feature </i> | ||
* | ||
* \param[in] subscription pointer to the rcl subscription | ||
* \param[out] publisher_count number of matched publishers | ||
* \return `RCL_RET_OK` if the count was retrieved, or | ||
* \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or | ||
* \return `RCL_RET_SUBSCRIPTION_INVALID` if the subscription is invalid, or | ||
* \return `RCL_RET_ERROR` if an unspecified error occurs. | ||
*/ | ||
RCL_PUBLIC | ||
RCL_WARN_UNUSED | ||
rmw_ret_t | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here too. |
||
rcl_subscription_get_publisher_count( | ||
const rcl_subscription_t * subscription, | ||
size_t * publisher_count); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,194 @@ | ||
// Copyright 2018 Open Source Robotics Foundation, Inc. | ||
// | ||
// 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 <gtest/gtest.h> | ||
|
||
#include <chrono> | ||
#include <string> | ||
#include <thread> | ||
|
||
#include "rcl/rcl.h" | ||
#include "rcl/publisher.h" | ||
#include "rcl/subscription.h" | ||
|
||
#include "rcutils/logging_macros.h" | ||
|
||
#include "test_msgs/msg/primitives.h" | ||
#include "test_msgs/srv/primitives.h" | ||
|
||
#include "rcl/error_handling.h" | ||
|
||
#ifdef RMW_IMPLEMENTATION | ||
# define CLASSNAME_(NAME, SUFFIX) NAME ## __ ## SUFFIX | ||
# define CLASSNAME(NAME, SUFFIX) CLASSNAME_(NAME, SUFFIX) | ||
#else | ||
# define CLASSNAME(NAME, SUFFIX) NAME | ||
#endif | ||
|
||
class CLASSNAME (TestCountFixture, RMW_IMPLEMENTATION) : public ::testing::Test | ||
{ | ||
public: | ||
rcl_node_t * old_node_ptr; | ||
wjwwood marked this conversation as resolved.
Show resolved
Hide resolved
|
||
rcl_node_t * node_ptr; | ||
rcl_wait_set_t * wait_set_ptr; | ||
void SetUp() | ||
{ | ||
rcl_ret_t ret; | ||
ret = rcl_init(0, nullptr, rcl_get_default_allocator()); | ||
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; | ||
this->old_node_ptr = new rcl_node_t; | ||
*this->old_node_ptr = rcl_get_zero_initialized_node(); | ||
const char * old_name = "old_node_name"; | ||
rcl_node_options_t node_options = rcl_node_get_default_options(); | ||
ret = rcl_node_init(this->old_node_ptr, old_name, "", &node_options); | ||
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; | ||
ret = rcl_shutdown(); // after this, the old_node_ptr should be invalid | ||
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; | ||
|
||
ret = rcl_init(0, nullptr, rcl_get_default_allocator()); | ||
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; | ||
this->node_ptr = new rcl_node_t; | ||
*this->node_ptr = rcl_get_zero_initialized_node(); | ||
const char * name = "test_graph_node"; | ||
ret = rcl_node_init(this->node_ptr, name, "", &node_options); | ||
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; | ||
|
||
this->wait_set_ptr = new rcl_wait_set_t; | ||
*this->wait_set_ptr = rcl_get_zero_initialized_wait_set(); | ||
ret = rcl_wait_set_init(this->wait_set_ptr, 0, 1, 0, 0, 0, rcl_get_default_allocator()); | ||
} | ||
|
||
void TearDown() | ||
{ | ||
rcl_ret_t ret; | ||
ret = rcl_node_fini(this->old_node_ptr); | ||
delete this->old_node_ptr; | ||
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; | ||
|
||
ret = rcl_wait_set_fini(this->wait_set_ptr); | ||
delete this->wait_set_ptr; | ||
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; | ||
|
||
ret = rcl_node_fini(this->node_ptr); | ||
delete this->node_ptr; | ||
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; | ||
|
||
ret = rcl_shutdown(); | ||
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; | ||
} | ||
}; | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: remove extra empty line |
||
|
||
TEST_F(CLASSNAME(TestCountFixture, RMW_IMPLEMENTATION), test_count_matched_functions) { | ||
std::string topic_name("/test_count_matched_functions__"); | ||
rcl_ret_t ret; | ||
|
||
rcl_publisher_t pub = rcl_get_zero_initialized_publisher(); | ||
rcl_publisher_options_t pub_ops = rcl_publisher_get_default_options(); | ||
auto ts = ROSIDL_GET_MSG_TYPE_SUPPORT(test_msgs, msg, Primitives); | ||
ret = rcl_publisher_init(&pub, this->node_ptr, ts, topic_name.c_str(), &pub_ops); | ||
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; | ||
rcl_reset_error(); | ||
|
||
{ | ||
size_t subscription_count; | ||
ret = rcl_publisher_get_subscription_count(&pub, &subscription_count); | ||
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; | ||
rcl_reset_error(); | ||
EXPECT_EQ(0u, subscription_count); | ||
} | ||
|
||
rcl_subscription_t sub = rcl_get_zero_initialized_subscription(); | ||
rcl_subscription_options_t sub_ops = rcl_subscription_get_default_options(); | ||
ret = rcl_subscription_init(&sub, this->node_ptr, ts, topic_name.c_str(), &sub_ops); | ||
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; | ||
rcl_reset_error(); | ||
|
||
// This sleep is currently needed to allow opensplice and connext to correctly fire | ||
// the on_publication_matched/on_subscription_matched functions. | ||
std::this_thread::sleep_for(std::chrono::milliseconds(10)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems really fragile. I'd prefer to see a sleep-check loop so that when it's quick, it's quick, but when it's really slow it will still pass. In my experience, sometimes Windows will just go AWAL for up to several seconds, so this is asking for a new flakey test. |
||
|
||
{ | ||
size_t subscription_count; | ||
ret = rcl_publisher_get_subscription_count(&pub, &subscription_count); | ||
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; | ||
rcl_reset_error(); | ||
EXPECT_EQ(1u, subscription_count); | ||
} | ||
|
||
{ | ||
size_t publisher_count; | ||
ret = rcl_subscription_get_publisher_count(&sub, &publisher_count); | ||
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; | ||
rcl_reset_error(); | ||
EXPECT_EQ(1u, publisher_count); | ||
} | ||
|
||
rcl_subscription_t sub2 = rcl_get_zero_initialized_subscription(); | ||
rcl_subscription_options_t sub2_ops = rcl_subscription_get_default_options(); | ||
ret = rcl_subscription_init(&sub2, this->node_ptr, ts, topic_name.c_str(), &sub2_ops); | ||
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; | ||
rcl_reset_error(); | ||
|
||
// This sleep is currently needed to allow opensplice and connext to correctly fire | ||
// the on_publication_matched/on_subscription_matched functions. | ||
std::this_thread::sleep_for(std::chrono::milliseconds(10)); | ||
|
||
{ | ||
size_t subscription_count; | ||
ret = rcl_publisher_get_subscription_count(&pub, &subscription_count); | ||
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; | ||
rcl_reset_error(); | ||
EXPECT_EQ(2u, subscription_count); | ||
} | ||
|
||
{ | ||
size_t publisher_count; | ||
ret = rcl_subscription_get_publisher_count(&sub, &publisher_count); | ||
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; | ||
rcl_reset_error(); | ||
EXPECT_EQ(1u, publisher_count); | ||
} | ||
|
||
{ | ||
size_t publisher_count; | ||
ret = rcl_subscription_get_publisher_count(&sub2, &publisher_count); | ||
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; | ||
rcl_reset_error(); | ||
EXPECT_EQ(1u, publisher_count); | ||
} | ||
|
||
ret = rcl_publisher_fini(&pub, this->node_ptr); | ||
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; | ||
rcl_reset_error(); | ||
|
||
// This sleep is currently needed to allow opensplice and connext to correctly fire | ||
// the on_publication_matched/on_subscription_matched functions. | ||
std::this_thread::sleep_for(std::chrono::milliseconds(10)); | ||
|
||
{ | ||
size_t publisher_count; | ||
ret = rcl_subscription_get_publisher_count(&sub, &publisher_count); | ||
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; | ||
rcl_reset_error(); | ||
EXPECT_EQ(0u, publisher_count); | ||
} | ||
|
||
{ | ||
size_t publisher_count; | ||
ret = rcl_subscription_get_publisher_count(&sub2, &publisher_count); | ||
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; | ||
rcl_reset_error(); | ||
EXPECT_EQ(0u, publisher_count); | ||
} | ||
wjwwood marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rcl functions should return
rcl_ret_t
rather thanrmw_ret_t
, @mjcarroll can you fix this up?