Skip to content
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

introduce ROS_DISABLE_LOAN_MSG to disable can_loan_messages. #949

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions rcl/include/rcl/node.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ extern "C"
#include "rcl/types.h"
#include "rcl/visibility_control.h"

extern const char * const RCL_DISABLE_LOANED_MESSAGES_ENV_VAR;

typedef struct rcl_node_impl_s rcl_node_impl_t;

/// Structure which encapsulates a ROS Node.
Expand Down Expand Up @@ -533,6 +535,20 @@ rcl_node_resolve_name(
bool only_expand,
char ** output_name);

/// Check if loaned message is disabled, according to the environment variable.
/**
* If the `ROS_DISABLE_LOANED_MESSAGES` environment variable is set to "1",
* `disable_loaned_message` will be set to true.
*
* \param[out] disable_loaned_message Must not be NULL.
* \return #RCL_RET_INVALID_ARGUMENT if an argument is not valid, or
* \return #RCL_RET_ERROR if an unexpected error happened, or
* \return #RCL_RET_OK.
*/
RCL_PUBLIC
rcl_ret_t
rcl_get_disable_loaned_message(bool * disable_loaned_message);

#ifdef __cplusplus
}
#endif
Expand Down
22 changes: 22 additions & 0 deletions rcl/src/rcl/node.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ extern "C"
#include "rcl/remap.h"
#include "rcl/security.h"

#include "rcutils/env.h"
#include "rcutils/filesystem.h"
#include "rcutils/find.h"
#include "rcutils/format_string.h"
Expand All @@ -52,6 +53,8 @@ extern "C"

#include "./context_impl.h"

const char * const RCL_DISABLE_LOANED_MESSAGES_ENV_VAR = "ROS_DISABLE_LOANED_MESSAGES";

struct rcl_node_impl_s
{
rcl_node_options_t options;
Expand Down Expand Up @@ -514,6 +517,25 @@ rcl_node_get_logger_name(const rcl_node_t * node)
return node->impl->logger_name;
}

rcl_ret_t
rcl_get_disable_loaned_message(bool * disable_loaned_message)
{
const char * env_val = NULL;
const char * env_error_str = NULL;

RCL_CHECK_ARGUMENT_FOR_NULL(disable_loaned_message, RCL_RET_INVALID_ARGUMENT);

env_error_str = rcutils_get_env(RCL_DISABLE_LOANED_MESSAGES_ENV_VAR, &env_val);
if (NULL != env_error_str) {
RCL_SET_ERROR_MSG_WITH_FORMAT_STRING(
"Error getting env var: '" RCUTILS_STRINGIFY(RCL_DISABLE_LOANED_MESSAGES_ENV_VAR) "': %s\n",
env_error_str);
return RCL_RET_ERROR;
}

*disable_loaned_message = (strcmp(env_val, "1") == 0);
return RCL_RET_OK;
}
#ifdef __cplusplus
}
#endif
7 changes: 7 additions & 0 deletions rcl/src/rcl/publisher.c
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,13 @@ rcl_publisher_can_loan_messages(const rcl_publisher_t * publisher)
if (!rcl_publisher_is_valid(publisher)) {
return false; // error message already set
}

bool disable_loaned_message = false;
rcl_ret_t ret = rcl_get_disable_loaned_message(&disable_loaned_message);
if (ret == RCL_RET_OK && disable_loaned_message) {
return false;
}

return publisher->impl->rmw_handle->can_loan_messages;
}

Expand Down
7 changes: 7 additions & 0 deletions rcl/src/rcl/subscription.c
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,13 @@ rcl_subscription_can_loan_messages(const rcl_subscription_t * subscription)
if (!rcl_subscription_is_valid(subscription)) {
return false; // error message already set
}

bool disable_loaned_message = false;
rcl_ret_t ret = rcl_get_disable_loaned_message(&disable_loaned_message);
if (ret == RCL_RET_OK && disable_loaned_message) {
return false;
}

return subscription->impl->rmw_handle->can_loan_messages;
}

Expand Down
46 changes: 46 additions & 0 deletions rcl/test/rcl/test_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "./failing_allocator_functions.hpp"
#include "osrf_testing_tools_cpp/memory_tools/memory_tools.hpp"
#include "osrf_testing_tools_cpp/scope_exit.hpp"
#include "rcutils/env.h"
#include "rcutils/testing/fault_injection.h"
#include "rcl/error_handling.h"
#include "rcl/logging.h"
Expand Down Expand Up @@ -997,3 +998,48 @@ TEST_F(CLASSNAME(TestNodeFixture, RMW_IMPLEMENTATION), test_rcl_node_resolve_nam
EXPECT_STREQ("/ns/relative_ns/foo", final_name);
default_allocator.deallocate(final_name, default_allocator.state);
}

/* Tests special case node_options
*/
TEST_F(CLASSNAME(TestNodeFixture, RMW_IMPLEMENTATION), test_rcl_get_disable_loaned_message) {
{
EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, rcl_get_disable_loaned_message(nullptr));
rcl_reset_error();
}

{
bool disable_loaned_message = false;
auto mock = mocking_utils::patch_and_return(
"lib:rcl", rcutils_get_env, "internal error");
EXPECT_EQ(RCL_RET_ERROR, rcl_get_disable_loaned_message(&disable_loaned_message));
rcl_reset_error();
}

{
ASSERT_TRUE(rcutils_set_env("ROS_DISABLE_LOANED_MESSAGES", "0"));
bool disable_loaned_message = true;
EXPECT_EQ(RCL_RET_OK, rcl_get_disable_loaned_message(&disable_loaned_message));
EXPECT_FALSE(disable_loaned_message);
}

{
ASSERT_TRUE(rcutils_set_env("ROS_DISABLE_LOANED_MESSAGES", "1"));
bool disable_loaned_message = false;
EXPECT_EQ(RCL_RET_OK, rcl_get_disable_loaned_message(&disable_loaned_message));
EXPECT_TRUE(disable_loaned_message);
}

{
ASSERT_TRUE(rcutils_set_env("ROS_DISABLE_LOANED_MESSAGES", "2"));
bool disable_loaned_message = true;
EXPECT_EQ(RCL_RET_OK, rcl_get_disable_loaned_message(&disable_loaned_message));
EXPECT_FALSE(disable_loaned_message);
}

{
ASSERT_TRUE(rcutils_set_env("ROS_DISABLE_LOANED_MESSAGES", "11"));
bool disable_loaned_message = true;
EXPECT_EQ(RCL_RET_OK, rcl_get_disable_loaned_message(&disable_loaned_message));
EXPECT_FALSE(disable_loaned_message);
}
}
38 changes: 38 additions & 0 deletions rcl/test/rcl/test_publisher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
#include "mimick/mimick.h"
#include "osrf_testing_tools_cpp/scope_exit.hpp"
#include "rcl/error_handling.h"
#include "rcl/node.h"
#include "rcutils/env.h"
#include "rmw/validate_full_topic_name.h"
#include "rmw/validate_node_name.h"

Expand Down Expand Up @@ -370,6 +372,42 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_publisher_loan)
}
}

TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_publisher_loan_disable) {
rcl_publisher_t publisher = rcl_get_zero_initialized_publisher();
const rosidl_message_type_support_t * ts =
ROSIDL_GET_MSG_TYPE_SUPPORT(test_msgs, msg, BasicTypes);
constexpr char topic_name[] = "pod_msg";
rcl_publisher_options_t publisher_options = rcl_publisher_get_default_options();
rcl_ret_t ret =
rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options);
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT(
{
rcl_ret_t ret = rcl_publisher_fini(&publisher, this->node_ptr);
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
});

