cpp/common/timer_test.cc
Go to the documentation of this file.
1 /*
2  *
3  * Copyright 2019 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
20 
21 #include <gtest/gtest.h>
22 
23 #include <grpc/grpc.h>
24 #include <grpc/support/log.h>
25 
32 
33 #ifdef GRPC_POSIX_SOCKET_EV
35 #endif
36 
37 // MAYBE_SKIP_TEST is a macro to determine if this particular test configuration
38 // should be skipped based on a decision made at SetUp time.
39 #define MAYBE_SKIP_TEST \
40  do { \
41  if (do_not_test_) { \
42  return; \
43  } \
44  } while (0)
45 
46 class TimerTest : public ::testing::Test {
47  protected:
48  void SetUp() override {
49  grpc_init();
50  // Skip test if slowdown factor > 1, or we are
51  // using event manager.
52 #ifdef GRPC_POSIX_SOCKET_EV
53  if (grpc_test_slowdown_factor() != 1 ||
55 #else
56  if (grpc_test_slowdown_factor() != 1) {
57 #endif
58  do_not_test_ = true;
59  }
60  }
61 
62  void TearDown() override { grpc_shutdown(); }
63 
64  bool do_not_test_{false};
65 };
66 
67 #ifndef GPR_WINDOWS
68 // the test fails with too many wakeups on windows opt build
69 // the mechanism by which that happens is described in
70 // https://github.com/grpc/grpc/issues/20436
71 TEST_F(TimerTest, NoTimers) {
75 
76  // We expect to get 1 wakeup per second. Sometimes we also get a wakeup
77  // during initialization, so in 1.5 seconds we expect to get 1 or 2 wakeups.
79  GPR_ASSERT(wakeups == 1 || wakeups == 2);
80 }
81 #endif
82 
83 TEST_F(TimerTest, OneTimerExpires) {
87  int timer_fired = 0;
89  &timer,
92  [](void* arg, grpc_error_handle) {
93  int* timer_fired = static_cast<int*>(arg);
94  ++*timer_fired;
95  },
96  &timer_fired, grpc_schedule_on_exec_ctx));
98  GPR_ASSERT(1 == timer_fired);
99 
100  // We expect to get 1 wakeup/second + 1 wakeup for the expired timer + maybe 1
101  // wakeup during initialization. i.e. in 1.5 seconds we expect 2 or 3 wakeups.
102  // Actual number of wakeups is more due to bug
103  // https://github.com/grpc/grpc/issues/19947
105  gpr_log(GPR_DEBUG, "wakeups: %" PRId64 "", wakeups);
106 }
107 
108 TEST_F(TimerTest, MultipleTimersExpire) {
111  const int kNumTimers = 10;
112  grpc_timer timers[kNumTimers];
113  int timer_fired = 0;
114  for (int i = 0; i < kNumTimers; ++i) {
115  grpc_timer_init(&timers[i],
120  [](void* arg, grpc_error_handle) {
121  int* timer_fired = static_cast<int*>(arg);
122  ++*timer_fired;
123  },
124  &timer_fired, grpc_schedule_on_exec_ctx));
125  }
126 
128  GPR_ASSERT(kNumTimers == timer_fired);
129 
130  // We expect to get 1 wakeup/second + 1 wakeup for per timer fired + maybe 1
131  // wakeup during initialization. i.e. in 1.5 seconds we expect 11 or 12
132  // wakeups. Actual number of wakeups is more due to bug
133  // https://github.com/grpc/grpc/issues/19947
135  gpr_log(GPR_DEBUG, "wakeups: %" PRId64 "", wakeups);
136 }
137 
138 TEST_F(TimerTest, CancelSomeTimers) {
141  const int kNumTimers = 10;
142  grpc_timer timers[kNumTimers];
143  int timer_fired = 0;
144  for (int i = 0; i < kNumTimers; ++i) {
145  grpc_timer_init(&timers[i],
150  [](void* arg, grpc_error_handle error) {
151  if (error == GRPC_ERROR_CANCELLED) {
152  return;
153  }
154  int* timer_fired = static_cast<int*>(arg);
155  ++*timer_fired;
156  },
157  &timer_fired, grpc_schedule_on_exec_ctx));
158  }
159  for (int i = 0; i < kNumTimers / 2; ++i) {
160  grpc_timer_cancel(&timers[i]);
161  }
162 
164  GPR_ASSERT(kNumTimers / 2 == timer_fired);
165 
166  // We expect to get 1 wakeup/second + 1 wakeup per timer fired + maybe 1
167  // wakeup during initialization. i.e. in 1.5 seconds we expect 6 or 7 wakeups.
168  // Actual number of wakeups is more due to bug
169  // https://github.com/grpc/grpc/issues/19947
171  gpr_log(GPR_DEBUG, "wakeups: %" PRId64 "", wakeups);
172 }
173 
174 // Enable the following test after
175 // https://github.com/grpc/grpc/issues/20049 has been fixed.
176 TEST_F(TimerTest, DISABLED_TimerNotCanceled) {
180  &timer,
182  GRPC_CLOSURE_CREATE([](void*, grpc_error_handle) {}, nullptr,
183  grpc_schedule_on_exec_ctx));
184 }
185 
186 // Enable the following test after
187 // https://github.com/grpc/grpc/issues/20064 has been fixed.
188 TEST_F(TimerTest, DISABLED_CancelRace) {
191  const int kNumTimers = 10;
192  grpc_timer timers[kNumTimers];
193  for (int i = 0; i < kNumTimers; ++i) {
194  grpc_timer* arg = (i != 0) ? &timers[i - 1] : nullptr;
195  grpc_timer_init(&timers[i],
199  [](void* arg, grpc_error_handle /*error*/) {
200  grpc_timer* timer = static_cast<grpc_timer*>(arg);
201  if (timer) {
203  }
204  },
205  arg, grpc_schedule_on_exec_ctx));
206  }
208 }
209 
210 // Enable the following test after
211 // https://github.com/grpc/grpc/issues/20066 has been fixed.
212 TEST_F(TimerTest, DISABLED_CancelNextTimer) {
215  const int kNumTimers = 10;
216  grpc_timer timers[kNumTimers];
217 
218  for (int i = 0; i < kNumTimers; ++i) {
219  grpc_timer_init_unset(&timers[i]);
220  }
221 
222  for (int i = 0; i < kNumTimers; ++i) {
223  grpc_timer* arg = nullptr;
224  if (i < kNumTimers - 1) {
225  arg = &timers[i + 1];
226  }
227  grpc_timer_init(&timers[i],
231  [](void* arg, grpc_error_handle /*error*/) {
232  grpc_timer* timer = static_cast<grpc_timer*>(arg);
233  if (timer) {
235  }
236  },
237  arg, grpc_schedule_on_exec_ctx));
238  }
239  grpc_timer_cancel(&timers[0]);
241 }
242 
243 int main(int argc, char** argv) {
244  grpc::testing::TestEnvironment env(&argc, argv);
245  ::testing::InitGoogleTest(&argc, argv);
246  return RUN_ALL_TESTS();
247 }
log.h
generate.env
env
Definition: generate.py:37
timer_manager.h
error
grpc_error_handle error
Definition: retry_filter.cc:499
closure.h
GRPC_CLOSURE_CREATE
#define GRPC_CLOSURE_CREATE(cb, cb_arg, scheduler)
Definition: closure.h:160
GRPC_ERROR_CANCELLED
#define GRPC_ERROR_CANCELLED
Definition: error.h:238
main
int main(int argc, char **argv)
Definition: cpp/common/timer_test.cc:243
grpc_timer
Definition: iomgr/timer.h:33
testing::Test
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:402
grpc_timer_init_unset
void grpc_timer_init_unset(grpc_timer *timer)
Definition: timer_generic.cc:330
GPR_ASSERT
#define GPR_ASSERT(x)
Definition: include/grpc/impl/codegen/log.h:94
TimerTest
Definition: cpp/common/timer_test.cc:46
int64_t
signed __int64 int64_t
Definition: stdint-msvc2008.h:89
ev_posix.h
grpc_timeout_milliseconds_to_deadline
gpr_timespec grpc_timeout_milliseconds_to_deadline(int64_t time_ms)
Definition: test/core/util/test_config.cc:89
gpr_log
GPRAPI void gpr_log(const char *file, int line, gpr_log_severity severity, const char *format,...) GPR_PRINT_FORMAT_CHECK(4
MAYBE_SKIP_TEST
#define MAYBE_SKIP_TEST
Definition: cpp/common/timer_test.cc:39
gpr_sleep_until
GPRAPI void gpr_sleep_until(gpr_timespec until)
grpc.h
grpc_test_slowdown_factor
int64_t grpc_test_slowdown_factor()
Definition: test/core/util/test_config.cc:76
arg
Definition: cmdline.cc:40
time.h
TEST_F
TEST_F(TimerTest, NoTimers)
Definition: cpp/common/timer_test.cc:71
TimerTest::TearDown
void TearDown() override
Definition: cpp/common/timer_test.cc:62
error.h
RUN_ALL_TESTS
int RUN_ALL_TESTS() GTEST_MUST_USE_RESULT_
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2471
grpc_core::ExecCtx
Definition: exec_ctx.h:97
TimerTest::do_not_test_
bool do_not_test_
Definition: cpp/common/timer_test.cc:64
test_config.h
grpc_event_engine_run_in_background
bool grpc_event_engine_run_in_background()
grpc_timer_cancel
void grpc_timer_cancel(grpc_timer *timer)
Definition: iomgr/timer.cc:36
grpc_core::Duration::Milliseconds
static constexpr Duration Milliseconds(int64_t millis)
Definition: src/core/lib/gprpp/time.h:155
absl::Now
ABSL_NAMESPACE_BEGIN Time Now()
Definition: abseil-cpp/absl/time/clock.cc:39
testing::InitGoogleTest
GTEST_API_ void InitGoogleTest(int *argc, char **argv)
Definition: bloaty/third_party/googletest/googletest/src/gtest.cc:6106
TimerTest::SetUp
void SetUp() override
Definition: cpp/common/timer_test.cc:48
exec_ctx
grpc_core::ExecCtx exec_ctx
Definition: end2end_binder_transport_test.cc:75
grpc::testing::TestEnvironment
Definition: test/core/util/test_config.h:54
grpc_core::Duration::Seconds
static constexpr Duration Seconds(int64_t seconds)
Definition: src/core/lib/gprpp/time.h:151
arg
struct arg arg
exec_ctx.h
grpc_timer_init
void grpc_timer_init(grpc_timer *timer, grpc_core::Timestamp deadline, grpc_closure *closure)
Definition: iomgr/timer.cc:31
timer.h
GPR_DEBUG
#define GPR_DEBUG
Definition: include/grpc/impl/codegen/log.h:55
grpc_init
GRPCAPI void grpc_init(void)
Definition: init.cc:146
grpc_error
Definition: error_internal.h:42
grpc_shutdown
GRPCAPI void grpc_shutdown(void)
Definition: init.cc:209
grpc_core::ExecCtx::Get
static ExecCtx * Get()
Definition: exec_ctx.h:205
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
grpc_timer_manager_get_wakeups_testonly
uint64_t grpc_timer_manager_get_wakeups_testonly(void)
Definition: iomgr/timer_manager.cc:364
timer
static uv_timer_t timer
Definition: test-callback-stack.c:34


grpc
Author(s):
autogenerated on Thu Mar 13 2025 03:01:39