add concept of node namespace to rcl API (#112)
* add concept of node namespace to rcl API also validate node name and node namespace * name_space -> namespace_ * doc clarification * make use of rmw_validate_namespace() * clear expected error messages in test_node.cpp * avoid unused invalid_index * include the validation result value when it is unknown * use _snprintf_s on windows * uncrustify
This commit is contained in:
parent
77ee3f987c
commit
64f1b16d2f
14 changed files with 376 additions and 41 deletions
|
@ -44,9 +44,12 @@ typedef struct rcl_node_t
|
||||||
typedef struct rcl_node_options_t
|
typedef struct rcl_node_options_t
|
||||||
{
|
{
|
||||||
// bool anonymous_name;
|
// bool anonymous_name;
|
||||||
|
|
||||||
// rmw_qos_profile_t parameter_qos;
|
// rmw_qos_profile_t parameter_qos;
|
||||||
|
|
||||||
/// If true, no parameter infrastructure will be setup.
|
/// If true, no parameter infrastructure will be setup.
|
||||||
// bool no_parameters;
|
// bool no_parameters;
|
||||||
|
|
||||||
/// If set, then this value overrides the ROS_DOMAIN_ID environment variable.
|
/// If set, then this value overrides the ROS_DOMAIN_ID environment variable.
|
||||||
/**
|
/**
|
||||||
* It defaults to RCL_NODE_OPTIONS_DEFAULT_DOMAIN_ID, which will cause the
|
* It defaults to RCL_NODE_OPTIONS_DEFAULT_DOMAIN_ID, which will cause the
|
||||||
|
@ -59,6 +62,7 @@ typedef struct rcl_node_options_t
|
||||||
* (currently max size_t)
|
* (currently max size_t)
|
||||||
*/
|
*/
|
||||||
size_t domain_id;
|
size_t domain_id;
|
||||||
|
|
||||||
/// Custom allocator used for internal allocations.
|
/// Custom allocator used for internal allocations.
|
||||||
rcl_allocator_t allocator;
|
rcl_allocator_t allocator;
|
||||||
} rcl_node_options_t;
|
} rcl_node_options_t;
|
||||||
|
@ -77,11 +81,27 @@ rcl_get_zero_initialized_node(void);
|
||||||
* After calling, the ROS node object can be used to create other middleware
|
* After calling, the ROS node object can be used to create other middleware
|
||||||
* primitives like publishers, services, parameters, etc.
|
* primitives like publishers, services, parameters, etc.
|
||||||
*
|
*
|
||||||
|
* The name of the node must not be NULL and adhere to naming restrictions,
|
||||||
|
* see the rmw_validate_node_name() function for rules.
|
||||||
|
*
|
||||||
* \todo TODO(wjwwood): node name uniqueness is no yet enforced
|
* \todo TODO(wjwwood): node name uniqueness is no yet enforced
|
||||||
*
|
*
|
||||||
* The name of the node cannot coincide with another node of the same name.
|
* The name of the node cannot coincide with another node of the same name.
|
||||||
* If a node of the same name is already in the domain, it will be shutdown.
|
* If a node of the same name is already in the domain, it will be shutdown.
|
||||||
*
|
*
|
||||||
|
* The namespace of the node should not be NULL and should also pass the
|
||||||
|
* rmw_validate_namespace() function's rules.
|
||||||
|
*
|
||||||
|
* Additionally this function allows namespaces which lack a leading forward
|
||||||
|
* slash.
|
||||||
|
* Because there is no notion of a relative namespace, there is no difference
|
||||||
|
* between a namespace which lacks a forward and the same namespace with a
|
||||||
|
* leasing forward slash.
|
||||||
|
* Therefore, a namespace like ``"foo/bar"`` is automatically changed to
|
||||||
|
* ``"/foo/bar"`` by this function.
|
||||||
|
* Similarly, the namespace ``""`` will implicitly become ``"/"`` which is a
|
||||||
|
* valid namespace.
|
||||||
|
*
|
||||||
* \todo TODO(wjwwood):
|
* \todo TODO(wjwwood):
|
||||||
* Parameter infrastructure is currently initialized in the language specific
|
* Parameter infrastructure is currently initialized in the language specific
|
||||||
* client library, e.g. rclcpp for C++, but will be initialized here in the
|
* client library, e.g. rclcpp for C++, but will be initialized here in the
|
||||||
|
@ -104,7 +124,7 @@ rcl_get_zero_initialized_node(void);
|
||||||
* rcl_node_t node = rcl_get_zero_initialized_node();
|
* rcl_node_t node = rcl_get_zero_initialized_node();
|
||||||
* rcl_node_options_t * node_ops = rcl_node_get_default_options();
|
* rcl_node_options_t * node_ops = rcl_node_get_default_options();
|
||||||
* // ... node options customization
|
* // ... node options customization
|
||||||
* rcl_ret_t ret = rcl_node_init(&node, "node_name", node_ops);
|
* rcl_ret_t ret = rcl_node_init(&node, "node_name", "/node_ns", node_ops);
|
||||||
* // ... error handling and then use the node, but eventually deinitialize it:
|
* // ... error handling and then use the node, but eventually deinitialize it:
|
||||||
* ret = rcl_node_fini(&node);
|
* ret = rcl_node_fini(&node);
|
||||||
* // ... error handling for rcl_node_fini()
|
* // ... error handling for rcl_node_fini()
|
||||||
|
@ -123,18 +143,25 @@ rcl_get_zero_initialized_node(void);
|
||||||
* \post the node handle is valid and can be used in other `rcl_*` functions
|
* \post the node handle is valid and can be used in other `rcl_*` functions
|
||||||
*
|
*
|
||||||
* \param[inout] node a preallocated rcl_node_t
|
* \param[inout] node a preallocated rcl_node_t
|
||||||
* \param[in] name the name of the node
|
* \param[in] name the name of the node, must be a valid c-string
|
||||||
|
* \param[in] namespace_ the namespace of the node, must be a valid c-string
|
||||||
* \param[in] options the node options
|
* \param[in] options the node options
|
||||||
* \return `RCL_RET_OK` if the node was initialized successfully, or
|
* \return `RCL_RET_OK` if the node was initialized successfully, or
|
||||||
* \return `RCL_RET_ALREADY_INIT` if the node has already be initialized, or
|
* \return `RCL_RET_ALREADY_INIT` if the node has already be initialized, or
|
||||||
* \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
|
* \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
|
||||||
* \return `RCL_RET_BAD_ALLOC` if allocating memory failed, or
|
* \return `RCL_RET_BAD_ALLOC` if allocating memory failed, or
|
||||||
|
* \return `RCL_RET_NODE_INVALID_NAME` if the name is invalid, or
|
||||||
|
* \return `RCL_RET_NODE_INVALID_NAMESPACE` if the namespace_ is invalid, or
|
||||||
* \return `RCL_RET_ERROR` if an unspecified error occurs.
|
* \return `RCL_RET_ERROR` if an unspecified error occurs.
|
||||||
*/
|
*/
|
||||||
RCL_PUBLIC
|
RCL_PUBLIC
|
||||||
RCL_WARN_UNUSED
|
RCL_WARN_UNUSED
|
||||||
rcl_ret_t
|
rcl_ret_t
|
||||||
rcl_node_init(rcl_node_t * node, const char * name, const rcl_node_options_t * options);
|
rcl_node_init(
|
||||||
|
rcl_node_t * node,
|
||||||
|
const char * name,
|
||||||
|
const char * namespace_,
|
||||||
|
const rcl_node_options_t * options);
|
||||||
|
|
||||||
/// Finalized a rcl_node_t.
|
/// Finalized a rcl_node_t.
|
||||||
/**
|
/**
|
||||||
|
@ -240,6 +267,33 @@ RCL_WARN_UNUSED
|
||||||
const char *
|
const char *
|
||||||
rcl_node_get_name(const rcl_node_t * node);
|
rcl_node_get_name(const rcl_node_t * node);
|
||||||
|
|
||||||
|
/// Return the namespace of the node.
|
||||||
|
/**
|
||||||
|
* This function returns the node's internal namespace string.
|
||||||
|
* This function can fail, and therefore return `NULL`, if:
|
||||||
|
* - node is `NULL`
|
||||||
|
* - node has not been initialized (the implementation is invalid)
|
||||||
|
*
|
||||||
|
* The returned string is only valid as long as the given rcl_node_t is valid.
|
||||||
|
* The value of the string may change if the value in the rcl_node_t changes,
|
||||||
|
* and therefore copying the string is recommended if this is a concern.
|
||||||
|
*
|
||||||
|
* <hr>
|
||||||
|
* Attribute | Adherence
|
||||||
|
* ------------------ | -------------
|
||||||
|
* Allocates Memory | No
|
||||||
|
* Thread-Safe | No
|
||||||
|
* Uses Atomics | No
|
||||||
|
* Lock-Free | Yes
|
||||||
|
*
|
||||||
|
* \param[in] node pointer to the node
|
||||||
|
* \return name string if successful, otherwise `NULL`
|
||||||
|
*/
|
||||||
|
RCL_PUBLIC
|
||||||
|
RCL_WARN_UNUSED
|
||||||
|
const char *
|
||||||
|
rcl_node_get_namespace(const rcl_node_t * node);
|
||||||
|
|
||||||
/// Return the rcl node options.
|
/// Return the rcl node options.
|
||||||
/**
|
/**
|
||||||
* This function returns the node's internal options struct.
|
* This function returns the node's internal options struct.
|
||||||
|
|
|
@ -24,22 +24,24 @@ typedef rmw_ret_t rcl_ret_t;
|
||||||
#define RCL_RET_ERROR RMW_RET_ERROR
|
#define RCL_RET_ERROR RMW_RET_ERROR
|
||||||
/// Timeout occurred return code.
|
/// Timeout occurred return code.
|
||||||
#define RCL_RET_TIMEOUT RMW_RET_TIMEOUT
|
#define RCL_RET_TIMEOUT RMW_RET_TIMEOUT
|
||||||
|
/// Failed to allocate memory return code.
|
||||||
|
#define RCL_RET_BAD_ALLOC RMW_RET_BAD_ALLOC
|
||||||
|
/// Invalid argument return code.
|
||||||
|
#define RCL_RET_INVALID_ARGUMENT RMW_RET_INVALID_ARGUMENT
|
||||||
|
|
||||||
// rcl specific ret codes start at 100
|
// rcl specific ret codes start at 100
|
||||||
/// rcl_init() already called return code.
|
/// rcl_init() already called return code.
|
||||||
#define RCL_RET_ALREADY_INIT 100
|
#define RCL_RET_ALREADY_INIT 100
|
||||||
/// rcl_init() not yet called return code.
|
/// rcl_init() not yet called return code.
|
||||||
#define RCL_RET_NOT_INIT 101
|
#define RCL_RET_NOT_INIT 101
|
||||||
/// Failed to allocate memory return code.
|
|
||||||
#define RCL_RET_BAD_ALLOC 102
|
|
||||||
/// Invalid argument return code.
|
|
||||||
#define RCL_RET_INVALID_ARGUMENT 103
|
|
||||||
/// Mismatched rmw identifier return code.
|
/// Mismatched rmw identifier return code.
|
||||||
#define RCL_RET_MISMATCHED_RMW_ID 104
|
#define RCL_RET_MISMATCHED_RMW_ID 102
|
||||||
|
|
||||||
// rcl node specific ret codes in 2XX
|
// rcl node specific ret codes in 2XX
|
||||||
/// Invalid rcl_node_t given return code.
|
/// Invalid rcl_node_t given return code.
|
||||||
#define RCL_RET_NODE_INVALID 200
|
#define RCL_RET_NODE_INVALID 200
|
||||||
|
#define RCL_RET_NODE_INVALID_NAME 201
|
||||||
|
#define RCL_RET_NODE_INVALID_NAMESPACE 202
|
||||||
|
|
||||||
// rcl publisher specific ret codes in 3XX
|
// rcl publisher specific ret codes in 3XX
|
||||||
/// Invalid rcl_publisher_t given return code.
|
/// Invalid rcl_publisher_t given return code.
|
||||||
|
|
|
@ -26,9 +26,19 @@ extern "C"
|
||||||
|
|
||||||
#include "rcl/rcl.h"
|
#include "rcl/rcl.h"
|
||||||
#include "rmw/rmw.h"
|
#include "rmw/rmw.h"
|
||||||
|
#include "rmw/validate_namespace.h"
|
||||||
|
#include "rmw/validate_node_name.h"
|
||||||
|
#include "rmw/validate_topic_name.h"
|
||||||
|
|
||||||
#include "./common.h"
|
#include "./common.h"
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
#define LOCAL_SNPRINTF snprintf
|
||||||
|
#else
|
||||||
|
#define LOCAL_SNPRINTF(buffer, buffer_size, format, ...) \
|
||||||
|
_snprintf_s(buffer, buffer_size, _TRUNCATE, format, __VA_ARGS__)
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct rcl_node_impl_t
|
typedef struct rcl_node_impl_t
|
||||||
{
|
{
|
||||||
rcl_node_options_t options;
|
rcl_node_options_t options;
|
||||||
|
@ -46,7 +56,11 @@ rcl_get_zero_initialized_node()
|
||||||
}
|
}
|
||||||
|
|
||||||
rcl_ret_t
|
rcl_ret_t
|
||||||
rcl_node_init(rcl_node_t * node, const char * name, const rcl_node_options_t * options)
|
rcl_node_init(
|
||||||
|
rcl_node_t * node,
|
||||||
|
const char * name,
|
||||||
|
const char * namespace_,
|
||||||
|
const rcl_node_options_t * options)
|
||||||
{
|
{
|
||||||
size_t domain_id = 0;
|
size_t domain_id = 0;
|
||||||
const char * ros_domain_id;
|
const char * ros_domain_id;
|
||||||
|
@ -56,6 +70,7 @@ rcl_node_init(rcl_node_t * node, const char * name, const rcl_node_options_t * o
|
||||||
rcl_ret_t ret;
|
rcl_ret_t ret;
|
||||||
rcl_ret_t fail_ret = RCL_RET_ERROR;
|
rcl_ret_t fail_ret = RCL_RET_ERROR;
|
||||||
RCL_CHECK_ARGUMENT_FOR_NULL(name, RCL_RET_INVALID_ARGUMENT);
|
RCL_CHECK_ARGUMENT_FOR_NULL(name, RCL_RET_INVALID_ARGUMENT);
|
||||||
|
RCL_CHECK_ARGUMENT_FOR_NULL(namespace_, RCL_RET_INVALID_ARGUMENT);
|
||||||
RCL_CHECK_ARGUMENT_FOR_NULL(options, RCL_RET_INVALID_ARGUMENT);
|
RCL_CHECK_ARGUMENT_FOR_NULL(options, RCL_RET_INVALID_ARGUMENT);
|
||||||
RCL_CHECK_ARGUMENT_FOR_NULL(node, RCL_RET_INVALID_ARGUMENT);
|
RCL_CHECK_ARGUMENT_FOR_NULL(node, RCL_RET_INVALID_ARGUMENT);
|
||||||
if (node->impl) {
|
if (node->impl) {
|
||||||
|
@ -72,18 +87,69 @@ rcl_node_init(rcl_node_t * node, const char * name, const rcl_node_options_t * o
|
||||||
allocator->allocate, "allocate not set", return RCL_RET_INVALID_ARGUMENT);
|
allocator->allocate, "allocate not set", return RCL_RET_INVALID_ARGUMENT);
|
||||||
RCL_CHECK_FOR_NULL_WITH_MSG(
|
RCL_CHECK_FOR_NULL_WITH_MSG(
|
||||||
allocator->deallocate, "deallocate not set", return RCL_RET_INVALID_ARGUMENT);
|
allocator->deallocate, "deallocate not set", return RCL_RET_INVALID_ARGUMENT);
|
||||||
|
// Make sure the node name is valid before allocating memory.
|
||||||
|
int validation_result = 0;
|
||||||
|
ret = rmw_validate_node_name(name, &validation_result, NULL);
|
||||||
|
if (ret != RMW_RET_OK) {
|
||||||
|
RCL_SET_ERROR_MSG(rmw_get_error_string_safe());
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if (validation_result != RMW_NODE_NAME_VALID) {
|
||||||
|
const char * msg = rmw_node_name_validation_result_string(validation_result);
|
||||||
|
if (!msg) {
|
||||||
|
msg = "unknown validation_result, this should not happen";
|
||||||
|
}
|
||||||
|
RCL_SET_ERROR_MSG(msg);
|
||||||
|
return RCL_RET_NODE_INVALID_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process the namespace.
|
||||||
|
size_t namespace_length = strlen(namespace_);
|
||||||
|
const char * local_namespace_ = namespace_;
|
||||||
|
bool should_free_local_namespace_ = false;
|
||||||
|
// If the namespace is just an empty string, replace with "/"
|
||||||
|
if (namespace_length == 0) {
|
||||||
|
// Have this special case to avoid a memory allocation when "" is passed.
|
||||||
|
local_namespace_ = "/";
|
||||||
|
}
|
||||||
|
// If the namespace does not start with a /, add one.
|
||||||
|
if (namespace_length > 0 && namespace_[0] != '/') {
|
||||||
|
// TODO(wjwwood): replace with generic strcat that takes an allocator once available
|
||||||
|
// length + 2, because new leading / and terminating \0
|
||||||
|
char * temp = (char *)allocator->allocate(namespace_length + 2, allocator->state);
|
||||||
|
RCL_CHECK_FOR_NULL_WITH_MSG(temp, "allocating memory failed", return RCL_RET_BAD_ALLOC);
|
||||||
|
temp[0] = '/';
|
||||||
|
memcpy(temp + 1, namespace_, strlen(namespace_) + 1);
|
||||||
|
local_namespace_ = temp;
|
||||||
|
should_free_local_namespace_ = true;
|
||||||
|
}
|
||||||
|
// Make sure the node namespace is valid.
|
||||||
|
validation_result = 0;
|
||||||
|
ret = rmw_validate_namespace(local_namespace_, &validation_result, NULL);
|
||||||
|
if (ret != RMW_RET_OK) {
|
||||||
|
RCL_SET_ERROR_MSG(rmw_get_error_string_safe());
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if (validation_result != RMW_NAMESPACE_VALID) {
|
||||||
|
const char * msg = rmw_namespace_validation_result_string(validation_result);
|
||||||
|
if (!msg) {
|
||||||
|
char fixed_msg[256];
|
||||||
|
LOCAL_SNPRINTF(
|
||||||
|
fixed_msg, sizeof(fixed_msg),
|
||||||
|
"unknown validation_result '%d', this should not happen", validation_result);
|
||||||
|
RCL_SET_ERROR_MSG(fixed_msg);
|
||||||
|
} else {
|
||||||
|
RCL_SET_ERROR_MSG(msg);
|
||||||
|
}
|
||||||
|
return RCL_RET_NODE_INVALID_NAMESPACE;
|
||||||
|
}
|
||||||
|
|
||||||
// Allocate space for the implementation struct.
|
// Allocate space for the implementation struct.
|
||||||
node->impl = (rcl_node_impl_t *)allocator->allocate(sizeof(rcl_node_impl_t), allocator->state);
|
node->impl = (rcl_node_impl_t *)allocator->allocate(sizeof(rcl_node_impl_t), allocator->state);
|
||||||
RCL_CHECK_FOR_NULL_WITH_MSG(node->impl, "allocating memory failed", return RCL_RET_BAD_ALLOC);
|
RCL_CHECK_FOR_NULL_WITH_MSG(node->impl, "allocating memory failed", return RCL_RET_BAD_ALLOC);
|
||||||
node->impl->rmw_node_handle = NULL;
|
node->impl->rmw_node_handle = NULL;
|
||||||
node->impl->graph_guard_condition = NULL;
|
node->impl->graph_guard_condition = NULL;
|
||||||
// Initialize node impl.
|
// Initialize node impl.
|
||||||
// node name
|
|
||||||
size_t name_len = strlen(name);
|
|
||||||
if (name_len == 0) {
|
|
||||||
RCL_SET_ERROR_MSG("node name cannot be empty string");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
// node options (assume it is trivially copyable)
|
// node options (assume it is trivially copyable)
|
||||||
node->impl->options = *options;
|
node->impl->options = *options;
|
||||||
// node rmw_node_handle
|
// node rmw_node_handle
|
||||||
|
@ -106,9 +172,13 @@ rcl_node_init(rcl_node_t * node, const char * name, const rcl_node_options_t * o
|
||||||
}
|
}
|
||||||
// actual domain id
|
// actual domain id
|
||||||
node->impl->actual_domain_id = domain_id;
|
node->impl->actual_domain_id = domain_id;
|
||||||
node->impl->rmw_node_handle = rmw_create_node(name, domain_id);
|
node->impl->rmw_node_handle = rmw_create_node(name, local_namespace_, domain_id);
|
||||||
RCL_CHECK_FOR_NULL_WITH_MSG(
|
RCL_CHECK_FOR_NULL_WITH_MSG(
|
||||||
node->impl->rmw_node_handle, rmw_get_error_string_safe(), goto fail);
|
node->impl->rmw_node_handle, rmw_get_error_string_safe(), goto fail);
|
||||||
|
// free local_namespace_ if necessary
|
||||||
|
if (should_free_local_namespace_) {
|
||||||
|
allocator->deallocate((char *)local_namespace_, allocator->state);
|
||||||
|
}
|
||||||
// instance id
|
// instance id
|
||||||
node->impl->rcl_instance_id = rcl_get_instance_id();
|
node->impl->rcl_instance_id = rcl_get_instance_id();
|
||||||
// graph guard condition
|
// graph guard condition
|
||||||
|
@ -215,6 +285,15 @@ rcl_node_get_name(const rcl_node_t * node)
|
||||||
return node->impl->rmw_node_handle->name;
|
return node->impl->rmw_node_handle->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
rcl_node_get_namespace(const rcl_node_t * node)
|
||||||
|
{
|
||||||
|
if (!rcl_node_is_valid(node)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return node->impl->rmw_node_handle->namespace_;
|
||||||
|
}
|
||||||
|
|
||||||
const rcl_node_options_t *
|
const rcl_node_options_t *
|
||||||
rcl_node_get_options(const rcl_node_t * node)
|
rcl_node_get_options(const rcl_node_t * node)
|
||||||
{
|
{
|
||||||
|
|
|
@ -109,7 +109,7 @@ int main(int argc, char ** argv)
|
||||||
rcl_node_t node = rcl_get_zero_initialized_node();
|
rcl_node_t node = rcl_get_zero_initialized_node();
|
||||||
const char * name = "node_name";
|
const char * name = "node_name";
|
||||||
rcl_node_options_t node_options = rcl_node_get_default_options();
|
rcl_node_options_t node_options = rcl_node_get_default_options();
|
||||||
if (rcl_node_init(&node, name, &node_options) != RCL_RET_OK) {
|
if (rcl_node_init(&node, name, "", &node_options) != RCL_RET_OK) {
|
||||||
fprintf(stderr, "Error in node init: %s\n", rcl_get_error_string_safe());
|
fprintf(stderr, "Error in node init: %s\n", rcl_get_error_string_safe());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,7 +83,7 @@ int main(int argc, char ** argv)
|
||||||
rcl_node_t node = rcl_get_zero_initialized_node();
|
rcl_node_t node = rcl_get_zero_initialized_node();
|
||||||
const char * name = "node_name";
|
const char * name = "node_name";
|
||||||
rcl_node_options_t node_options = rcl_node_get_default_options();
|
rcl_node_options_t node_options = rcl_node_get_default_options();
|
||||||
if (rcl_node_init(&node, name, &node_options) != RCL_RET_OK) {
|
if (rcl_node_init(&node, name, "", &node_options) != RCL_RET_OK) {
|
||||||
fprintf(stderr, "Error in node init: %s\n", rcl_get_error_string_safe());
|
fprintf(stderr, "Error in node init: %s\n", rcl_get_error_string_safe());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ public:
|
||||||
*this->node_ptr = rcl_get_zero_initialized_node();
|
*this->node_ptr = rcl_get_zero_initialized_node();
|
||||||
const char * name = "node_name";
|
const char * name = "node_name";
|
||||||
rcl_node_options_t node_options = rcl_node_get_default_options();
|
rcl_node_options_t node_options = rcl_node_get_default_options();
|
||||||
ret = rcl_node_init(this->node_ptr, name, &node_options);
|
ret = rcl_node_init(this->node_ptr, name, "", &node_options);
|
||||||
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string_safe();
|
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string_safe();
|
||||||
set_on_unexpected_malloc_callback([]() {ASSERT_FALSE(true) << "UNEXPECTED MALLOC";});
|
set_on_unexpected_malloc_callback([]() {ASSERT_FALSE(true) << "UNEXPECTED MALLOC";});
|
||||||
set_on_unexpected_realloc_callback([]() {ASSERT_FALSE(true) << "UNEXPECTED REALLOC";});
|
set_on_unexpected_realloc_callback([]() {ASSERT_FALSE(true) << "UNEXPECTED REALLOC";});
|
||||||
|
|
|
@ -63,14 +63,14 @@ TEST_F(CLASSNAME(TestGetNodeNames, RMW_IMPLEMENTATION), test_rcl_get_node_names)
|
||||||
*node1_ptr = rcl_get_zero_initialized_node();
|
*node1_ptr = rcl_get_zero_initialized_node();
|
||||||
const char * node1_name = "node1";
|
const char * node1_name = "node1";
|
||||||
rcl_node_options_t node1_options = rcl_node_get_default_options();
|
rcl_node_options_t node1_options = rcl_node_get_default_options();
|
||||||
ret = rcl_node_init(node1_ptr, node1_name, &node1_options);
|
ret = rcl_node_init(node1_ptr, node1_name, "", &node1_options);
|
||||||
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string_safe();
|
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string_safe();
|
||||||
|
|
||||||
auto node2_ptr = new rcl_node_t;
|
auto node2_ptr = new rcl_node_t;
|
||||||
*node2_ptr = rcl_get_zero_initialized_node();
|
*node2_ptr = rcl_get_zero_initialized_node();
|
||||||
const char * node2_name = "node2";
|
const char * node2_name = "node2";
|
||||||
rcl_node_options_t node2_options = rcl_node_get_default_options();
|
rcl_node_options_t node2_options = rcl_node_get_default_options();
|
||||||
ret = rcl_node_init(node2_ptr, node2_name, &node2_options);
|
ret = rcl_node_init(node2_ptr, node2_name, "", &node2_options);
|
||||||
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string_safe();
|
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string_safe();
|
||||||
|
|
||||||
std::this_thread::sleep_for(1s);
|
std::this_thread::sleep_for(1s);
|
||||||
|
|
|
@ -63,7 +63,7 @@ public:
|
||||||
*this->old_node_ptr = rcl_get_zero_initialized_node();
|
*this->old_node_ptr = rcl_get_zero_initialized_node();
|
||||||
const char * old_name = "old_node_name";
|
const char * old_name = "old_node_name";
|
||||||
rcl_node_options_t node_options = rcl_node_get_default_options();
|
rcl_node_options_t node_options = rcl_node_get_default_options();
|
||||||
ret = rcl_node_init(this->old_node_ptr, old_name, &node_options);
|
ret = rcl_node_init(this->old_node_ptr, old_name, "", &node_options);
|
||||||
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string_safe();
|
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string_safe();
|
||||||
ret = rcl_shutdown(); // after this, the old_node_ptr should be invalid
|
ret = rcl_shutdown(); // after this, the old_node_ptr should be invalid
|
||||||
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string_safe();
|
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string_safe();
|
||||||
|
@ -73,7 +73,7 @@ public:
|
||||||
this->node_ptr = new rcl_node_t;
|
this->node_ptr = new rcl_node_t;
|
||||||
*this->node_ptr = rcl_get_zero_initialized_node();
|
*this->node_ptr = rcl_get_zero_initialized_node();
|
||||||
const char * name = "node_name";
|
const char * name = "node_name";
|
||||||
ret = rcl_node_init(this->node_ptr, name, &node_options);
|
ret = rcl_node_init(this->node_ptr, name, "", &node_options);
|
||||||
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string_safe();
|
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string_safe();
|
||||||
|
|
||||||
this->wait_set_ptr = new rcl_wait_set_t;
|
this->wait_set_ptr = new rcl_wait_set_t;
|
||||||
|
|
|
@ -73,15 +73,16 @@ TEST_F(CLASSNAME(TestNodeFixture, RMW_IMPLEMENTATION), test_rcl_node_accessors)
|
||||||
// Create an invalid node (rcl_shutdown).
|
// Create an invalid node (rcl_shutdown).
|
||||||
rcl_node_t invalid_node = rcl_get_zero_initialized_node();
|
rcl_node_t invalid_node = rcl_get_zero_initialized_node();
|
||||||
const char * name = "node_name";
|
const char * name = "node_name";
|
||||||
|
const char * namespace_ = "/ns";
|
||||||
rcl_node_options_t default_options = rcl_node_get_default_options();
|
rcl_node_options_t default_options = rcl_node_get_default_options();
|
||||||
default_options.domain_id = 42; // Set the domain id to something explicit.
|
default_options.domain_id = 42; // Set the domain id to something explicit.
|
||||||
ret = rcl_node_init(&invalid_node, name, &default_options);
|
ret = rcl_node_init(&invalid_node, name, namespace_, &default_options);
|
||||||
if (is_windows && is_opensplice) {
|
if (is_windows && is_opensplice) {
|
||||||
// On Windows with OpenSplice, setting the domain id is not expected to work.
|
// On Windows with OpenSplice, setting the domain id is not expected to work.
|
||||||
ASSERT_NE(RCL_RET_OK, ret);
|
ASSERT_NE(RCL_RET_OK, ret);
|
||||||
// So retry with the default domain id setting (uses the environment as is).
|
// So retry with the default domain id setting (uses the environment as is).
|
||||||
default_options.domain_id = rcl_node_get_default_options().domain_id;
|
default_options.domain_id = rcl_node_get_default_options().domain_id;
|
||||||
ret = rcl_node_init(&invalid_node, name, &default_options);
|
ret = rcl_node_init(&invalid_node, name, namespace_, &default_options);
|
||||||
ASSERT_EQ(RCL_RET_OK, ret);
|
ASSERT_EQ(RCL_RET_OK, ret);
|
||||||
} else {
|
} else {
|
||||||
// This is the normal check (not windows and windows if not opensplice)
|
// This is the normal check (not windows and windows if not opensplice)
|
||||||
|
@ -105,7 +106,7 @@ TEST_F(CLASSNAME(TestNodeFixture, RMW_IMPLEMENTATION), test_rcl_node_accessors)
|
||||||
rcl_node_t zero_node = rcl_get_zero_initialized_node();
|
rcl_node_t zero_node = rcl_get_zero_initialized_node();
|
||||||
// Create a normal node.
|
// Create a normal node.
|
||||||
rcl_node_t node = rcl_get_zero_initialized_node();
|
rcl_node_t node = rcl_get_zero_initialized_node();
|
||||||
ret = rcl_node_init(&node, name, &default_options);
|
ret = rcl_node_init(&node, name, namespace_, &default_options);
|
||||||
ASSERT_EQ(RCL_RET_OK, ret);
|
ASSERT_EQ(RCL_RET_OK, ret);
|
||||||
auto rcl_node_exit = make_scope_exit([&node]() {
|
auto rcl_node_exit = make_scope_exit([&node]() {
|
||||||
stop_memory_checking();
|
stop_memory_checking();
|
||||||
|
@ -150,6 +151,30 @@ TEST_F(CLASSNAME(TestNodeFixture, RMW_IMPLEMENTATION), test_rcl_node_accessors)
|
||||||
if (actual_node_name) {
|
if (actual_node_name) {
|
||||||
EXPECT_EQ(std::string(name), std::string(actual_node_name));
|
EXPECT_EQ(std::string(name), std::string(actual_node_name));
|
||||||
}
|
}
|
||||||
|
// Test rcl_node_get_namespace().
|
||||||
|
const char * actual_node_namespace;
|
||||||
|
actual_node_namespace = rcl_node_get_namespace(nullptr);
|
||||||
|
EXPECT_EQ(nullptr, actual_node_namespace);
|
||||||
|
rcl_reset_error();
|
||||||
|
actual_node_namespace = rcl_node_get_namespace(&zero_node);
|
||||||
|
EXPECT_EQ(nullptr, actual_node_namespace);
|
||||||
|
rcl_reset_error();
|
||||||
|
actual_node_namespace = rcl_node_get_namespace(&invalid_node);
|
||||||
|
EXPECT_EQ(nullptr, actual_node_namespace);
|
||||||
|
rcl_reset_error();
|
||||||
|
start_memory_checking();
|
||||||
|
assert_no_malloc_begin();
|
||||||
|
assert_no_realloc_begin();
|
||||||
|
assert_no_free_begin();
|
||||||
|
actual_node_namespace = rcl_node_get_namespace(&node);
|
||||||
|
assert_no_malloc_end();
|
||||||
|
assert_no_realloc_end();
|
||||||
|
assert_no_free_end();
|
||||||
|
stop_memory_checking();
|
||||||
|
EXPECT_TRUE(actual_node_namespace ? true : false);
|
||||||
|
if (actual_node_namespace) {
|
||||||
|
EXPECT_EQ(std::string(namespace_), std::string(actual_node_namespace));
|
||||||
|
}
|
||||||
// Test rcl_node_get_options().
|
// Test rcl_node_get_options().
|
||||||
const rcl_node_options_t * actual_options;
|
const rcl_node_options_t * actual_options;
|
||||||
actual_options = rcl_node_get_options(nullptr);
|
actual_options = rcl_node_get_options(nullptr);
|
||||||
|
@ -179,12 +204,15 @@ TEST_F(CLASSNAME(TestNodeFixture, RMW_IMPLEMENTATION), test_rcl_node_accessors)
|
||||||
size_t actual_domain_id;
|
size_t actual_domain_id;
|
||||||
ret = rcl_node_get_domain_id(nullptr, &actual_domain_id);
|
ret = rcl_node_get_domain_id(nullptr, &actual_domain_id);
|
||||||
EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret);
|
EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret);
|
||||||
|
ASSERT_TRUE(rcl_error_is_set());
|
||||||
rcl_reset_error();
|
rcl_reset_error();
|
||||||
ret = rcl_node_get_domain_id(&zero_node, &actual_domain_id);
|
ret = rcl_node_get_domain_id(&zero_node, &actual_domain_id);
|
||||||
EXPECT_EQ(RCL_RET_NODE_INVALID, ret);
|
EXPECT_EQ(RCL_RET_NODE_INVALID, ret);
|
||||||
|
ASSERT_TRUE(rcl_error_is_set());
|
||||||
rcl_reset_error();
|
rcl_reset_error();
|
||||||
ret = rcl_node_get_domain_id(&invalid_node, &actual_domain_id);
|
ret = rcl_node_get_domain_id(&invalid_node, &actual_domain_id);
|
||||||
EXPECT_EQ(RCL_RET_NODE_INVALID, ret);
|
EXPECT_EQ(RCL_RET_NODE_INVALID, ret);
|
||||||
|
ASSERT_TRUE(rcl_error_is_set());
|
||||||
rcl_reset_error();
|
rcl_reset_error();
|
||||||
start_memory_checking();
|
start_memory_checking();
|
||||||
assert_no_malloc_begin();
|
assert_no_malloc_begin();
|
||||||
|
@ -278,10 +306,12 @@ TEST_F(CLASSNAME(TestNodeFixture, RMW_IMPLEMENTATION), test_rcl_node_life_cycle)
|
||||||
rcl_ret_t ret;
|
rcl_ret_t ret;
|
||||||
rcl_node_t node = rcl_get_zero_initialized_node();
|
rcl_node_t node = rcl_get_zero_initialized_node();
|
||||||
const char * name = "node_name";
|
const char * name = "node_name";
|
||||||
|
const char * namespace_ = "/ns";
|
||||||
rcl_node_options_t default_options = rcl_node_get_default_options();
|
rcl_node_options_t default_options = rcl_node_get_default_options();
|
||||||
// Trying to init before rcl_init() should fail.
|
// Trying to init before rcl_init() should fail.
|
||||||
ret = rcl_node_init(&node, name, &default_options);
|
ret = rcl_node_init(&node, name, "", &default_options);
|
||||||
ASSERT_EQ(RCL_RET_NOT_INIT, ret) << "Expected RCL_RET_NOT_INIT";
|
ASSERT_EQ(RCL_RET_NOT_INIT, ret) << "Expected RCL_RET_NOT_INIT";
|
||||||
|
ASSERT_TRUE(rcl_error_is_set());
|
||||||
rcl_reset_error();
|
rcl_reset_error();
|
||||||
// Initialize rcl with rcl_init().
|
// Initialize rcl with rcl_init().
|
||||||
ret = rcl_init(0, nullptr, rcl_get_default_allocator());
|
ret = rcl_init(0, nullptr, rcl_get_default_allocator());
|
||||||
|
@ -291,48 +321,60 @@ TEST_F(CLASSNAME(TestNodeFixture, RMW_IMPLEMENTATION), test_rcl_node_life_cycle)
|
||||||
ASSERT_EQ(RCL_RET_OK, ret);
|
ASSERT_EQ(RCL_RET_OK, ret);
|
||||||
});
|
});
|
||||||
// Try invalid arguments.
|
// Try invalid arguments.
|
||||||
ret = rcl_node_init(nullptr, name, &default_options);
|
ret = rcl_node_init(nullptr, name, namespace_, &default_options);
|
||||||
EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret);
|
EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret);
|
||||||
|
ASSERT_TRUE(rcl_error_is_set());
|
||||||
rcl_reset_error();
|
rcl_reset_error();
|
||||||
ret = rcl_node_init(&node, nullptr, &default_options);
|
ret = rcl_node_init(&node, nullptr, namespace_, &default_options);
|
||||||
EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret);
|
EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret);
|
||||||
|
ASSERT_TRUE(rcl_error_is_set());
|
||||||
rcl_reset_error();
|
rcl_reset_error();
|
||||||
ret = rcl_node_init(&node, name, nullptr);
|
ret = rcl_node_init(&node, name, nullptr, &default_options);
|
||||||
EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret);
|
EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret);
|
||||||
|
ASSERT_TRUE(rcl_error_is_set());
|
||||||
|
rcl_reset_error();
|
||||||
|
ret = rcl_node_init(&node, name, namespace_, nullptr);
|
||||||
|
EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret);
|
||||||
|
ASSERT_TRUE(rcl_error_is_set());
|
||||||
rcl_reset_error();
|
rcl_reset_error();
|
||||||
// Try with invalid allocator.
|
// Try with invalid allocator.
|
||||||
rcl_node_options_t options_with_invalid_allocator = rcl_node_get_default_options();
|
rcl_node_options_t options_with_invalid_allocator = rcl_node_get_default_options();
|
||||||
options_with_invalid_allocator.allocator.allocate = nullptr;
|
options_with_invalid_allocator.allocator.allocate = nullptr;
|
||||||
options_with_invalid_allocator.allocator.deallocate = nullptr;
|
options_with_invalid_allocator.allocator.deallocate = nullptr;
|
||||||
options_with_invalid_allocator.allocator.reallocate = nullptr;
|
options_with_invalid_allocator.allocator.reallocate = nullptr;
|
||||||
ret = rcl_node_init(&node, name, &options_with_invalid_allocator);
|
ret = rcl_node_init(&node, name, namespace_, &options_with_invalid_allocator);
|
||||||
EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret) << "Expected RCL_RET_INVALID_ARGUMENT";
|
EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret) << "Expected RCL_RET_INVALID_ARGUMENT";
|
||||||
|
ASSERT_TRUE(rcl_error_is_set());
|
||||||
rcl_reset_error();
|
rcl_reset_error();
|
||||||
// Try with failing allocator.
|
// Try with failing allocator.
|
||||||
rcl_node_options_t options_with_failing_allocator = rcl_node_get_default_options();
|
rcl_node_options_t options_with_failing_allocator = rcl_node_get_default_options();
|
||||||
options_with_failing_allocator.allocator.allocate = failing_malloc;
|
options_with_failing_allocator.allocator.allocate = failing_malloc;
|
||||||
options_with_failing_allocator.allocator.deallocate = failing_free;
|
options_with_failing_allocator.allocator.deallocate = failing_free;
|
||||||
options_with_failing_allocator.allocator.reallocate = failing_realloc;
|
options_with_failing_allocator.allocator.reallocate = failing_realloc;
|
||||||
ret = rcl_node_init(&node, name, &options_with_failing_allocator);
|
ret = rcl_node_init(&node, name, namespace_, &options_with_failing_allocator);
|
||||||
EXPECT_EQ(RCL_RET_BAD_ALLOC, ret) << "Expected RCL_RET_BAD_ALLOC";
|
EXPECT_EQ(RCL_RET_BAD_ALLOC, ret) << "Expected RCL_RET_BAD_ALLOC";
|
||||||
|
ASSERT_TRUE(rcl_error_is_set());
|
||||||
rcl_reset_error();
|
rcl_reset_error();
|
||||||
// Try fini with invalid arguments.
|
// Try fini with invalid arguments.
|
||||||
ret = rcl_node_fini(nullptr);
|
ret = rcl_node_fini(nullptr);
|
||||||
EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret) << "Expected RCL_RET_INVALID_ARGUMENT";
|
EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret) << "Expected RCL_RET_INVALID_ARGUMENT";
|
||||||
|
ASSERT_TRUE(rcl_error_is_set());
|
||||||
rcl_reset_error();
|
rcl_reset_error();
|
||||||
// Try fini with an uninitialized node.
|
// Try fini with an uninitialized node.
|
||||||
ret = rcl_node_fini(&node);
|
ret = rcl_node_fini(&node);
|
||||||
EXPECT_EQ(RCL_RET_OK, ret);
|
EXPECT_EQ(RCL_RET_OK, ret);
|
||||||
// Try a normal init and fini.
|
// Try a normal init and fini.
|
||||||
ret = rcl_node_init(&node, name, &default_options);
|
ret = rcl_node_init(&node, name, namespace_, &default_options);
|
||||||
EXPECT_EQ(RCL_RET_OK, ret);
|
EXPECT_EQ(RCL_RET_OK, ret);
|
||||||
ret = rcl_node_fini(&node);
|
ret = rcl_node_fini(&node);
|
||||||
EXPECT_EQ(RCL_RET_OK, ret);
|
EXPECT_EQ(RCL_RET_OK, ret);
|
||||||
// Try repeated init and fini calls.
|
// Try repeated init and fini calls.
|
||||||
ret = rcl_node_init(&node, name, &default_options);
|
ret = rcl_node_init(&node, name, namespace_, &default_options);
|
||||||
EXPECT_EQ(RCL_RET_OK, ret);
|
EXPECT_EQ(RCL_RET_OK, ret);
|
||||||
ret = rcl_node_init(&node, name, &default_options);
|
ret = rcl_node_init(&node, name, namespace_, &default_options);
|
||||||
EXPECT_EQ(RCL_RET_ALREADY_INIT, ret) << "Expected RCL_RET_ALREADY_INIT";
|
EXPECT_EQ(RCL_RET_ALREADY_INIT, ret) << "Expected RCL_RET_ALREADY_INIT";
|
||||||
|
ASSERT_TRUE(rcl_error_is_set());
|
||||||
|
rcl_reset_error();
|
||||||
ret = rcl_node_fini(&node);
|
ret = rcl_node_fini(&node);
|
||||||
EXPECT_EQ(RCL_RET_OK, ret);
|
EXPECT_EQ(RCL_RET_OK, ret);
|
||||||
ret = rcl_node_fini(&node);
|
ret = rcl_node_fini(&node);
|
||||||
|
@ -340,7 +382,7 @@ TEST_F(CLASSNAME(TestNodeFixture, RMW_IMPLEMENTATION), test_rcl_node_life_cycle)
|
||||||
// Try with a specific domain id.
|
// Try with a specific domain id.
|
||||||
rcl_node_options_t options_with_custom_domain_id = rcl_node_get_default_options();
|
rcl_node_options_t options_with_custom_domain_id = rcl_node_get_default_options();
|
||||||
options_with_custom_domain_id.domain_id = 42;
|
options_with_custom_domain_id.domain_id = 42;
|
||||||
ret = rcl_node_init(&node, name, &options_with_custom_domain_id);
|
ret = rcl_node_init(&node, name, namespace_, &options_with_custom_domain_id);
|
||||||
if (is_windows && is_opensplice) {
|
if (is_windows && is_opensplice) {
|
||||||
// A custom domain id is not expected to work on Windows with Opensplice.
|
// A custom domain id is not expected to work on Windows with Opensplice.
|
||||||
EXPECT_NE(RCL_RET_OK, ret);
|
EXPECT_NE(RCL_RET_OK, ret);
|
||||||
|
@ -351,3 +393,161 @@ TEST_F(CLASSNAME(TestNodeFixture, RMW_IMPLEMENTATION), test_rcl_node_life_cycle)
|
||||||
EXPECT_EQ(RCL_RET_OK, ret);
|
EXPECT_EQ(RCL_RET_OK, ret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Tests the node name restrictions enforcement.
|
||||||
|
*/
|
||||||
|
TEST_F(CLASSNAME(TestNodeFixture, RMW_IMPLEMENTATION), test_rcl_node_name_restrictions) {
|
||||||
|
stop_memory_checking();
|
||||||
|
rcl_ret_t ret;
|
||||||
|
|
||||||
|
// Initialize rcl with rcl_init().
|
||||||
|
ret = rcl_init(0, nullptr, rcl_get_default_allocator());
|
||||||
|
ASSERT_EQ(RCL_RET_OK, ret);
|
||||||
|
auto rcl_shutdown_exit = make_scope_exit([]() {
|
||||||
|
rcl_ret_t ret = rcl_shutdown();
|
||||||
|
ASSERT_EQ(RCL_RET_OK, ret);
|
||||||
|
});
|
||||||
|
|
||||||
|
const char * namespace_ = "/ns";
|
||||||
|
rcl_node_options_t default_options = rcl_node_get_default_options();
|
||||||
|
|
||||||
|
// First do a normal node name.
|
||||||
|
{
|
||||||
|
rcl_node_t node = rcl_get_zero_initialized_node();
|
||||||
|
ret = rcl_node_init(&node, "my_node_42", namespace_, &default_options);
|
||||||
|
ASSERT_EQ(RCL_RET_OK, ret);
|
||||||
|
rcl_ret_t ret = rcl_node_fini(&node);
|
||||||
|
EXPECT_EQ(RCL_RET_OK, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Node name with invalid characters.
|
||||||
|
{
|
||||||
|
rcl_node_t node = rcl_get_zero_initialized_node();
|
||||||
|
ret = rcl_node_init(&node, "my_node_42$", namespace_, &default_options);
|
||||||
|
ASSERT_EQ(RCL_RET_NODE_INVALID_NAME, ret);
|
||||||
|
ASSERT_TRUE(rcl_error_is_set());
|
||||||
|
rcl_reset_error();
|
||||||
|
rcl_ret_t ret = rcl_node_fini(&node);
|
||||||
|
EXPECT_EQ(RCL_RET_OK, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Node name with /, which is valid in a topic, but not a node name.
|
||||||
|
{
|
||||||
|
rcl_node_t node = rcl_get_zero_initialized_node();
|
||||||
|
ret = rcl_node_init(&node, "my/node_42", namespace_, &default_options);
|
||||||
|
ASSERT_EQ(RCL_RET_NODE_INVALID_NAME, ret);
|
||||||
|
ASSERT_TRUE(rcl_error_is_set());
|
||||||
|
rcl_reset_error();
|
||||||
|
rcl_ret_t ret = rcl_node_fini(&node);
|
||||||
|
EXPECT_EQ(RCL_RET_OK, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Node name with {}, which is valid in a topic, but not a node name.
|
||||||
|
{
|
||||||
|
rcl_node_t node = rcl_get_zero_initialized_node();
|
||||||
|
ret = rcl_node_init(&node, "my_{node}_42", namespace_, &default_options);
|
||||||
|
ASSERT_EQ(RCL_RET_NODE_INVALID_NAME, ret);
|
||||||
|
ASSERT_TRUE(rcl_error_is_set());
|
||||||
|
rcl_reset_error();
|
||||||
|
rcl_ret_t ret = rcl_node_fini(&node);
|
||||||
|
EXPECT_EQ(RCL_RET_OK, ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tests the node namespace restrictions enforcement.
|
||||||
|
*/
|
||||||
|
TEST_F(CLASSNAME(TestNodeFixture, RMW_IMPLEMENTATION), test_rcl_node_namespace_restrictions) {
|
||||||
|
stop_memory_checking();
|
||||||
|
rcl_ret_t ret;
|
||||||
|
|
||||||
|
// Initialize rcl with rcl_init().
|
||||||
|
ret = rcl_init(0, nullptr, rcl_get_default_allocator());
|
||||||
|
ASSERT_EQ(RCL_RET_OK, ret);
|
||||||
|
auto rcl_shutdown_exit = make_scope_exit([]() {
|
||||||
|
rcl_ret_t ret = rcl_shutdown();
|
||||||
|
ASSERT_EQ(RCL_RET_OK, ret);
|
||||||
|
});
|
||||||
|
|
||||||
|
const char * name = "node";
|
||||||
|
rcl_node_options_t default_options = rcl_node_get_default_options();
|
||||||
|
|
||||||
|
// First do a normal node namespace.
|
||||||
|
{
|
||||||
|
rcl_node_t node = rcl_get_zero_initialized_node();
|
||||||
|
ret = rcl_node_init(&node, name, "/ns", &default_options);
|
||||||
|
ASSERT_EQ(RCL_RET_OK, ret);
|
||||||
|
rcl_ret_t ret = rcl_node_fini(&node);
|
||||||
|
EXPECT_EQ(RCL_RET_OK, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Node namespace which is an empty string, which is also valid.
|
||||||
|
{
|
||||||
|
rcl_node_t node = rcl_get_zero_initialized_node();
|
||||||
|
ret = rcl_node_init(&node, name, "", &default_options);
|
||||||
|
ASSERT_EQ(RCL_RET_OK, ret);
|
||||||
|
ASSERT_STREQ("/", rcl_node_get_namespace(&node));
|
||||||
|
rcl_ret_t ret = rcl_node_fini(&node);
|
||||||
|
EXPECT_EQ(RCL_RET_OK, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Node namespace which is just a forward slash, which is valid.
|
||||||
|
{
|
||||||
|
rcl_node_t node = rcl_get_zero_initialized_node();
|
||||||
|
ret = rcl_node_init(&node, name, "/", &default_options);
|
||||||
|
ASSERT_EQ(RCL_RET_OK, ret);
|
||||||
|
rcl_ret_t ret = rcl_node_fini(&node);
|
||||||
|
EXPECT_EQ(RCL_RET_OK, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Node namespaces with invalid characters.
|
||||||
|
{
|
||||||
|
rcl_node_t node = rcl_get_zero_initialized_node();
|
||||||
|
ret = rcl_node_init(&node, name, "/ns/{name}", &default_options);
|
||||||
|
ASSERT_EQ(RCL_RET_NODE_INVALID_NAMESPACE, ret);
|
||||||
|
ASSERT_TRUE(rcl_error_is_set());
|
||||||
|
rcl_reset_error();
|
||||||
|
rcl_ret_t ret = rcl_node_fini(&node);
|
||||||
|
EXPECT_EQ(RCL_RET_OK, ret);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
rcl_node_t node = rcl_get_zero_initialized_node();
|
||||||
|
ret = rcl_node_init(&node, name, "/~/", &default_options);
|
||||||
|
ASSERT_EQ(RCL_RET_NODE_INVALID_NAMESPACE, ret);
|
||||||
|
ASSERT_TRUE(rcl_error_is_set());
|
||||||
|
rcl_reset_error();
|
||||||
|
rcl_ret_t ret = rcl_node_fini(&node);
|
||||||
|
EXPECT_EQ(RCL_RET_OK, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Node namespace with a trailing / which is not allowed.
|
||||||
|
{
|
||||||
|
rcl_node_t node = rcl_get_zero_initialized_node();
|
||||||
|
ret = rcl_node_init(&node, name, "/ns/foo/", &default_options);
|
||||||
|
ASSERT_EQ(RCL_RET_NODE_INVALID_NAMESPACE, ret);
|
||||||
|
ASSERT_TRUE(rcl_error_is_set());
|
||||||
|
rcl_reset_error();
|
||||||
|
rcl_ret_t ret = rcl_node_fini(&node);
|
||||||
|
EXPECT_EQ(RCL_RET_OK, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Node namespace which is not absolute, it should get / added automatically.
|
||||||
|
{
|
||||||
|
rcl_node_t node = rcl_get_zero_initialized_node();
|
||||||
|
ret = rcl_node_init(&node, name, "ns", &default_options);
|
||||||
|
ASSERT_EQ(RCL_RET_OK, ret);
|
||||||
|
ASSERT_STREQ("/ns", rcl_node_get_namespace(&node));
|
||||||
|
rcl_ret_t ret = rcl_node_fini(&node);
|
||||||
|
EXPECT_EQ(RCL_RET_OK, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Other reasons for being invalid, which are related to being part of a topic.
|
||||||
|
{
|
||||||
|
rcl_node_t node = rcl_get_zero_initialized_node();
|
||||||
|
ret = rcl_node_init(&node, name, "/starts/with/42number", &default_options);
|
||||||
|
ASSERT_EQ(RCL_RET_NODE_INVALID_NAMESPACE, ret);
|
||||||
|
ASSERT_TRUE(rcl_error_is_set());
|
||||||
|
rcl_reset_error();
|
||||||
|
rcl_ret_t ret = rcl_node_fini(&node);
|
||||||
|
EXPECT_EQ(RCL_RET_OK, ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ public:
|
||||||
*this->node_ptr = rcl_get_zero_initialized_node();
|
*this->node_ptr = rcl_get_zero_initialized_node();
|
||||||
const char * name = "node_name";
|
const char * name = "node_name";
|
||||||
rcl_node_options_t node_options = rcl_node_get_default_options();
|
rcl_node_options_t node_options = rcl_node_get_default_options();
|
||||||
ret = rcl_node_init(this->node_ptr, name, &node_options);
|
ret = rcl_node_init(this->node_ptr, name, "", &node_options);
|
||||||
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string_safe();
|
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string_safe();
|
||||||
set_on_unexpected_malloc_callback([]() {ASSERT_FALSE(true) << "UNEXPECTED MALLOC";});
|
set_on_unexpected_malloc_callback([]() {ASSERT_FALSE(true) << "UNEXPECTED MALLOC";});
|
||||||
set_on_unexpected_realloc_callback([]() {ASSERT_FALSE(true) << "UNEXPECTED REALLOC";});
|
set_on_unexpected_realloc_callback([]() {ASSERT_FALSE(true) << "UNEXPECTED REALLOC";});
|
||||||
|
|
|
@ -49,7 +49,7 @@ public:
|
||||||
*this->node_ptr = rcl_get_zero_initialized_node();
|
*this->node_ptr = rcl_get_zero_initialized_node();
|
||||||
const char * name = "node_name";
|
const char * name = "node_name";
|
||||||
rcl_node_options_t node_options = rcl_node_get_default_options();
|
rcl_node_options_t node_options = rcl_node_get_default_options();
|
||||||
ret = rcl_node_init(this->node_ptr, name, &node_options);
|
ret = rcl_node_init(this->node_ptr, name, "", &node_options);
|
||||||
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string_safe();
|
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string_safe();
|
||||||
set_on_unexpected_malloc_callback([]() {ASSERT_FALSE(true) << "UNEXPECTED MALLOC";});
|
set_on_unexpected_malloc_callback([]() {ASSERT_FALSE(true) << "UNEXPECTED MALLOC";});
|
||||||
set_on_unexpected_realloc_callback([]() {ASSERT_FALSE(true) << "UNEXPECTED REALLOC";});
|
set_on_unexpected_realloc_callback([]() {ASSERT_FALSE(true) << "UNEXPECTED REALLOC";});
|
||||||
|
|
|
@ -50,7 +50,7 @@ public:
|
||||||
*this->node_ptr = rcl_get_zero_initialized_node();
|
*this->node_ptr = rcl_get_zero_initialized_node();
|
||||||
const char * name = "node_name";
|
const char * name = "node_name";
|
||||||
rcl_node_options_t node_options = rcl_node_get_default_options();
|
rcl_node_options_t node_options = rcl_node_get_default_options();
|
||||||
ret = rcl_node_init(this->node_ptr, name, &node_options);
|
ret = rcl_node_init(this->node_ptr, name, "", &node_options);
|
||||||
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string_safe();
|
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string_safe();
|
||||||
set_on_unexpected_malloc_callback([]() {ASSERT_FALSE(true) << "UNEXPECTED MALLOC";});
|
set_on_unexpected_malloc_callback([]() {ASSERT_FALSE(true) << "UNEXPECTED MALLOC";});
|
||||||
set_on_unexpected_realloc_callback([]() {ASSERT_FALSE(true) << "UNEXPECTED REALLOC";});
|
set_on_unexpected_realloc_callback([]() {ASSERT_FALSE(true) << "UNEXPECTED REALLOC";});
|
||||||
|
|
|
@ -42,7 +42,7 @@ protected:
|
||||||
*this->node_ptr = rcl_get_zero_initialized_node();
|
*this->node_ptr = rcl_get_zero_initialized_node();
|
||||||
const char * name = "node_name";
|
const char * name = "node_name";
|
||||||
rcl_node_options_t node_options = rcl_node_get_default_options();
|
rcl_node_options_t node_options = rcl_node_get_default_options();
|
||||||
ret = rcl_node_init(this->node_ptr, name, &node_options);
|
ret = rcl_node_init(this->node_ptr, name, "", &node_options);
|
||||||
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string_safe();
|
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string_safe();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ protected:
|
||||||
*this->node_ptr = rcl_get_zero_initialized_node();
|
*this->node_ptr = rcl_get_zero_initialized_node();
|
||||||
const char * name = "node_name";
|
const char * name = "node_name";
|
||||||
rcl_node_options_t node_options = rcl_node_get_default_options();
|
rcl_node_options_t node_options = rcl_node_get_default_options();
|
||||||
ret = rcl_node_init(this->node_ptr, name, &node_options);
|
ret = rcl_node_init(this->node_ptr, name, "", &node_options);
|
||||||
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string_safe();
|
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string_safe();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue