diff --git a/rcl/test/rcl/test_timer.cpp b/rcl/test/rcl/test_timer.cpp index ae3984bed..8d0757875 100644 --- a/rcl/test/rcl/test_timer.cpp +++ b/rcl/test/rcl/test_timer.cpp @@ -246,14 +246,24 @@ TEST_F(TestTimerFixture, test_two_timers) { ret = rcl_wait_set_fini(&wait_set); EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; }); - ret = rcl_wait(&wait_set, RCL_MS_TO_NS(100)); - EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; + // The loop is needed because the rcl_wait_set might suffer spurious + // awakes when timers are involved. + // The loop can be removed if spurious awakes are fixed in the future. + // This issue particularly happens on Windows. uint8_t nonnull_timers = 0; - for (uint8_t i = 0; i < wait_set.size_of_timers; i++) { - if (wait_set.timers[i] != NULL) { - nonnull_timers++; + auto start = std::chrono::system_clock::now(); + do { + ret = rcl_wait(&wait_set, RCL_MS_TO_NS(100)); + EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; + for (uint8_t i = 0; i < wait_set.size_of_timers; i++) { + if (wait_set.timers[i] != NULL) { + nonnull_timers++; + } } - } + } while ( + nonnull_timers == 0u || + std::chrono::duration_cast( + std::chrono::system_clock::now() - start).count() > 100u); bool is_ready = false; ret = rcl_timer_is_ready(&timer, &is_ready); EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; @@ -304,14 +314,24 @@ TEST_F(TestTimerFixture, test_two_timers_ready_before_timeout) { ret = rcl_wait_set_fini(&wait_set); EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; }); - ret = rcl_wait(&wait_set, RCL_MS_TO_NS(100)); - EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; - uint8_t nonnull_timers = 0; - for (uint8_t i = 0; i < wait_set.size_of_timers; i++) { - if (wait_set.timers[i] != NULL) { - nonnull_timers++; + // The loop is needed because the rcl_wait_set might suffer spurious + // awakes when timers are involved. + // The loop can be removed if spurious awakes are fixed in the future. + // This issue particularly happens on Windows. + uint8_t nonnull_timers = 0u; + auto start = std::chrono::system_clock::now(); + do { + ret = rcl_wait(&wait_set, RCL_MS_TO_NS(100)); + EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; + for (uint8_t i = 0; i < wait_set.size_of_timers; i++) { + if (wait_set.timers[i] != NULL) { + nonnull_timers++; + } } - } + } while ( + nonnull_timers == 0u || + std::chrono::duration_cast( + std::chrono::system_clock::now() - start).count() > 100u); bool is_ready = false; ret = rcl_timer_is_ready(&timer, &is_ready); EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;