From 21baed999e31c5e69c75f0cbb8757ef91585d917 Mon Sep 17 00:00:00 2001 From: Casey Bodley Date: Mon, 19 Jul 2021 18:07:47 -0400 Subject: [PATCH] test/rgw: fix use of poll() with timers in unittest_rgw_dmclock_scheduler the AsyncScheduler uses an asio timer to dispatch work to its executor with an optional delay. when no delay is requested, it waits on the timer with an expiration time in the past (crimson::dmclock::TimeZero) tests are failing here because poll() is returning without executing the handlers of those expired timers asio implements these timers with timerfd and epoll. debugging with strace, i see that these timers armed with timerfd_settime() are not always immediately ready according to epoll_wait(): eventfd2(0, EFD_CLOEXEC|EFD_NONBLOCK) = 3 epoll_create1(EPOLL_CLOEXEC) = 4 timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC) = 5 epoll_ctl(4, EPOLL_CTL_ADD, 3, {events=EPOLLIN|EPOLLERR|EPOLLET, data={u32=14164052, u64=14164052}}) = 0 epoll_ctl(4, EPOLL_CTL_ADD, 5, {events=EPOLLIN|EPOLLERR, data={u32=14164064, u64=14164064}}) = 0 timerfd_settime(5, TFD_TIMER_ABSTIME, {it_interval={tv_sec=0, tv_nsec=0}, it_value={tv_sec=0, tv_nsec=1}}, {it_interval={tv_sec=0, tv_nsec=0}, it_value={tv_sec=0, tv_nsec=0}}) = 0 epoll_wait(4, [{events=EPOLLIN, data={u32=14164052, u64=14164052}}], 128, 0) = 1 epoll_wait(4, [], 128, 0) = 0 epoll_wait(4, [], 128, 0) = 0 epoll_wait(4, [], 128, 0) = 0 epoll_wait(4, [], 128, 0) = 0 epoll_wait(4, [{events=EPOLLIN, data={u32=14164064, u64=14164064}}], 128, 0) = 1 in this example, it took 6 calls to context.poll() before it was ready to execute the timer's handler to work around this, replace calls to context.poll() with calls to context.run_for() with a very short duration Fixes: https://tracker.ceph.com/issues/42788 Signed-off-by: Casey Bodley --- src/test/rgw/test_rgw_dmclock_scheduler.cc | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/test/rgw/test_rgw_dmclock_scheduler.cc b/src/test/rgw/test_rgw_dmclock_scheduler.cc index d13c4fca69e58..84d411b3d3a02 100644 --- a/src/test/rgw/test_rgw_dmclock_scheduler.cc +++ b/src/test/rgw/test_rgw_dmclock_scheduler.cc @@ -105,7 +105,7 @@ TEST(Queue, RateLimit) EXPECT_EQ(1u, counters(client_id::admin)->get(queue_counters::l_qlen)); EXPECT_EQ(1u, counters(client_id::auth)->get(queue_counters::l_qlen)); - context.poll(); + context.run_for(std::chrono::milliseconds(1)); EXPECT_TRUE(context.stopped()); ASSERT_TRUE(ec1); @@ -163,7 +163,7 @@ TEST(Queue, AsyncRequest) EXPECT_EQ(1u, counters(client_id::admin)->get(queue_counters::l_qlen)); EXPECT_EQ(1u, counters(client_id::auth)->get(queue_counters::l_qlen)); - context.poll(); + context.run_for(std::chrono::milliseconds(1)); EXPECT_TRUE(context.stopped()); ASSERT_TRUE(ec1); @@ -217,7 +217,7 @@ TEST(Queue, Cancel) EXPECT_FALSE(ec1); EXPECT_FALSE(ec2); - context.poll(); + context.run_for(std::chrono::milliseconds(1)); EXPECT_TRUE(context.stopped()); ASSERT_TRUE(ec1); @@ -265,7 +265,7 @@ TEST(Queue, CancelClient) EXPECT_FALSE(ec1); EXPECT_FALSE(ec2); - context.poll(); + context.run_for(std::chrono::milliseconds(1)); EXPECT_TRUE(context.stopped()); ASSERT_TRUE(ec1); @@ -315,7 +315,7 @@ TEST(Queue, CancelOnDestructor) EXPECT_FALSE(ec1); EXPECT_FALSE(ec2); - context.poll(); + context.run_for(std::chrono::milliseconds(1)); EXPECT_TRUE(context.stopped()); ASSERT_TRUE(ec1); @@ -369,20 +369,20 @@ TEST(Queue, CrossExecutorRequest) EXPECT_EQ(1u, counters(client_id::admin)->get(queue_counters::l_qlen)); EXPECT_EQ(1u, counters(client_id::auth)->get(queue_counters::l_qlen)); - callback_context.poll(); + callback_context.run_for(std::chrono::milliseconds(1)); // maintains work on callback executor while in queue EXPECT_FALSE(callback_context.stopped()); EXPECT_FALSE(ec1); EXPECT_FALSE(ec2); - queue_context.poll(); + queue_context.run_for(std::chrono::milliseconds(1)); EXPECT_TRUE(queue_context.stopped()); EXPECT_FALSE(ec1); // no callbacks until callback executor runs EXPECT_FALSE(ec2); - callback_context.poll(); + callback_context.run_for(std::chrono::milliseconds(1)); EXPECT_TRUE(callback_context.stopped()); ASSERT_TRUE(ec1); @@ -421,7 +421,7 @@ TEST(Queue, SpawnAsyncRequest) EXPECT_EQ(PhaseType::priority, p2); }); - context.poll(); + context.run_for(std::chrono::milliseconds(1)); EXPECT_TRUE(context.stopped()); } -- 2.39.5