diff --git a/rcl/test/rcl/test_wait.cpp b/rcl/test/rcl/test_wait.cpp index d61c02cd44..3578072ef5 100644 --- a/rcl/test/rcl/test_wait.cpp +++ b/rcl/test/rcl/test_wait.cpp @@ -46,11 +46,12 @@ class CLASSNAME (WaitSetTestFixture, RMW_IMPLEMENTATION) : public ::testing::Tes { 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; + ret = rcl_init_options_fini(&init_options); + EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; }); + ret = rcl_init_options_init(&init_options, rcl_get_default_allocator()); + ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; this->context_ptr = new rcl_context_t; *this->context_ptr = rcl_get_zero_initialized_context(); ret = rcl_init(0, nullptr, &init_options, this->context_ptr); @@ -66,10 +67,14 @@ class CLASSNAME (WaitSetTestFixture, RMW_IMPLEMENTATION) : public ::testing::Tes }; TEST_F(CLASSNAME(WaitSetTestFixture, RMW_IMPLEMENTATION), test_resize_to_zero) { + rcl_ret_t ret; // Initialize a wait set with a subscription and then resize it to zero. rcl_wait_set_t wait_set = rcl_get_zero_initialized_wait_set(); - rcl_ret_t ret = - rcl_wait_set_init(&wait_set, 1, 1, 1, 1, 1, 0, context_ptr, rcl_get_default_allocator()); + OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT({ + ret = rcl_wait_set_fini(&wait_set); + EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; + }); + ret = rcl_wait_set_init(&wait_set, 1, 1, 1, 1, 1, 0, context_ptr, rcl_get_default_allocator()); EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; ret = rcl_wait_set_resize(&wait_set, 0u, 0u, 0u, 0u, 0u, 0u); @@ -80,16 +85,17 @@ TEST_F(CLASSNAME(WaitSetTestFixture, RMW_IMPLEMENTATION), test_resize_to_zero) { EXPECT_EQ(wait_set.size_of_clients, 0ull); EXPECT_EQ(wait_set.size_of_services, 0ull); EXPECT_EQ(wait_set.size_of_timers, 0ull); - - ret = rcl_wait_set_fini(&wait_set); - ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; } // Test rcl_wait with a positive finite timeout value (1ms) TEST_F(CLASSNAME(WaitSetTestFixture, RMW_IMPLEMENTATION), finite_timeout) { + rcl_ret_t ret; rcl_wait_set_t wait_set = rcl_get_zero_initialized_wait_set(); - rcl_ret_t ret = - rcl_wait_set_init(&wait_set, 0, 0, 1, 0, 0, 0, context_ptr, rcl_get_default_allocator()); + OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT({ + ret = rcl_wait_set_fini(&wait_set); + EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; + }); + ret = rcl_wait_set_init(&wait_set, 0, 0, 1, 0, 0, 0, context_ptr, rcl_get_default_allocator()); EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; int64_t timeout = RCL_MS_TO_NS(10); // nanoseconds @@ -100,20 +106,26 @@ TEST_F(CLASSNAME(WaitSetTestFixture, RMW_IMPLEMENTATION), finite_timeout) { // Check time int64_t diff = std::chrono::duration_cast(after_sc - before_sc).count(); EXPECT_LE(diff, timeout + TOLERANCE); - - ret = rcl_wait_set_fini(&wait_set); - ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; } // Check that a timer overrides a negative timeout value (blocking forever) TEST_F(CLASSNAME(WaitSetTestFixture, RMW_IMPLEMENTATION), negative_timeout) { + rcl_ret_t ret; rcl_wait_set_t wait_set = rcl_get_zero_initialized_wait_set(); - rcl_ret_t ret = - rcl_wait_set_init(&wait_set, 0, 1, 1, 0, 0, 0, context_ptr, rcl_get_default_allocator()); + OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT({ + ret = rcl_wait_set_fini(&wait_set); + EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; + }); + + ret = rcl_wait_set_init(&wait_set, 0, 1, 1, 0, 0, 0, context_ptr, rcl_get_default_allocator()); EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; // Add a dummy guard condition to avoid an error rcl_guard_condition_t guard_cond = rcl_get_zero_initialized_guard_condition(); + OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT({ + ret = rcl_guard_condition_fini(&guard_cond); + EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; + }); ret = rcl_guard_condition_init( &guard_cond, this->context_ptr, rcl_guard_condition_get_default_options()); EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; @@ -126,21 +138,16 @@ TEST_F(CLASSNAME(WaitSetTestFixture, RMW_IMPLEMENTATION), negative_timeout) { ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; rcl_timer_t timer = rcl_get_zero_initialized_timer(); + OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT({ + ret = rcl_timer_fini(&timer); + EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; + }); ret = rcl_timer_init( &timer, &clock, this->context_ptr, RCL_MS_TO_NS(10), nullptr, rcl_get_default_allocator()); EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; ret = rcl_wait_set_add_timer(&wait_set, &timer, NULL); EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; - OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT({ - rcl_ret_t ret = rcl_guard_condition_fini(&guard_cond); - EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; - ret = rcl_wait_set_fini(&wait_set); - EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; - ret = rcl_timer_fini(&timer); - EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; - }); - int64_t timeout = -1; std::chrono::steady_clock::time_point before_sc = std::chrono::steady_clock::now(); ret = rcl_wait(&wait_set, timeout); @@ -154,26 +161,28 @@ TEST_F(CLASSNAME(WaitSetTestFixture, RMW_IMPLEMENTATION), negative_timeout) { // Test rcl_wait with a timeout value of 0 (non-blocking) TEST_F(CLASSNAME(WaitSetTestFixture, RMW_IMPLEMENTATION), zero_timeout) { + rcl_ret_t ret; rcl_wait_set_t wait_set = rcl_get_zero_initialized_wait_set(); - rcl_ret_t ret = - rcl_wait_set_init(&wait_set, 0, 1, 1, 0, 0, 0, context_ptr, rcl_get_default_allocator()); + OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT({ + ret = rcl_wait_set_fini(&wait_set); + EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; + }); + + ret = rcl_wait_set_init(&wait_set, 0, 1, 1, 0, 0, 0, context_ptr, rcl_get_default_allocator()); EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; // Add a dummy guard condition to avoid an error rcl_guard_condition_t guard_cond = rcl_get_zero_initialized_guard_condition(); + OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT({ + ret = rcl_guard_condition_fini(&guard_cond); + EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; + }); ret = rcl_guard_condition_init( &guard_cond, this->context_ptr, rcl_guard_condition_get_default_options()); EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; ret = rcl_wait_set_add_guard_condition(&wait_set, &guard_cond, NULL); EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; - OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT({ - rcl_ret_t ret = rcl_guard_condition_fini(&guard_cond); - EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; - ret = rcl_wait_set_fini(&wait_set); - EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; - }); - // Time spent during wait should be negligible. int64_t timeout = 0; std::chrono::steady_clock::time_point before_sc = std::chrono::steady_clock::now(); @@ -187,12 +196,20 @@ TEST_F(CLASSNAME(WaitSetTestFixture, RMW_IMPLEMENTATION), zero_timeout) { // Test rcl_wait with a timeout value of 0 (non-blocking) and an already triggered guard condition TEST_F(CLASSNAME(WaitSetTestFixture, RMW_IMPLEMENTATION), zero_timeout_triggered_guard_condition) { + rcl_ret_t ret; rcl_wait_set_t wait_set = rcl_get_zero_initialized_wait_set(); - rcl_ret_t ret = - rcl_wait_set_init(&wait_set, 0, 1, 0, 0, 0, 0, context_ptr, rcl_get_default_allocator()); + OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT({ + ret = rcl_wait_set_fini(&wait_set); + EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; + }); + ret = rcl_wait_set_init(&wait_set, 0, 1, 0, 0, 0, 0, context_ptr, rcl_get_default_allocator()); EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; rcl_guard_condition_t guard_cond = rcl_get_zero_initialized_guard_condition(); + OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT({ + ret = rcl_guard_condition_fini(&guard_cond); + EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; + }); ret = rcl_guard_condition_init( &guard_cond, this->context_ptr, rcl_guard_condition_get_default_options()); EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; @@ -201,13 +218,6 @@ TEST_F(CLASSNAME(WaitSetTestFixture, RMW_IMPLEMENTATION), zero_timeout_triggered ret = rcl_trigger_guard_condition(&guard_cond); EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; - OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT({ - rcl_ret_t ret = rcl_guard_condition_fini(&guard_cond); - EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; - ret = rcl_wait_set_fini(&wait_set); - EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; - }); - // Time spent during wait should be negligible. int64_t timeout = 0; std::chrono::steady_clock::time_point before_sc = std::chrono::steady_clock::now(); @@ -221,13 +231,21 @@ TEST_F(CLASSNAME(WaitSetTestFixture, RMW_IMPLEMENTATION), zero_timeout_triggered // Check that a canceled timer doesn't wake up rcl_wait TEST_F(CLASSNAME(WaitSetTestFixture, RMW_IMPLEMENTATION), canceled_timer) { + rcl_ret_t ret; rcl_wait_set_t wait_set = rcl_get_zero_initialized_wait_set(); - rcl_ret_t ret = - rcl_wait_set_init(&wait_set, 0, 1, 1, 0, 0, 0, context_ptr, rcl_get_default_allocator()); + OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT({ + ret = rcl_wait_set_fini(&wait_set); + EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; + }); + ret = rcl_wait_set_init(&wait_set, 0, 1, 1, 0, 0, 0, context_ptr, rcl_get_default_allocator()); EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; // Add a dummy guard condition to avoid an error rcl_guard_condition_t guard_cond = rcl_get_zero_initialized_guard_condition(); + OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT({ + ret = rcl_guard_condition_fini(&guard_cond); + EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; + }); ret = rcl_guard_condition_init( &guard_cond, this->context_ptr, rcl_guard_condition_get_default_options()); EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; @@ -240,6 +258,11 @@ TEST_F(CLASSNAME(WaitSetTestFixture, RMW_IMPLEMENTATION), canceled_timer) { ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; rcl_timer_t canceled_timer = rcl_get_zero_initialized_timer(); + OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT({ + ret = rcl_timer_fini(&canceled_timer); + EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; + }); + ret = rcl_timer_init( &canceled_timer, &clock, this->context_ptr, RCL_MS_TO_NS(1), nullptr, rcl_get_default_allocator()); @@ -249,15 +272,6 @@ TEST_F(CLASSNAME(WaitSetTestFixture, RMW_IMPLEMENTATION), canceled_timer) { ret = rcl_wait_set_add_timer(&wait_set, &canceled_timer, NULL); EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; - OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT({ - rcl_ret_t ret = rcl_guard_condition_fini(&guard_cond); - EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; - ret = rcl_wait_set_fini(&wait_set); - EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; - ret = rcl_timer_fini(&canceled_timer); - EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; - }); - int64_t timeout = RCL_MS_TO_NS(10); std::chrono::steady_clock::time_point before_sc = std::chrono::steady_clock::now(); ret = rcl_wait(&wait_set, timeout); @@ -274,9 +288,15 @@ TEST_F(CLASSNAME(WaitSetTestFixture, RMW_IMPLEMENTATION), canceled_timer) { // Test rcl_wait_set_t with excess capacity works. TEST_F(CLASSNAME(WaitSetTestFixture, RMW_IMPLEMENTATION), excess_capacity) { + rcl_ret_t ret; rcl_wait_set_t wait_set = rcl_get_zero_initialized_wait_set(); - rcl_ret_t ret = - rcl_wait_set_init(&wait_set, 42, 42, 42, 42, 42, 0, context_ptr, rcl_get_default_allocator()); + OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT({ + ret = rcl_wait_set_fini(&wait_set); + EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; + }); + ret = + rcl_wait_set_init(&wait_set, 42, 42, 42, 42, 42, 0, context_ptr,rcl_get_default_allocator ()); + EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; int64_t timeout = 1; @@ -350,16 +370,17 @@ TEST_F(CLASSNAME(WaitSetTestFixture, RMW_IMPLEMENTATION), multi_wait_set_threade // *INDENT-ON* // Setup each test set. for (auto & test_set : test_sets) { - rcl_ret_t ret; // init the wake count test_set.wake_count.store(0); // setup the guard condition test_set.guard_condition = rcl_get_zero_initialized_guard_condition(); + // guard_condition must live longer than this loop. Call fini from function-level exit-scope. ret = rcl_guard_condition_init( &test_set.guard_condition, this->context_ptr, rcl_guard_condition_get_default_options()); EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; // setup the wait set test_set.wait_set = rcl_get_zero_initialized_wait_set(); + // wait_set must live longer than this loop. Call fini from function-level exit-scope. ret = rcl_wait_set_init( &test_set.wait_set, 0, 1, 0, 0, 0, 0, context_ptr, rcl_get_default_allocator()); EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; @@ -370,7 +391,7 @@ TEST_F(CLASSNAME(WaitSetTestFixture, RMW_IMPLEMENTATION), multi_wait_set_threade // Setup safe tear-down. OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT({ for (auto & test_set : test_sets) { - rcl_ret_t ret = rcl_guard_condition_fini(&test_set.guard_condition); + ret = rcl_guard_condition_fini(&test_set.guard_condition); EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; ret = rcl_wait_set_fini(&test_set.wait_set); EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; @@ -417,24 +438,25 @@ TEST_F(CLASSNAME(WaitSetTestFixture, RMW_IMPLEMENTATION), multi_wait_set_threade // Check the interaction of a guard condition and a negative timeout by // triggering a guard condition in a separate thread TEST_F(CLASSNAME(WaitSetTestFixture, RMW_IMPLEMENTATION), guard_condition) { + rcl_ret_t ret; rcl_wait_set_t wait_set = rcl_get_zero_initialized_wait_set(); - rcl_ret_t ret = - rcl_wait_set_init(&wait_set, 0, 1, 0, 0, 0, 0, context_ptr, rcl_get_default_allocator()); + OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT({ + ret = rcl_wait_set_fini(&wait_set); + EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; + }); + ret = rcl_wait_set_init(&wait_set, 0, 1, 0, 0, 0, 0, context_ptr, rcl_get_default_allocator()); EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; rcl_guard_condition_t guard_cond = rcl_get_zero_initialized_guard_condition(); + OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT({ + ret = rcl_guard_condition_fini(&guard_cond); + EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; + }); ret = rcl_guard_condition_init( &guard_cond, this->context_ptr, rcl_guard_condition_get_default_options()); EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; ret = rcl_wait_set_add_guard_condition(&wait_set, &guard_cond, NULL); EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; - OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT({ - rcl_ret_t ret = rcl_wait_set_fini(&wait_set); - EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; - ret = rcl_guard_condition_fini(&guard_cond); - EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; - }); - std::promise p; int64_t timeout = -1; @@ -464,10 +486,17 @@ TEST_F(CLASSNAME(WaitSetTestFixture, RMW_IMPLEMENTATION), guard_condition) { // Check that index arguments are properly set when adding entities TEST_F(CLASSNAME(WaitSetTestFixture, RMW_IMPLEMENTATION), add_with_index) { + rcl_ret_t ret; const size_t kNumEntities = 3u; rcl_wait_set_t wait_set = rcl_get_zero_initialized_wait_set(); - rcl_ret_t ret = rcl_wait_set_init( + OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT({ + ret = rcl_wait_set_fini(&wait_set); + EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; + }); + + ret = rcl_wait_set_init( &wait_set, 0, kNumEntities, 0, 0, 0, 0, context_ptr, rcl_get_default_allocator()); + EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; // Initialize to invalid value @@ -476,6 +505,10 @@ TEST_F(CLASSNAME(WaitSetTestFixture, RMW_IMPLEMENTATION), add_with_index) { rcl_guard_condition_t guard_conditions[kNumEntities]; for (size_t i = 0u; i < kNumEntities; ++i) { guard_conditions[i] = rcl_get_zero_initialized_guard_condition(); + OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT({ + ret = rcl_guard_condition_fini(&guard_conditions[i]); + EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; + }); ret = rcl_guard_condition_init( &guard_conditions[i], this->context_ptr, rcl_guard_condition_get_default_options()); EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;