if (rcl_publisher_can_loan_messages(&publisher)) {
ASSERT_TRUE(rcutils_set_env("ROS_DISABLE_LOANED_MESSAGES", "0"));
EXPECT_TRUE(rcl_publisher_can_loan_messages(&publisher));
ASSERT_TRUE(rcutils_set_env("ROS_DISABLE_LOANED_MESSAGES", "1"));
EXPECT_FALSE(rcl_publisher_can_loan_messages(&publisher));
ASSERT_TRUE(rcutils_set_env("ROS_DISABLE_LOANED_MESSAGES", "2"));
EXPECT_TRUE(rcl_publisher_can_loan_messages(&publisher));
ASSERT_TRUE(rcutils_set_env("ROS_DISABLE_LOANED_MESSAGES", "Unexpected"));
EXPECT_TRUE(rcl_publisher_can_loan_messages(&publisher));
} else {
ASSERT_TRUE(rcutils_set_env("ROS_DISABLE_LOANED_MESSAGES", "0"));
EXPECT_FALSE(rcl_publisher_can_loan_messages(&publisher));
ASSERT_TRUE(rcutils_set_env("ROS_DISABLE_LOANED_MESSAGES", "1"));
EXPECT_FALSE(rcl_publisher_can_loan_messages(&publisher));
ASSERT_TRUE(rcutils_set_env("ROS_DISABLE_LOANED_MESSAGES", "2"));
EXPECT_FALSE(rcl_publisher_can_loan_messages(&publisher));
ASSERT_TRUE(rcutils_set_env("ROS_DISABLE_LOANED_MESSAGES", "Unexpected"));
EXPECT_FALSE(rcl_publisher_can_loan_messages(&publisher));
}
}

TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_invalid_publisher) {
rcl_publisher_t publisher = rcl_get_zero_initialized_publisher();
const rosidl_message_type_support_t * ts =
Expand Down
38 changes: 38 additions & 0 deletions rcl/test/rcl/test_subscription.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@

#include "osrf_testing_tools_cpp/scope_exit.hpp"
#include "rcl/error_handling.h"
#include "rcl/node.h"
#include "rcutils/env.h"
#include "wait_for_entity_helpers.hpp"

#include "./allocator_testing_utils.h"
Expand Down Expand Up @@ -712,6 +714,42 @@ TEST_F(CLASSNAME(TestSubscriptionFixture, RMW_IMPLEMENTATION), test_subscription
}
}

TEST_F(CLASSNAME(TestSubscriptionFixture, RMW_IMPLEMENTATION), test_subscription_loan_disable) {
rcl_subscription_t subscription = rcl_get_zero_initialized_subscription();
const rosidl_message_type_support_t * ts =
ROSIDL_GET_MSG_TYPE_SUPPORT(test_msgs, msg, BasicTypes);
constexpr char topic[] = "pod_msg";
rcl_subscription_options_t subscription_options = rcl_subscription_get_default_options();
rcl_ret_t ret =
rcl_subscription_init(&subscription, this->node_ptr, ts, topic, &subscription_options);
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT(
{
rcl_ret_t ret = rcl_subscription_fini(&subscription, this->node_ptr);
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
});

if (rcl_subscription_can_loan_messages(&subscription)) {
ASSERT_TRUE(rcutils_set_env("ROS_DISABLE_LOANED_MESSAGES", "0"));
EXPECT_TRUE(rcl_subscription_can_loan_messages(&subscription));
ASSERT_TRUE(rcutils_set_env("ROS_DISABLE_LOANED_MESSAGES", "1"));
EXPECT_FALSE(rcl_subscription_can_loan_messages(&subscription));
ASSERT_TRUE(rcutils_set_env("ROS_DISABLE_LOANED_MESSAGES", "2"));
EXPECT_TRUE(rcl_subscription_can_loan_messages(&subscription));
ASSERT_TRUE(rcutils_set_env("ROS_DISABLE_LOANED_MESSAGES", "Unexpected"));
EXPECT_TRUE(rcl_subscription_can_loan_messages(&subscription));
} else {
ASSERT_TRUE(rcutils_set_env("ROS_DISABLE_LOANED_MESSAGES", "0"));
EXPECT_FALSE(rcl_subscription_can_loan_messages(&subscription));
ASSERT_TRUE(rcutils_set_env("ROS_DISABLE_LOANED_MESSAGES", "1"));
EXPECT_FALSE(rcl_subscription_can_loan_messages(&subscription));
ASSERT_TRUE(rcutils_set_env("ROS_DISABLE_LOANED_MESSAGES", "2"));
EXPECT_FALSE(rcl_subscription_can_loan_messages(&subscription));
ASSERT_TRUE(rcutils_set_env("ROS_DISABLE_LOANED_MESSAGES", "Unexpected"));
EXPECT_FALSE(rcl_subscription_can_loan_messages(&subscription));
}
}

/* Test for all failure modes in subscription take with loaned messages function.
*/
TEST_F(CLASSNAME(TestSubscriptionFixture, RMW_IMPLEMENTATION), test_bad_take_loaned_message) {
Expand Down