Skip to content

Commit

Permalink
Fix leaks in test_wait.cpp
Browse files Browse the repository at this point in the history
  • Loading branch information
cevans87 committed May 16, 2019
1 parent 4e0b33f commit 1cdc4a0
Showing 1 changed file with 100 additions and 67 deletions.
167 changes: 100 additions & 67 deletions rcl/test/rcl/test_wait.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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
Expand All @@ -100,20 +106,26 @@ TEST_F(CLASSNAME(WaitSetTestFixture, RMW_IMPLEMENTATION), finite_timeout) {
// Check time
int64_t diff = std::chrono::duration_cast<std::chrono::nanoseconds>(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;
Expand All @@ -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);
Expand All @@ -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();
Expand All @@ -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;
Expand All @@ -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();
Expand All @@ -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;
Expand All @@ -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());
Expand All @@ -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);
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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<rcl_ret_t> p;

int64_t timeout = -1;
Expand Down Expand Up @@ -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
Expand All @@ -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;
Expand Down

0 comments on commit 1cdc4a0

Please sign in to comment.