alarm_test.cc
Go to the documentation of this file.
1 /*
2  *
3  * Copyright 2015 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 
19 #include <condition_variable>
20 #include <memory>
21 #include <mutex>
22 #include <thread>
23 
24 #include <gtest/gtest.h>
25 
26 #include <grpcpp/alarm.h>
28 
30 
31 namespace grpc {
32 namespace {
33 
34 TEST(AlarmTest, RegularExpiry) {
35  CompletionQueue cq;
36  void* junk = reinterpret_cast<void*>(1618033);
37  Alarm alarm;
38  alarm.Set(&cq, grpc_timeout_seconds_to_deadline(1), junk);
39 
40  void* output_tag;
41  bool ok;
43  cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(10));
44 
46  EXPECT_TRUE(ok);
47  EXPECT_EQ(junk, output_tag);
48 }
49 
50 TEST(AlarmTest, RegularExpiryMultiSet) {
51  CompletionQueue cq;
52  void* junk = reinterpret_cast<void*>(1618033);
53  Alarm alarm;
54 
55  for (int i = 0; i < 3; i++) {
56  alarm.Set(&cq, grpc_timeout_seconds_to_deadline(1), junk);
57 
58  void* output_tag;
59  bool ok;
61  cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(10));
62 
64  EXPECT_TRUE(ok);
65  EXPECT_EQ(junk, output_tag);
66  }
67 }
68 
69 TEST(AlarmTest, RegularExpiryMultiSetMultiCQ) {
70  void* junk = reinterpret_cast<void*>(1618033);
71  Alarm alarm;
72 
73  for (int i = 0; i < 3; i++) {
74  CompletionQueue cq;
75  alarm.Set(&cq, grpc_timeout_seconds_to_deadline(1), junk);
76 
77  void* output_tag;
78  bool ok;
80  cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(10));
81 
83  EXPECT_TRUE(ok);
84  EXPECT_EQ(junk, output_tag);
85  }
86 }
87 
88 struct Completion {
89  bool completed = false;
90  std::mutex mu;
91  std::condition_variable cv;
92 };
93 
94 TEST(AlarmTest, CallbackRegularExpiry) {
95  Alarm alarm;
96 
97  auto c = std::make_shared<Completion>();
99  [c](bool ok) {
100  EXPECT_TRUE(ok);
101  std::lock_guard<std::mutex> l(c->mu);
102  c->completed = true;
103  c->cv.notify_one();
104  });
105 
106  std::unique_lock<std::mutex> l(c->mu);
107  EXPECT_TRUE(c->cv.wait_until(
109  [c] { return c->completed; }));
110 }
111 
112 TEST(AlarmTest, CallbackZeroExpiry) {
113  Alarm alarm;
114 
115  auto c = std::make_shared<Completion>();
116  alarm.Set(grpc_timeout_seconds_to_deadline(0), [c](bool ok) {
117  EXPECT_TRUE(ok);
118  std::lock_guard<std::mutex> l(c->mu);
119  c->completed = true;
120  c->cv.notify_one();
121  });
122 
123  std::unique_lock<std::mutex> l(c->mu);
124  EXPECT_TRUE(c->cv.wait_until(
126  [c] { return c->completed; }));
127 }
128 
129 TEST(AlarmTest, CallbackNegativeExpiry) {
130  Alarm alarm;
131 
132  auto c = std::make_shared<Completion>();
134  [c](bool ok) {
135  EXPECT_TRUE(ok);
136  std::lock_guard<std::mutex> l(c->mu);
137  c->completed = true;
138  c->cv.notify_one();
139  });
140 
141  std::unique_lock<std::mutex> l(c->mu);
142  EXPECT_TRUE(c->cv.wait_until(
144  [c] { return c->completed; }));
145 }
146 
147 TEST(AlarmTest, MultithreadedRegularExpiry) {
148  CompletionQueue cq;
149  void* junk = reinterpret_cast<void*>(1618033);
150  void* output_tag;
151  bool ok;
153  Alarm alarm;
154 
155  std::thread t1([&alarm, &cq, &junk] {
156  alarm.Set(&cq, grpc_timeout_seconds_to_deadline(1), junk);
157  });
158 
159  std::thread t2([&cq, &ok, &output_tag, &status] {
160  status =
161  cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(10));
162  });
163 
164  t1.join();
165  t2.join();
167  EXPECT_TRUE(ok);
168  EXPECT_EQ(junk, output_tag);
169 }
170 
171 TEST(AlarmTest, DeprecatedRegularExpiry) {
172  CompletionQueue cq;
173  void* junk = reinterpret_cast<void*>(1618033);
174  Alarm alarm(&cq, grpc_timeout_seconds_to_deadline(1), junk);
175 
176  void* output_tag;
177  bool ok;
179  cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(10));
180 
182  EXPECT_TRUE(ok);
183  EXPECT_EQ(junk, output_tag);
184 }
185 
186 TEST(AlarmTest, MoveConstructor) {
187  CompletionQueue cq;
188  void* junk = reinterpret_cast<void*>(1618033);
189  Alarm first;
190  first.Set(&cq, grpc_timeout_seconds_to_deadline(1), junk);
191  Alarm second(std::move(first));
192  void* output_tag;
193  bool ok;
195  cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(10));
197  EXPECT_TRUE(ok);
198  EXPECT_EQ(junk, output_tag);
199 }
200 
201 TEST(AlarmTest, MoveAssignment) {
202  CompletionQueue cq;
203  void* junk = reinterpret_cast<void*>(1618033);
204  Alarm first;
205  first.Set(&cq, grpc_timeout_seconds_to_deadline(1), junk);
206  Alarm second(std::move(first));
208 
209  void* output_tag;
210  bool ok;
212  cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(10));
213 
215  EXPECT_TRUE(ok);
216  EXPECT_EQ(junk, output_tag);
217 }
218 
219 TEST(AlarmTest, RegularExpiryChrono) {
220  CompletionQueue cq;
221  void* junk = reinterpret_cast<void*>(1618033);
222  std::chrono::system_clock::time_point one_sec_deadline =
224  Alarm alarm;
225  alarm.Set(&cq, one_sec_deadline, junk);
226 
227  void* output_tag;
228  bool ok;
230  cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(10));
231 
233  EXPECT_TRUE(ok);
234  EXPECT_EQ(junk, output_tag);
235 }
236 
237 TEST(AlarmTest, ZeroExpiry) {
238  CompletionQueue cq;
239  void* junk = reinterpret_cast<void*>(1618033);
240  Alarm alarm;
241  alarm.Set(&cq, grpc_timeout_seconds_to_deadline(0), junk);
242 
243  void* output_tag;
244  bool ok;
246  cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(1));
247 
249  EXPECT_TRUE(ok);
250  EXPECT_EQ(junk, output_tag);
251 }
252 
253 TEST(AlarmTest, NegativeExpiry) {
254  CompletionQueue cq;
255  void* junk = reinterpret_cast<void*>(1618033);
256  Alarm alarm;
257  alarm.Set(&cq, grpc_timeout_seconds_to_deadline(-1), junk);
258 
259  void* output_tag;
260  bool ok;
262  cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(1));
263 
265  EXPECT_TRUE(ok);
266  EXPECT_EQ(junk, output_tag);
267 }
268 
269 TEST(AlarmTest, Cancellation) {
270  CompletionQueue cq;
271  void* junk = reinterpret_cast<void*>(1618033);
272  Alarm alarm;
273  alarm.Set(&cq, grpc_timeout_seconds_to_deadline(10), junk);
274  alarm.Cancel();
275 
276  void* output_tag;
277  bool ok;
279  cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(1));
280 
282  EXPECT_FALSE(ok);
283  EXPECT_EQ(junk, output_tag);
284 }
285 
286 TEST(AlarmTest, CallbackCancellation) {
287  Alarm alarm;
288 
289  auto c = std::make_shared<Completion>();
291  [c](bool ok) {
292  EXPECT_FALSE(ok);
293  std::lock_guard<std::mutex> l(c->mu);
294  c->completed = true;
295  c->cv.notify_one();
296  });
297  alarm.Cancel();
298 
299  std::unique_lock<std::mutex> l(c->mu);
300  EXPECT_TRUE(c->cv.wait_until(
302  [c] { return c->completed; }));
303 }
304 
305 TEST(AlarmTest, CallbackCancellationLocked) {
306  Alarm alarm;
307 
308  auto c = std::make_shared<Completion>();
310  [c](bool ok) {
311  EXPECT_FALSE(ok);
312  std::lock_guard<std::mutex> l(c->mu);
313  c->completed = true;
314  c->cv.notify_one();
315  });
316  std::unique_lock<std::mutex> l(c->mu);
317  alarm.Cancel();
318 
319  EXPECT_TRUE(c->cv.wait_until(
321  [c] { return c->completed; }));
322 }
323 
324 TEST(AlarmTest, SetDestruction) {
325  CompletionQueue cq;
326  void* junk = reinterpret_cast<void*>(1618033);
327  {
328  Alarm alarm;
329  alarm.Set(&cq, grpc_timeout_seconds_to_deadline(10), junk);
330  }
331 
332  void* output_tag;
333  bool ok;
335  cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(1));
336 
338  EXPECT_FALSE(ok);
339  EXPECT_EQ(junk, output_tag);
340 }
341 
342 TEST(AlarmTest, CallbackSetDestruction) {
343  auto c = std::make_shared<Completion>();
344  {
345  Alarm alarm;
347  [c](bool ok) {
348  EXPECT_FALSE(ok);
349  std::lock_guard<std::mutex> l(c->mu);
350  c->completed = true;
351  c->cv.notify_one();
352  });
353  }
354 
355  std::unique_lock<std::mutex> l(c->mu);
356  EXPECT_TRUE(c->cv.wait_until(
358  [c] { return c->completed; }));
359 }
360 
361 TEST(AlarmTest, UnsetDestruction) {
362  CompletionQueue cq;
363  Alarm alarm;
364 }
365 
366 } // namespace
367 } // namespace grpc
368 
369 int main(int argc, char** argv) {
370  grpc::testing::TestEnvironment env(&argc, argv);
371  ::testing::InitGoogleTest(&argc, argv);
372  return RUN_ALL_TESTS();
373 }
EXPECT_FALSE
#define EXPECT_FALSE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1970
absl::time_internal::cctz::seconds
std::chrono::duration< std::int_fast64_t > seconds
Definition: abseil-cpp/absl/time/internal/cctz/include/cctz/time_zone.h:40
grpc::status
auto status
Definition: cpp/client/credentials_test.cc:200
now
static double now(void)
Definition: test/core/fling/client.cc:130
grpc_timeout_seconds_to_deadline
gpr_timespec grpc_timeout_seconds_to_deadline(int64_t time_s)
Definition: test/core/util/test_config.cc:81
generate.env
env
Definition: generate.py:37
grpc
Definition: grpcpp/alarm.h:33
fix_build_deps.c
list c
Definition: fix_build_deps.py:490
grpc::CompletionQueue::GOT_EVENT
@ GOT_EVENT
Definition: include/grpcpp/impl/codegen/completion_queue.h:126
mutex
static uv_mutex_t mutex
Definition: threadpool.c:34
absl::time_internal::cctz::time_point
std::chrono::time_point< std::chrono::system_clock, D > time_point
Definition: abseil-cpp/absl/time/internal/cctz/include/cctz/time_zone.h:39
grpc::CompletionQueue::NextStatus
NextStatus
Tri-state return for AsyncNext: SHUTDOWN, GOT_EVENT, TIMEOUT.
Definition: include/grpcpp/impl/codegen/completion_queue.h:124
alarm.h
grpc::EXPECT_TRUE
EXPECT_TRUE(status.ok())
second
StrT second
Definition: cxa_demangle.cpp:4885
main
int main(int argc, char **argv)
Definition: alarm_test.cc:369
absl::move
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
Definition: abseil-cpp/absl/utility/utility.h:221
mu
Mutex mu
Definition: server_config_selector_filter.cc:74
completion_queue.h
RUN_ALL_TESTS
int RUN_ALL_TESTS() GTEST_MUST_USE_RESULT_
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2471
test_config.h
testing::InitGoogleTest
GTEST_API_ void InitGoogleTest(int *argc, char **argv)
Definition: bloaty/third_party/googletest/googletest/src/gtest.cc:6106
cv
unsigned cv
Definition: cxa_demangle.cpp:4908
grpc::TEST
TEST(CredentialsTest, StsCredentialsOptionsFromEnv)
Definition: cpp/client/credentials_test.cc:229
first
StrT first
Definition: cxa_demangle.cpp:4884
grpc::testing::TestEnvironment
Definition: test/core/util/test_config.h:54
ok
bool ok
Definition: async_end2end_test.cc:197
grpc::EXPECT_EQ
EXPECT_EQ(grpc::StatusCode::INVALID_ARGUMENT, status.error_code())
run_grpclb_interop_tests.l
dictionary l
Definition: run_grpclb_interop_tests.py:410
t1
Table t1
Definition: abseil-cpp/absl/container/internal/raw_hash_set_allocator_test.cc:185
thread
static uv_thread_t thread
Definition: test-async-null-cb.c:29
cq
static grpc_completion_queue * cq
Definition: test/core/fling/client.cc:37
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230


grpc
Author(s):
autogenerated on Fri May 16 2025 02:57:40