-
Notifications
You must be signed in to change notification settings - Fork 534
Add coverage tests context functions #1321
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
Changes from 5 commits
293458b
6a567dc
c462cf7
ba66fff
89bb416
eb70a4b
cbeae71
ff35723
f52f2ae
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 |
|---|---|---|
|
|
@@ -17,10 +17,15 @@ | |
| #include <string> | ||
| #include <memory> | ||
|
|
||
| #include "rcl/init.h" | ||
| #include "rcl/logging.h" | ||
|
|
||
| #include "rclcpp/contexts/default_context.hpp" | ||
| #include "rclcpp/exceptions.hpp" | ||
| #include "rclcpp/utilities.hpp" | ||
|
|
||
| #include "../mocking_utils/patch.hpp" | ||
|
|
||
| TEST(TestUtilities, remove_ros_arguments) { | ||
| const char * const argv[] = { | ||
| "process_name", | ||
|
|
@@ -78,3 +83,130 @@ TEST(TestUtilities, multi_init) { | |
| EXPECT_FALSE(rclcpp::ok(context1)); | ||
| EXPECT_FALSE(rclcpp::ok(context2)); | ||
| } | ||
|
|
||
| TEST(TestUtilities, test_context_basic_access) { | ||
| auto context1 = std::make_shared<rclcpp::contexts::DefaultContext>(); | ||
| EXPECT_NE(nullptr, context1->get_init_options().get_rcl_init_options()); | ||
| EXPECT_EQ(0u, context1->get_on_shutdown_callbacks().size()); | ||
| EXPECT_EQ(std::string{""}, context1->shutdown_reason()); | ||
| } | ||
|
|
||
| TEST(TestUtilities, test_context_basic_access_const_methods) { | ||
| auto context1 = std::make_shared<const rclcpp::contexts::DefaultContext>(); | ||
|
|
||
| EXPECT_NE(nullptr, context1->get_init_options().get_rcl_init_options()); | ||
| EXPECT_EQ(0u, context1->get_on_shutdown_callbacks().size()); | ||
| // EXPECT_EQ(std::string{""}, context1->shutdown_reason()); not available for const | ||
| } | ||
|
|
||
| MOCKING_UTILS_BOOL_OPERATOR_RETURNS_FALSE(rcl_guard_condition_options_t, ==) | ||
| MOCKING_UTILS_BOOL_OPERATOR_RETURNS_FALSE(rcl_guard_condition_options_t, !=) | ||
| MOCKING_UTILS_BOOL_OPERATOR_RETURNS_FALSE(rcl_guard_condition_options_t, >) | ||
| MOCKING_UTILS_BOOL_OPERATOR_RETURNS_FALSE(rcl_guard_condition_options_t, <) | ||
|
|
||
| TEST(TestUtilities, test_context_release_interrupt_guard_condition) { | ||
| auto context1 = std::make_shared<rclcpp::contexts::DefaultContext>(); | ||
| context1->init(0, nullptr); | ||
| rcl_wait_set_t wait_set = rcl_get_zero_initialized_wait_set(); | ||
|
|
||
| rcl_ret_t ret = rcl_wait_set_init( | ||
| &wait_set, 0, 2, 0, 0, 0, 0, context1->get_rcl_context().get(), | ||
| rcl_get_default_allocator()); | ||
| ASSERT_EQ(RCL_RET_OK, ret); | ||
|
|
||
| // Expected usage | ||
| rcl_guard_condition_t * interrupt_guard_condition = | ||
| context1->get_interrupt_guard_condition(&wait_set); | ||
| EXPECT_NE(nullptr, interrupt_guard_condition); | ||
| EXPECT_NO_THROW(context1->release_interrupt_guard_condition(&wait_set)); | ||
|
|
||
| { | ||
| auto mock = mocking_utils::patch_and_return( | ||
| "lib:rclcpp", rcl_guard_condition_init, RCL_RET_ERROR); | ||
| EXPECT_THROW( | ||
| {interrupt_guard_condition = context1->get_interrupt_guard_condition(&wait_set);}, | ||
| rclcpp::exceptions::RCLError); | ||
| } | ||
|
|
||
| { | ||
| interrupt_guard_condition = context1->get_interrupt_guard_condition(&wait_set); | ||
| auto mock = mocking_utils::inject_on_return( | ||
| "lib:rclcpp", rcl_guard_condition_fini, RCL_RET_ERROR); | ||
| EXPECT_THROW( | ||
| {context1->release_interrupt_guard_condition(&wait_set);}, | ||
| rclcpp::exceptions::RCLError); | ||
| } | ||
|
|
||
| { | ||
| interrupt_guard_condition = context1->get_interrupt_guard_condition(&wait_set); | ||
| auto mock = mocking_utils::inject_on_return( | ||
| "lib:rclcpp", rcl_guard_condition_fini, RCL_RET_ERROR); | ||
| EXPECT_NO_THROW({context1->release_interrupt_guard_condition(&wait_set, std::nothrow);}); | ||
| } | ||
|
|
||
| { | ||
| EXPECT_THROW( | ||
| context1->release_interrupt_guard_condition(nullptr), | ||
| std::runtime_error); | ||
| } | ||
|
|
||
| // Test it works after restore mocks | ||
| interrupt_guard_condition = context1->get_interrupt_guard_condition(&wait_set); | ||
| EXPECT_NE(nullptr, interrupt_guard_condition); | ||
| EXPECT_NO_THROW(context1->release_interrupt_guard_condition(&wait_set)); | ||
|
|
||
| rclcpp::shutdown(context1); | ||
|
Contributor
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. Put this in a SCOPE_EXIT after you call init (if it doesn't make sense to put in
Contributor
Author
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. osrf_tools are not added to the
Contributor
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. No need to recreate. Fortunately rclcpp has it's own SCOPE_EXIT in
Contributor
Author
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. Cool, didn't know about it, see ff35723 |
||
| } | ||
|
|
||
|
|
||
| TEST(TestUtilities, test_context_init_shutdown_fails) { | ||
| auto context = std::make_shared<rclcpp::contexts::DefaultContext>(); | ||
|
Blast545 marked this conversation as resolved.
Outdated
|
||
|
|
||
| { | ||
| auto context_fail_init = std::make_shared<rclcpp::contexts::DefaultContext>(); | ||
| auto mock = mocking_utils::patch_and_return( | ||
| "lib:rclcpp", rcl_init, RCL_RET_ERROR); | ||
| EXPECT_THROW(context_fail_init->init(0, nullptr), rclcpp::exceptions::RCLError); | ||
| } | ||
|
|
||
| { | ||
| auto context_fail_init = std::make_shared<rclcpp::contexts::DefaultContext>(); | ||
| auto mock = mocking_utils::patch_and_return( | ||
| "lib:rclcpp", rcl_logging_configure_with_output_handler, RCL_RET_ERROR); | ||
| EXPECT_THROW(context_fail_init->init(0, nullptr), rclcpp::exceptions::RCLError); | ||
| } | ||
|
|
||
| { | ||
| context->init(0, nullptr); | ||
| auto mock = mocking_utils::inject_on_return( | ||
| "lib:rclcpp", rcl_trigger_guard_condition, RCL_RET_ERROR); | ||
| // This will log a message, no throw expected | ||
| EXPECT_NO_THROW(context->shutdown("")); | ||
| } | ||
|
|
||
| { | ||
| context->init(0, nullptr); | ||
| auto mock = mocking_utils::inject_on_return( | ||
| "lib:rclcpp", rcl_shutdown, RCL_RET_ERROR); | ||
| EXPECT_THROW(context->shutdown(""), rclcpp::exceptions::RCLError); | ||
| } | ||
|
|
||
| { | ||
| context->init(0, nullptr); | ||
| auto mock = mocking_utils::inject_on_return( | ||
| "lib:rclcpp", rcl_logging_fini, RCL_RET_ERROR); | ||
| // This will log a message, no throw expected | ||
| EXPECT_NO_THROW(context->shutdown("")); | ||
| } | ||
|
|
||
| { | ||
| auto context_to_destroy = std::make_shared<rclcpp::contexts::DefaultContext>(); | ||
| auto mock = mocking_utils::inject_on_return( | ||
| "lib:rclcpp", rcl_trigger_guard_condition, RCL_RET_ERROR); | ||
| // This will log a message, no throw expected | ||
| EXPECT_NO_THROW( | ||
| { | ||
| // context_to_destroy.~rclcpp::Context(); | ||
|
Blast545 marked this conversation as resolved.
Outdated
|
||
| }); | ||
| } | ||
| } | ||
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.
This seems like a method that should be const, I wonder if there is a better thread-safe way of setting the string in
rclcpp::Contextso it can be.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.
I imagine it is not const because the shutdown_reason may change. But, in terms of this specific test, is odd that the method is not available for a const context. Not sure how to proceed here
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.
It looks like it's const because it has to lock the mutex. It might just be worth opening an issue and getting some input from others. I don't know whether it's worth investigating or if it's not an important use case.
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.
I opened #1323 to track the conversation. I didn't tag anyone as it might not be a priority at the moment, let me know if you think I should tag someone in particular.