From 4dfa808e75fbf0fd94a9787c596bedaabb684215 Mon Sep 17 00:00:00 2001 From: Prashant Jaikumar Date: Fri, 23 Aug 2019 17:12:41 -0700 Subject: [PATCH] Add test for timer expiry racing with cancelation --- test/cpp/common/timer_test.cc | 71 +++++++++++++++++++++++++++++------ 1 file changed, 60 insertions(+), 11 deletions(-) diff --git a/test/cpp/common/timer_test.cc b/test/cpp/common/timer_test.cc index 9b23be2885a..1abed1660e8 100644 --- a/test/cpp/common/timer_test.cc +++ b/test/cpp/common/timer_test.cc @@ -77,7 +77,7 @@ TEST_F(TimerTest, OneTimerExpires) { grpc_core::ExecCtx exec_ctx; grpc_timer timer; int timer_fired = 0; - grpc_timer_init(&timer, 500, + grpc_timer_init(&timer, grpc_core::ExecCtx::Get()->Now() + 500, GRPC_CLOSURE_CREATE( [](void* arg, grpc_error*) { int* timer_fired = static_cast(arg); @@ -102,7 +102,7 @@ TEST_F(TimerTest, MultipleTimersExpire) { grpc_timer timers[kNumTimers]; int timer_fired = 0; for (int i = 0; i < kNumTimers; ++i) { - grpc_timer_init(&timers[i], 500 + i, + grpc_timer_init(&timers[i], grpc_core::ExecCtx::Get()->Now() + 500 + i, GRPC_CLOSURE_CREATE( [](void* arg, grpc_error*) { int* timer_fired = static_cast(arg); @@ -129,7 +129,7 @@ TEST_F(TimerTest, CancelSomeTimers) { grpc_timer timers[kNumTimers]; int timer_fired = 0; for (int i = 0; i < kNumTimers; ++i) { - grpc_timer_init(&timers[i], 500 + i, + grpc_timer_init(&timers[i], grpc_core::ExecCtx::Get()->Now() + 500 + i, GRPC_CLOSURE_CREATE( [](void* arg, grpc_error* error) { if (error == GRPC_ERROR_CANCELLED) { @@ -157,17 +157,66 @@ TEST_F(TimerTest, CancelSomeTimers) { // Enable the following test after // https://github.com/grpc/grpc/issues/20049 has been fixed. -#if 0 -TEST_F(TimerTest, TimerNotCanceled) { +TEST_F(TimerTest, DISABLED_TimerNotCanceled) { grpc_core::ExecCtx exec_ctx; grpc_timer timer; - grpc_timer_init(&timer, 10000, - GRPC_CLOSURE_CREATE( - [](void*, grpc_error*) { - }, - nullptr, grpc_schedule_on_exec_ctx)); + grpc_timer_init(&timer, grpc_core::ExecCtx::Get()->Now() + 10000, + GRPC_CLOSURE_CREATE([](void*, grpc_error*) {}, nullptr, + grpc_schedule_on_exec_ctx)); +} + +// Enable the following test after +// https://github.com/grpc/grpc/issues/20064 has been fixed. +TEST_F(TimerTest, DISABLED_CancelRace) { + MAYBE_SKIP_TEST; + grpc_core::ExecCtx exec_ctx; + const int kNumTimers = 10; + grpc_timer timers[kNumTimers]; + for (int i = 0; i < kNumTimers; ++i) { + grpc_timer* arg = (i != 0) ? &timers[i - 1] : nullptr; + grpc_timer_init(&timers[i], grpc_core::ExecCtx::Get()->Now() + 100, + GRPC_CLOSURE_CREATE( + [](void* arg, grpc_error* error) { + grpc_timer* timer = static_cast(arg); + if (timer) { + grpc_timer_cancel(timer); + } + }, + arg, grpc_schedule_on_exec_ctx)); + } + gpr_sleep_until(grpc_timeout_milliseconds_to_deadline(100)); +} + +// Enable the following test after +// https://github.com/grpc/grpc/issues/20066 has been fixed. +TEST_F(TimerTest, DISABLED_CancelNextTimer) { + MAYBE_SKIP_TEST; + grpc_core::ExecCtx exec_ctx; + const int kNumTimers = 10; + grpc_timer timers[kNumTimers]; + + for (int i = 0; i < kNumTimers; ++i) { + grpc_timer_init_unset(&timers[i]); + } + + for (int i = 0; i < kNumTimers; ++i) { + grpc_timer* arg = nullptr; + if (i < kNumTimers - 1) { + arg = &timers[i + 1]; + } + grpc_timer_init(&timers[i], grpc_core::ExecCtx::Get()->Now() + 100, + GRPC_CLOSURE_CREATE( + [](void* arg, grpc_error* error) { + grpc_timer* timer = static_cast(arg); + if (timer) { + grpc_timer_cancel(timer); + } + }, + arg, grpc_schedule_on_exec_ctx)); + } + grpc_timer_cancel(&timers[0]); + gpr_sleep_until(grpc_timeout_milliseconds_to_deadline(100)); } -#endif int main(int argc, char** argv) { grpc::testing::TestEnvironment env(argc, argv);