Implement functions to get publisher and subcription informations like QoS policies from topic name (#511)
Signed-off-by: Jaison Titus <jaisontj92@gmail.com> Signed-off-by: Miaofei <miaofei@amazon.com>
This commit is contained in:
parent
024c3ee50d
commit
2221d6374e
5 changed files with 599 additions and 4 deletions
|
@ -22,6 +22,7 @@ extern "C"
|
|||
|
||||
#include <rmw/names_and_types.h>
|
||||
#include <rmw/get_topic_names_and_types.h>
|
||||
#include <rmw/topic_endpoint_info_array.h>
|
||||
|
||||
#include "rcutils/types.h"
|
||||
|
||||
|
@ -420,8 +421,8 @@ rcl_names_and_types_fini(rcl_names_and_types_t * names_and_types);
|
|||
*
|
||||
* \param[in] node the handle to the node being used to query the ROS graph
|
||||
* \param[in] allocator used to control allocation and deallocation of names
|
||||
* \param[out] node_names struct storing discovered node names.
|
||||
* \param[out] node_namesspaces struct storing discovered node namespaces.
|
||||
* \param[out] node_names struct storing discovered node names
|
||||
* \param[out] node_namesspaces struct storing discovered node namespaces
|
||||
* \return `RCL_RET_OK` if the query was successful, or
|
||||
* \return `RCL_RET_ERROR` if an unspecified error occurs.
|
||||
*/
|
||||
|
@ -524,6 +525,126 @@ rcl_count_subscribers(
|
|||
const char * topic_name,
|
||||
size_t * count);
|
||||
|
||||
/// Return a list of all publishers to a topic.
|
||||
/**
|
||||
* The `node` parameter must point to a valid node.
|
||||
*
|
||||
* The `topic_name` parameter must not be `NULL`.
|
||||
*
|
||||
* When the `no_mangle` parameter is `true`, the provided `topic_name` should be a valid topic name
|
||||
* for the middleware (useful when combining ROS with native middleware (e.g. DDS) apps).
|
||||
* When the `no_mangle` parameter is `false`, the provided `topic_name` should follow
|
||||
* ROS topic name conventions.
|
||||
* In either case, the topic name should always be fully qualified.
|
||||
*
|
||||
* Each element in the `publishers_info` array will contain the node name, node namespace,
|
||||
* topic type, gid and the qos profile of the publisher.
|
||||
* It is the responsibility of the caller to ensure that `publishers_info` parameter points
|
||||
* to a valid struct of type rmw_topic_endpoint_info_array_t.
|
||||
* The `count` field inside the struct must be set to 0 and the `info_array` field inside
|
||||
* the struct must be set to null.
|
||||
* \see rmw_get_zero_initialized_topic_endpoint_info_array
|
||||
*
|
||||
* The `allocator` will be used to allocate memory to the `info_array` member
|
||||
* inside of `publishers_info`.
|
||||
* Moreover, every const char * member inside of
|
||||
* rmw_topic_endpoint_info_t will be assigned a copied value on allocated memory.
|
||||
* \see rmw_topic_endpoint_info_set_node_name and the likes.
|
||||
* However, it is the responsibility of the caller to
|
||||
* reclaim any allocated resources to `publishers_info` to avoid leaking memory.
|
||||
* \see rmw_topic_endpoint_info_array_fini
|
||||
*
|
||||
* <hr>
|
||||
* Attribute | Adherence
|
||||
* ------------------ | -------------
|
||||
* Allocates Memory | Yes
|
||||
* Thread-Safe | No
|
||||
* Uses Atomics | No
|
||||
* Lock-Free | Maybe [1]
|
||||
* <i>[1] implementation may need to protect the data structure with a lock</i>
|
||||
*
|
||||
* \param[in] node the handle to the node being used to query the ROS graph
|
||||
* \param[in] allocator allocator to be used when allocating space for
|
||||
* the array inside publishers_info
|
||||
* \param[in] topic_name the name of the topic in question
|
||||
* \param[in] no_mangle if true, the topic_name will be expanded to its fully qualified name
|
||||
* \param[out] publishers_info a struct representing a list of publisher information
|
||||
* \return `RCL_RET_OK` if the query was successful, or
|
||||
* \return `RCL_RET_NODE_INVALID` if the node is invalid, or
|
||||
* \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
|
||||
* \return `RCL_RET_BAD_ALLOC` if memory allocation fails, or
|
||||
* \return `RCL_RET_ERROR` if an unspecified error occurs.
|
||||
*/
|
||||
RCL_PUBLIC
|
||||
RCL_WARN_UNUSED
|
||||
rcl_ret_t
|
||||
rcl_get_publishers_info_by_topic(
|
||||
const rcl_node_t * node,
|
||||
rcutils_allocator_t * allocator,
|
||||
const char * topic_name,
|
||||
bool no_mangle,
|
||||
rmw_topic_endpoint_info_array_t * publishers_info);
|
||||
|
||||
/// Return a list of all subscriptions to a topic.
|
||||
/**
|
||||
* The `node` parameter must point to a valid node.
|
||||
*
|
||||
* The `topic_name` parameter must not be `NULL`.
|
||||
*
|
||||
* When the `no_mangle` parameter is `true`, the provided `topic_name` should be a valid topic name
|
||||
* for the middleware (useful when combining ROS with native middleware (e.g. DDS) apps).
|
||||
* When the `no_mangle` parameter is `false`, the provided `topic_name` should follow
|
||||
* ROS topic name conventions.
|
||||
* In either case, the topic name should always be fully qualified.
|
||||
*
|
||||
* Each element in the `subscriptions_info` array will contain the node name, node namespace,
|
||||
* topic type, gid and the qos profile of the subscription.
|
||||
* It is the responsibility of the caller to ensure that `subscriptions_info` parameter points
|
||||
* to a valid struct of type rmw_topic_endpoint_info_array_t.
|
||||
* The `count` field inside the struct must be set to 0 and the `info_array` field inside
|
||||
* the struct must be set to null.
|
||||
* \see rmw_get_zero_initialized_topic_endpoint_info_array
|
||||
*
|
||||
* The `allocator` will be used to allocate memory to the `info_array` member
|
||||
* inside of `subscriptions_info`.
|
||||
* Moreover, every const char * member inside of
|
||||
* rmw_topic_endpoint_info_t will be assigned a copied value on allocated memory.
|
||||
* \see rmw_topic_endpoint_info_set_node_name and the likes.
|
||||
* However, it is the responsibility of the caller to
|
||||
* reclaim any allocated resources to `subscriptions_info` to avoid leaking memory.
|
||||
* \see rmw_topic_endpoint_info_array_fini
|
||||
*
|
||||
* <hr>
|
||||
* Attribute | Adherence
|
||||
* ------------------ | -------------
|
||||
* Allocates Memory | Yes
|
||||
* Thread-Safe | No
|
||||
* Uses Atomics | No
|
||||
* Lock-Free | Maybe [1]
|
||||
* <i>[1] implementation may need to protect the data structure with a lock</i>
|
||||
*
|
||||
* \param[in] node the handle to the node being used to query the ROS graph
|
||||
* \param[in] allocator allocator to be used when allocating space for
|
||||
* the array inside publishers_info
|
||||
* \param[in] topic_name the name of the topic in question
|
||||
* \param[in] no_mangle if true, the topic_name will be expanded to its fully qualified name
|
||||
* \param[out] subscriptions_info a struct representing a list of subscriptions information
|
||||
* \return `RCL_RET_OK` if the query was successful, or
|
||||
* \return `RCL_RET_NODE_INVALID` if the node is invalid, or
|
||||
* \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
|
||||
* \return `RCL_RET_BAD_ALLOC` if memory allocation fails, or
|
||||
* \return `RCL_RET_ERROR` if an unspecified error occurs.
|
||||
*/
|
||||
RCL_PUBLIC
|
||||
RCL_WARN_UNUSED
|
||||
rcl_ret_t
|
||||
rcl_get_subscriptions_info_by_topic(
|
||||
const rcl_node_t * node,
|
||||
rcutils_allocator_t * allocator,
|
||||
const char * topic_name,
|
||||
bool no_mangle,
|
||||
rmw_topic_endpoint_info_array_t * subscriptions_info);
|
||||
|
||||
/// Check if a service server is available for the given service client.
|
||||
/**
|
||||
* This function will return true for `is_available` if there is a service server
|
||||
|
|
|
@ -25,9 +25,11 @@ extern "C"
|
|||
#include "rmw/error_handling.h"
|
||||
#include "rmw/get_node_info_and_types.h"
|
||||
#include "rmw/get_service_names_and_types.h"
|
||||
#include "rmw/get_topic_endpoint_info.h"
|
||||
#include "rmw/get_topic_names_and_types.h"
|
||||
#include "rmw/names_and_types.h"
|
||||
#include "rmw/rmw.h"
|
||||
#include "rmw/topic_endpoint_info_array.h"
|
||||
#include "rmw/validate_namespace.h"
|
||||
#include "rmw/validate_node_name.h"
|
||||
|
||||
|
@ -375,6 +377,90 @@ rcl_count_subscribers(
|
|||
return rcl_convert_rmw_ret_to_rcl_ret(rmw_ret);
|
||||
}
|
||||
|
||||
typedef rmw_ret_t (* get_topic_endpoint_info_func_t)(
|
||||
const rmw_node_t * node,
|
||||
rcutils_allocator_t * allocator,
|
||||
const char * topic_name,
|
||||
bool no_mangle,
|
||||
rmw_topic_endpoint_info_array_t * info_array);
|
||||
|
||||
rcl_ret_t
|
||||
__rcl_get_info_by_topic(
|
||||
const rcl_node_t * node,
|
||||
rcutils_allocator_t * allocator,
|
||||
const char * topic_name,
|
||||
bool no_mangle,
|
||||
rmw_topic_endpoint_info_array_t * info_array,
|
||||
get_topic_endpoint_info_func_t get_topic_endpoint_info)
|
||||
{
|
||||
if (!rcl_node_is_valid(node)) {
|
||||
return RCL_RET_NODE_INVALID; // error already set.
|
||||
}
|
||||
const rcl_node_options_t * node_options = rcl_node_get_options(node);
|
||||
if (!node_options) {
|
||||
return RCL_RET_NODE_INVALID; // shouldn't happen, but error is already set if so
|
||||
}
|
||||
RCL_CHECK_ALLOCATOR_WITH_MSG(allocator, "invalid allocator", return RCL_RET_INVALID_ARGUMENT);
|
||||
RCL_CHECK_ARGUMENT_FOR_NULL(topic_name, RCL_RET_INVALID_ARGUMENT);
|
||||
rmw_error_string_t error_string;
|
||||
rmw_ret_t rmw_ret = rmw_topic_endpoint_info_array_check_zero(info_array);
|
||||
if (rmw_ret != RMW_RET_OK) {
|
||||
error_string = rmw_get_error_string();
|
||||
rmw_reset_error();
|
||||
RCL_SET_ERROR_MSG_WITH_FORMAT_STRING(
|
||||
"rmw_topic_endpoint_info_array_t must be zero initialized: %s,\n"
|
||||
"Use rmw_get_zero_initialized_topic_endpoint_info_array",
|
||||
error_string.str);
|
||||
return rcl_convert_rmw_ret_to_rcl_ret(rmw_ret);
|
||||
}
|
||||
rmw_ret = get_topic_endpoint_info(
|
||||
rcl_node_get_rmw_handle(node),
|
||||
allocator,
|
||||
topic_name,
|
||||
no_mangle,
|
||||
info_array);
|
||||
if (rmw_ret != RMW_RET_OK) {
|
||||
error_string = rmw_get_error_string();
|
||||
rmw_reset_error();
|
||||
RCL_SET_ERROR_MSG(error_string.str);
|
||||
}
|
||||
return rcl_convert_rmw_ret_to_rcl_ret(rmw_ret);
|
||||
}
|
||||
|
||||
rcl_ret_t
|
||||
rcl_get_publishers_info_by_topic(
|
||||
const rcl_node_t * node,
|
||||
rcutils_allocator_t * allocator,
|
||||
const char * topic_name,
|
||||
bool no_mangle,
|
||||
rmw_topic_endpoint_info_array_t * publishers_info)
|
||||
{
|
||||
return __rcl_get_info_by_topic(
|
||||
node,
|
||||
allocator,
|
||||
topic_name,
|
||||
no_mangle,
|
||||
publishers_info,
|
||||
rmw_get_publishers_info_by_topic);
|
||||
}
|
||||
|
||||
rcl_ret_t
|
||||
rcl_get_subscriptions_info_by_topic(
|
||||
const rcl_node_t * node,
|
||||
rcutils_allocator_t * allocator,
|
||||
const char * topic_name,
|
||||
bool no_mangle,
|
||||
rmw_topic_endpoint_info_array_t * subscriptions_info)
|
||||
{
|
||||
return __rcl_get_info_by_topic(
|
||||
node,
|
||||
allocator,
|
||||
topic_name,
|
||||
no_mangle,
|
||||
subscriptions_info,
|
||||
rmw_get_subscriptions_info_by_topic);
|
||||
}
|
||||
|
||||
rcl_ret_t
|
||||
rcl_service_server_is_available(
|
||||
const rcl_node_t * node,
|
||||
|
|
|
@ -101,6 +101,21 @@ function(test_target_function)
|
|||
${AMENT_GTEST_ARGS}
|
||||
)
|
||||
|
||||
set(AMENT_GTEST_ARGS "")
|
||||
# TODO(mm318): why rmw_connext tests run much slower than rmw_fastrtps and rmw_opensplice tests
|
||||
if(rmw_implementation STREQUAL "rmw_connext_cpp")
|
||||
message(STATUS "Increasing test_info_by_topic${target_suffix} test timeout.")
|
||||
set(AMENT_GTEST_ARGS TIMEOUT 120)
|
||||
endif()
|
||||
rcl_add_custom_gtest(test_info_by_topic${target_suffix}
|
||||
SRCS rcl/test_info_by_topic.cpp
|
||||
ENV ${rmw_implementation_env_var}
|
||||
APPEND_LIBRARY_DIRS ${extra_lib_dirs}
|
||||
LIBRARIES ${PROJECT_NAME}
|
||||
AMENT_DEPENDENCIES ${rmw_implementation} "osrf_testing_tools_cpp" "test_msgs"
|
||||
${AMENT_GTEST_ARGS}
|
||||
)
|
||||
|
||||
rcl_add_custom_gtest(test_count_matched${target_suffix}
|
||||
SRCS rcl/test_count_matched.cpp
|
||||
ENV ${rmw_implementation_env_var}
|
||||
|
|
|
@ -916,8 +916,8 @@ public:
|
|||
/**
|
||||
* Verify the number of subsystems each node should have.
|
||||
*
|
||||
* @param node_state expected state of node
|
||||
* @param remote_node_state expected state of remote node
|
||||
* \param node_state expected state of node
|
||||
* \param remote_node_state expected state of remote node
|
||||
*/
|
||||
void VerifySubsystemCount(
|
||||
const expected_node_state && node_state,
|
||||
|
|
373
rcl/test/rcl/test_info_by_topic.cpp
Normal file
373
rcl/test/rcl/test_info_by_topic.cpp
Normal file
|
@ -0,0 +1,373 @@
|
|||
// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
//
|
||||
// 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 _WIN32
|
||||
# pragma GCC diagnostic ignored "-Wmissing-field-initializers"
|
||||
#endif
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "rcl/error_handling.h"
|
||||
#include "rcl/graph.h"
|
||||
#include "rcl/rcl.h"
|
||||
|
||||
#include "rmw/topic_endpoint_info_array.h"
|
||||
#include "rmw/error_handling.h"
|
||||
|
||||
#include "test_msgs/msg/strings.h"
|
||||
#include "rosidl_generator_c/string_functions.h"
|
||||
|
||||
#include "osrf_testing_tools_cpp/scope_exit.hpp"
|
||||
|
||||
#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 (TestInfoByTopicFixture, RMW_IMPLEMENTATION) : public ::testing::Test
|
||||
{
|
||||
public:
|
||||
rcl_context_t old_context;
|
||||
rcl_context_t context;
|
||||
rcl_node_t old_node;
|
||||
rcl_node_t node;
|
||||
const char * test_graph_node_name = "test_graph_node";
|
||||
rmw_topic_endpoint_info_array_t topic_endpoint_info_array;
|
||||
const char * const topic_name = "valid_topic_name";
|
||||
bool is_fastrtps;
|
||||
|
||||
void SetUp()
|
||||
{
|
||||
is_fastrtps = (std::string(rmw_get_implementation_identifier()).find("rmw_fastrtps") == 0);
|
||||
rcl_ret_t ret;
|
||||
rcl_init_options_t init_options = rcl_get_zero_initialized_init_options();
|
||||
ret = rcl_init_options_init(&init_options, rcl_get_default_allocator());
|
||||
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
|
||||
OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT({
|
||||
EXPECT_EQ(RCL_RET_OK, rcl_init_options_fini(&init_options)) << rcl_get_error_string().str;
|
||||
});
|
||||
this->old_context = rcl_get_zero_initialized_context();
|
||||
ret = rcl_init(0, nullptr, &init_options, &this->old_context);
|
||||
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
|
||||
this->old_node = 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, old_name, "", &this->old_context, &node_options);
|
||||
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
|
||||
ret = rcl_shutdown(&this->old_context); // after this, the old_node should be invalid
|
||||
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
|
||||
|
||||
this->context = rcl_get_zero_initialized_context();
|
||||
|
||||
ret = rcl_init(0, nullptr, &init_options, &this->context);
|
||||
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
|
||||
this->node = rcl_get_zero_initialized_node();
|
||||
const char * name = "test_graph_node";
|
||||
ret = rcl_node_init(&this->node, name, "", &this->context, &node_options);
|
||||
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
|
||||
}
|
||||
|
||||
void TearDown()
|
||||
{
|
||||
rcl_ret_t ret;
|
||||
ret = rcl_node_fini(&this->old_node);
|
||||
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
|
||||
|
||||
ret = rcl_node_fini(&this->node);
|
||||
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
|
||||
|
||||
ret = rcl_shutdown(&this->context);
|
||||
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
|
||||
ret = rcl_context_fini(&this->context);
|
||||
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
|
||||
|
||||
// old_context was supposed to have been shutdown already during SetUp()
|
||||
if (rcl_context_is_valid(&this->old_context)) {
|
||||
ret = rcl_shutdown(&this->old_context);
|
||||
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
|
||||
}
|
||||
ret = rcl_context_fini(&this->old_context);
|
||||
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
|
||||
}
|
||||
|
||||
void assert_qos_equality(rmw_qos_profile_t qos_profile1, rmw_qos_profile_t qos_profile2)
|
||||
{
|
||||
EXPECT_EQ(qos_profile1.deadline.sec, qos_profile2.deadline.sec);
|
||||
EXPECT_EQ(qos_profile1.deadline.nsec, qos_profile2.deadline.nsec);
|
||||
EXPECT_EQ(qos_profile1.lifespan.sec, qos_profile2.lifespan.sec);
|
||||
EXPECT_EQ(qos_profile1.lifespan.nsec, qos_profile2.lifespan.nsec);
|
||||
EXPECT_EQ(qos_profile1.reliability, qos_profile2.reliability);
|
||||
EXPECT_EQ(qos_profile1.liveliness, qos_profile2.liveliness);
|
||||
EXPECT_EQ(qos_profile1.liveliness_lease_duration.sec,
|
||||
qos_profile2.liveliness_lease_duration.sec);
|
||||
EXPECT_EQ(qos_profile1.liveliness_lease_duration.nsec,
|
||||
qos_profile2.liveliness_lease_duration.nsec);
|
||||
EXPECT_EQ(qos_profile1.durability, qos_profile2.durability);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* This does not test content of the response.
|
||||
* It only tests if the return code is the one expected.
|
||||
*/
|
||||
TEST_F(CLASSNAME(TestInfoByTopicFixture, RMW_IMPLEMENTATION),
|
||||
test_rcl_get_publishers_info_by_topic_null_node)
|
||||
{
|
||||
rcl_allocator_t allocator = rcl_get_default_allocator();
|
||||
const auto ret = rcl_get_publishers_info_by_topic(nullptr,
|
||||
&allocator, this->topic_name, false, &this->topic_endpoint_info_array);
|
||||
EXPECT_EQ(RCL_RET_NODE_INVALID, ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* This does not test content of the response.
|
||||
* It only tests if the return code is the one expected.
|
||||
*/
|
||||
TEST_F(CLASSNAME(TestInfoByTopicFixture, RMW_IMPLEMENTATION),
|
||||
test_rcl_get_subscriptions_info_by_topic_null_node)
|
||||
{
|
||||
rcl_allocator_t allocator = rcl_get_default_allocator();
|
||||
const auto ret = rcl_get_subscriptions_info_by_topic(nullptr,
|
||||
&allocator, this->topic_name, false, &this->topic_endpoint_info_array);
|
||||
EXPECT_EQ(RCL_RET_NODE_INVALID, ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* This does not test content of the response.
|
||||
* It only tests if the return code is the one expected.
|
||||
*/
|
||||
TEST_F(CLASSNAME(TestInfoByTopicFixture, RMW_IMPLEMENTATION),
|
||||
test_rcl_get_publishers_info_by_topic_invalid_node)
|
||||
{
|
||||
// this->old_node is an invalid node.
|
||||
rcl_allocator_t allocator = rcl_get_default_allocator();
|
||||
const auto ret = rcl_get_publishers_info_by_topic(&this->old_node,
|
||||
&allocator, this->topic_name, false, &this->topic_endpoint_info_array);
|
||||
EXPECT_EQ(RCL_RET_NODE_INVALID, ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* This does not test content of the response.
|
||||
* It only tests if the return code is the one expected.
|
||||
*/
|
||||
TEST_F(CLASSNAME(TestInfoByTopicFixture, RMW_IMPLEMENTATION),
|
||||
test_rcl_get_subscriptions_info_by_topic_invalid_node)
|
||||
{
|
||||
// this->old_node is an invalid node.
|
||||
rcl_allocator_t allocator = rcl_get_default_allocator();
|
||||
const auto ret = rcl_get_subscriptions_info_by_topic(&this->old_node,
|
||||
&allocator, this->topic_name, false, &this->topic_endpoint_info_array);
|
||||
EXPECT_EQ(RCL_RET_NODE_INVALID, ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* This does not test content of the response.
|
||||
* It only tests if the return code is the one expected.
|
||||
*/
|
||||
TEST_F(CLASSNAME(TestInfoByTopicFixture, RMW_IMPLEMENTATION),
|
||||
test_rcl_get_publishers_info_by_topic_null_allocator)
|
||||
{
|
||||
const auto ret = rcl_get_publishers_info_by_topic(&this->node, nullptr, this->topic_name,
|
||||
false,
|
||||
&this->topic_endpoint_info_array);
|
||||
EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* This does not test content of the response.
|
||||
* It only tests if the return code is the one expected.
|
||||
*/
|
||||
TEST_F(CLASSNAME(TestInfoByTopicFixture, RMW_IMPLEMENTATION),
|
||||
test_rcl_get_subscriptions_info_by_topic_null_allocator)
|
||||
{
|
||||
const auto ret = rcl_get_subscriptions_info_by_topic(&this->node, nullptr, this->topic_name,
|
||||
false,
|
||||
&this->topic_endpoint_info_array);
|
||||
EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* This does not test content of the response.
|
||||
* It only tests if the return code is the one expected.
|
||||
*/
|
||||
TEST_F(CLASSNAME(TestInfoByTopicFixture, RMW_IMPLEMENTATION),
|
||||
test_rcl_get_publishers_info_by_topic_null_topic)
|
||||
{
|
||||
rcl_allocator_t allocator = rcl_get_default_allocator();
|
||||
const auto ret = rcl_get_publishers_info_by_topic(&this->node,
|
||||
&allocator, nullptr, false, &this->topic_endpoint_info_array);
|
||||
EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* This does not test content of the response.
|
||||
* It only tests if the return code is the one expected.
|
||||
*/
|
||||
TEST_F(CLASSNAME(TestInfoByTopicFixture, RMW_IMPLEMENTATION),
|
||||
test_rcl_get_subscriptions_info_by_topic_null_topic)
|
||||
{
|
||||
rcl_allocator_t allocator = rcl_get_default_allocator();
|
||||
const auto ret = rcl_get_subscriptions_info_by_topic(&this->node,
|
||||
&allocator, nullptr, false, &this->topic_endpoint_info_array);
|
||||
EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* This does not test content of the response.
|
||||
* It only tests if the return code is the one expected.
|
||||
*/
|
||||
TEST_F(CLASSNAME(TestInfoByTopicFixture, RMW_IMPLEMENTATION),
|
||||
test_rcl_get_publishers_info_by_topic_null_participants)
|
||||
{
|
||||
rcl_allocator_t allocator = rcl_get_default_allocator();
|
||||
const auto ret = rcl_get_publishers_info_by_topic(&this->node,
|
||||
&allocator, this->topic_name, false, nullptr);
|
||||
EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* This does not test content of the response.
|
||||
* It only tests if the return code is the one expected.
|
||||
*/
|
||||
TEST_F(CLASSNAME(TestInfoByTopicFixture, RMW_IMPLEMENTATION),
|
||||
test_rcl_get_subscriptions_info_by_topic_null_participants)
|
||||
{
|
||||
rcl_allocator_t allocator = rcl_get_default_allocator();
|
||||
const auto ret = rcl_get_subscriptions_info_by_topic(&this->node,
|
||||
&allocator, this->topic_name, false, nullptr);
|
||||
EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* This does not test content of the response.
|
||||
* It only tests if the return code is the one expected.
|
||||
*/
|
||||
TEST_F(CLASSNAME(TestInfoByTopicFixture, RMW_IMPLEMENTATION),
|
||||
test_rcl_get_publishers_info_by_topic_invalid_participants)
|
||||
{
|
||||
// topic_endpoint_info_array is invalid because it is expected to be zero initialized
|
||||
// and the info_array variable inside it is expected to be null.
|
||||
this->topic_endpoint_info_array.info_array = new rmw_topic_endpoint_info_t();
|
||||
OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT({
|
||||
free(this->topic_endpoint_info_array.info_array);
|
||||
});
|
||||
rcl_allocator_t allocator = rcl_get_default_allocator();
|
||||
const auto ret = rcl_get_publishers_info_by_topic(&this->node,
|
||||
&allocator, this->topic_name, false, &this->topic_endpoint_info_array);
|
||||
EXPECT_EQ(RCL_RET_ERROR, ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* This does not test content of the response.
|
||||
* It only tests if the return code is the one expected.
|
||||
*/
|
||||
TEST_F(CLASSNAME(TestInfoByTopicFixture, RMW_IMPLEMENTATION),
|
||||
test_rcl_get_subscriptions_info_by_topic_invalid_participants)
|
||||
{
|
||||
// topic_endpoint_info_array is invalid because it is expected to be zero initialized
|
||||
// and the info_array variable inside it is expected to be null.
|
||||
this->topic_endpoint_info_array.info_array = new rmw_topic_endpoint_info_t();
|
||||
OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT({
|
||||
free(this->topic_endpoint_info_array.info_array);
|
||||
});
|
||||
rcl_allocator_t allocator = rcl_get_default_allocator();
|
||||
const auto ret = rcl_get_subscriptions_info_by_topic(&this->node,
|
||||
&allocator, this->topic_name, false, &this->topic_endpoint_info_array);
|
||||
EXPECT_EQ(RCL_RET_ERROR, ret);
|
||||
}
|
||||
|
||||
TEST_F(CLASSNAME(TestInfoByTopicFixture, RMW_IMPLEMENTATION),
|
||||
test_rcl_get_publishers_subscription_info_by_topic)
|
||||
{
|
||||
// This is implemented only in fastrtps currently.
|
||||
if (!is_fastrtps) {
|
||||
GTEST_SKIP();
|
||||
}
|
||||
rmw_qos_profile_t default_qos_profile;
|
||||
default_qos_profile.history = RMW_QOS_POLICY_HISTORY_KEEP_LAST;
|
||||
default_qos_profile.depth = 0;
|
||||
default_qos_profile.reliability = RMW_QOS_POLICY_RELIABILITY_BEST_EFFORT;
|
||||
default_qos_profile.durability = RMW_QOS_POLICY_DURABILITY_VOLATILE;
|
||||
default_qos_profile.lifespan = {10, 0};
|
||||
default_qos_profile.deadline = {11, 0};
|
||||
default_qos_profile.liveliness_lease_duration = {20, 0};
|
||||
default_qos_profile.liveliness = RMW_QOS_POLICY_LIVELINESS_MANUAL_BY_TOPIC;
|
||||
|
||||
rcl_ret_t ret;
|
||||
const rosidl_message_type_support_t * ts = ROSIDL_GET_MSG_TYPE_SUPPORT(test_msgs, msg, Strings);
|
||||
rcl_allocator_t allocator = rcl_get_default_allocator();
|
||||
|
||||
rcl_publisher_t publisher = rcl_get_zero_initialized_publisher();
|
||||
rcl_publisher_options_t publisher_options = rcl_publisher_get_default_options();
|
||||
publisher_options.qos = default_qos_profile;
|
||||
ret = rcl_publisher_init(
|
||||
&publisher,
|
||||
&this->node,
|
||||
ts,
|
||||
this->topic_name,
|
||||
&publisher_options);
|
||||
ASSERT_EQ(ret, RCL_RET_OK) << rcl_get_error_string().str;
|
||||
|
||||
rcl_subscription_t subscription = rcl_get_zero_initialized_subscription();
|
||||
rcl_subscription_options_t subscription_options = rcl_subscription_get_default_options();
|
||||
subscription_options.qos = default_qos_profile;
|
||||
ret = rcl_subscription_init(
|
||||
&subscription,
|
||||
&this->node,
|
||||
ts,
|
||||
this->topic_name,
|
||||
&subscription_options);
|
||||
ASSERT_EQ(ret, RCL_RET_OK) << rcl_get_error_string().str;
|
||||
const std::string fqdn = std::string("/") + this->topic_name;
|
||||
// Get publishers info by topic
|
||||
rmw_topic_endpoint_info_array_t topic_endpoint_info_array_pub =
|
||||
rmw_get_zero_initialized_topic_endpoint_info_array();
|
||||
ret = rcl_get_publishers_info_by_topic(&this->node,
|
||||
&allocator, fqdn.c_str(), false, &topic_endpoint_info_array_pub);
|
||||
EXPECT_EQ(ret, RCL_RET_OK) << rcl_get_error_string().str;
|
||||
EXPECT_EQ(topic_endpoint_info_array_pub.count, 1u) << "Expected one publisher";
|
||||
rmw_topic_endpoint_info_t topic_endpoint_info_pub = topic_endpoint_info_array_pub.info_array[0];
|
||||
EXPECT_STREQ(topic_endpoint_info_pub.node_name, this->test_graph_node_name);
|
||||
EXPECT_STREQ(topic_endpoint_info_pub.node_namespace, "/");
|
||||
EXPECT_STREQ(topic_endpoint_info_pub.topic_type, "test_msgs/msg/Strings");
|
||||
assert_qos_equality(topic_endpoint_info_pub.qos_profile, default_qos_profile);
|
||||
|
||||
rmw_topic_endpoint_info_array_t topic_endpoint_info_array_sub =
|
||||
rmw_get_zero_initialized_topic_endpoint_info_array();
|
||||
ret = rcl_get_subscriptions_info_by_topic(&this->node,
|
||||
&allocator, fqdn.c_str(), false, &topic_endpoint_info_array_sub);
|
||||
EXPECT_EQ(ret, RCL_RET_OK) << rcl_get_error_string().str;
|
||||
EXPECT_EQ(topic_endpoint_info_array_sub.count, 1u) << "Expected one subscription";
|
||||
rmw_topic_endpoint_info_t topic_endpoint_info_sub = topic_endpoint_info_array_sub.info_array[0];
|
||||
EXPECT_STREQ(topic_endpoint_info_sub.node_name, this->test_graph_node_name);
|
||||
EXPECT_STREQ(topic_endpoint_info_sub.node_namespace, "/");
|
||||
EXPECT_STREQ(topic_endpoint_info_sub.topic_type, "test_msgs/msg/Strings");
|
||||
assert_qos_equality(topic_endpoint_info_sub.qos_profile, default_qos_profile);
|
||||
|
||||
// clean up
|
||||
rmw_ret_t rmw_ret =
|
||||
rmw_topic_endpoint_info_array_fini(&topic_endpoint_info_array_pub, &allocator);
|
||||
EXPECT_EQ(rmw_ret, RMW_RET_OK) << rmw_get_error_string().str;
|
||||
rmw_ret = rmw_topic_endpoint_info_array_fini(&topic_endpoint_info_array_sub, &allocator);
|
||||
EXPECT_EQ(rmw_ret, RMW_RET_OK) << rmw_get_error_string().str;
|
||||
ret = rcl_subscription_fini(&subscription, &this->node);
|
||||
EXPECT_EQ(ret, RCL_RET_OK) << rcl_get_error_string().str;
|
||||
ret = rcl_publisher_fini(&publisher, &this->node);
|
||||
EXPECT_EQ(ret, RCL_RET_OK) << rcl_get_error_string().str;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue