Skip to content

Commit ffcfda1

Browse files
authored
Improve wait sets test coverage. (#683)
Signed-off-by: Michel Hidalgo <[email protected]>
1 parent ba25806 commit ffcfda1

File tree

1 file changed

+68
-0
lines changed

1 file changed

+68
-0
lines changed

rcl/test/rcl/test_wait.cpp

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,20 @@
2929

3030
#include "rcutils/logging_macros.h"
3131

32+
#include "./allocator_testing_utils.h"
33+
3234
#ifdef RMW_IMPLEMENTATION
3335
# define CLASSNAME_(NAME, SUFFIX) NAME ## __ ## SUFFIX
3436
# define CLASSNAME(NAME, SUFFIX) CLASSNAME_(NAME, SUFFIX)
3537
#else
3638
# define CLASSNAME(NAME, SUFFIX) NAME
3739
#endif
3840

41+
#ifndef _WIN32
3942
#define TOLERANCE RCL_MS_TO_NS(6)
43+
#else
44+
#define TOLERANCE RCL_MS_TO_NS(15)
45+
#endif
4046

4147
class CLASSNAME (WaitSetTestFixture, RMW_IMPLEMENTATION) : public ::testing::Test
4248
{
@@ -86,6 +92,25 @@ TEST_F(CLASSNAME(WaitSetTestFixture, RMW_IMPLEMENTATION), wait_set_is_valid) {
8692
EXPECT_FALSE(rcl_wait_set_is_valid(&wait_set));
8793
}
8894

95+
TEST_F(CLASSNAME(WaitSetTestFixture, RMW_IMPLEMENTATION), test_failed_resize) {
96+
// Initialize a wait set with a subscription and then resize it to zero.
97+
rcl_allocator_t allocator = get_failing_allocator();
98+
rcl_wait_set_t wait_set = rcl_get_zero_initialized_wait_set();
99+
set_failing_allocator_is_failing(allocator, false);
100+
rcl_ret_t ret =
101+
rcl_wait_set_init(&wait_set, 1, 1, 1, 1, 1, 0, context_ptr, allocator);
102+
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
103+
104+
set_failing_allocator_is_failing(allocator, true);
105+
ret = rcl_wait_set_resize(&wait_set, 0, 1, 0, 0, 0, 0);
106+
EXPECT_EQ(RCL_RET_BAD_ALLOC, ret);
107+
rcl_reset_error();
108+
109+
set_failing_allocator_is_failing(allocator, false);
110+
ret = rcl_wait_set_fini(&wait_set);
111+
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
112+
}
113+
89114
TEST_F(CLASSNAME(WaitSetTestFixture, RMW_IMPLEMENTATION), test_resize_to_zero) {
90115
// Initialize a wait set with a subscription and then resize it to zero.
91116
rcl_wait_set_t wait_set = rcl_get_zero_initialized_wait_set();
@@ -257,6 +282,49 @@ TEST_F(CLASSNAME(WaitSetTestFixture, RMW_IMPLEMENTATION), zero_timeout_triggered
257282
EXPECT_LE(diff, TOLERANCE);
258283
}
259284

285+
// Test rcl_wait with a timeout value and an overrun timer
286+
TEST_F(CLASSNAME(WaitSetTestFixture, RMW_IMPLEMENTATION), zero_timeout_overrun_timer) {
287+
rcl_wait_set_t wait_set = rcl_get_zero_initialized_wait_set();
288+
rcl_ret_t ret =
289+
rcl_wait_set_init(&wait_set, 0, 0, 1, 0, 0, 0, context_ptr, rcl_get_default_allocator());
290+
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
291+
OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT(
292+
{
293+
ret = rcl_wait_set_fini(&wait_set);
294+
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
295+
});
296+
rcl_clock_t clock;
297+
rcl_allocator_t allocator = rcl_get_default_allocator();
298+
ret = rcl_clock_init(RCL_STEADY_TIME, &clock, &allocator);
299+
OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT(
300+
{
301+
ret = rcl_clock_fini(&clock);
302+
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
303+
});
304+
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
305+
306+
rcl_timer_t timer = rcl_get_zero_initialized_timer();
307+
ret = rcl_timer_init(
308+
&timer, &clock, this->context_ptr, 0, nullptr, rcl_get_default_allocator());
309+
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
310+
OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT(
311+
{
312+
ret = rcl_timer_fini(&timer);
313+
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
314+
});
315+
ret = rcl_wait_set_add_timer(&wait_set, &timer, NULL);
316+
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
317+
318+
// Time spent during wait should be negligible, definitely less than the given timeout
319+
std::chrono::steady_clock::time_point before_sc = std::chrono::steady_clock::now();
320+
ret = rcl_wait(&wait_set, RCL_MS_TO_NS(100));
321+
std::chrono::steady_clock::time_point after_sc = std::chrono::steady_clock::now();
322+
// We don't expect a timeout here (since the guard condition had already been triggered)
323+
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
324+
int64_t diff = std::chrono::duration_cast<std::chrono::nanoseconds>(after_sc - before_sc).count();
325+
EXPECT_LE(diff, RCL_MS_TO_NS(50));
326+
}
327+
260328
// Check that a canceled timer doesn't wake up rcl_wait
261329
TEST_F(CLASSNAME(WaitSetTestFixture, RMW_IMPLEMENTATION), canceled_timer) {
262330
rcl_wait_set_t wait_set = rcl_get_zero_initialized_wait_set();

0 commit comments

Comments
 (0)