1*cc02d7e2SAndroid Build Coastguard Worker //
2*cc02d7e2SAndroid Build Coastguard Worker //
3*cc02d7e2SAndroid Build Coastguard Worker // Copyright 2015 gRPC authors.
4*cc02d7e2SAndroid Build Coastguard Worker //
5*cc02d7e2SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
6*cc02d7e2SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
7*cc02d7e2SAndroid Build Coastguard Worker // You may obtain a copy of the License at
8*cc02d7e2SAndroid Build Coastguard Worker //
9*cc02d7e2SAndroid Build Coastguard Worker // http://www.apache.org/licenses/LICENSE-2.0
10*cc02d7e2SAndroid Build Coastguard Worker //
11*cc02d7e2SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
12*cc02d7e2SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
13*cc02d7e2SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*cc02d7e2SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
15*cc02d7e2SAndroid Build Coastguard Worker // limitations under the License.
16*cc02d7e2SAndroid Build Coastguard Worker //
17*cc02d7e2SAndroid Build Coastguard Worker //
18*cc02d7e2SAndroid Build Coastguard Worker
19*cc02d7e2SAndroid Build Coastguard Worker #include <condition_variable>
20*cc02d7e2SAndroid Build Coastguard Worker #include <memory>
21*cc02d7e2SAndroid Build Coastguard Worker #include <mutex>
22*cc02d7e2SAndroid Build Coastguard Worker #include <thread>
23*cc02d7e2SAndroid Build Coastguard Worker
24*cc02d7e2SAndroid Build Coastguard Worker #include <gtest/gtest.h>
25*cc02d7e2SAndroid Build Coastguard Worker
26*cc02d7e2SAndroid Build Coastguard Worker #include <grpcpp/alarm.h>
27*cc02d7e2SAndroid Build Coastguard Worker #include <grpcpp/completion_queue.h>
28*cc02d7e2SAndroid Build Coastguard Worker
29*cc02d7e2SAndroid Build Coastguard Worker #include "src/core/lib/gprpp/notification.h"
30*cc02d7e2SAndroid Build Coastguard Worker #include "test/core/util/test_config.h"
31*cc02d7e2SAndroid Build Coastguard Worker
32*cc02d7e2SAndroid Build Coastguard Worker namespace grpc {
33*cc02d7e2SAndroid Build Coastguard Worker namespace {
34*cc02d7e2SAndroid Build Coastguard Worker
TEST(AlarmTest,RegularExpiry)35*cc02d7e2SAndroid Build Coastguard Worker TEST(AlarmTest, RegularExpiry) {
36*cc02d7e2SAndroid Build Coastguard Worker CompletionQueue cq;
37*cc02d7e2SAndroid Build Coastguard Worker void* junk = reinterpret_cast<void*>(1618033);
38*cc02d7e2SAndroid Build Coastguard Worker Alarm alarm;
39*cc02d7e2SAndroid Build Coastguard Worker alarm.Set(&cq, grpc_timeout_seconds_to_deadline(1), junk);
40*cc02d7e2SAndroid Build Coastguard Worker
41*cc02d7e2SAndroid Build Coastguard Worker void* output_tag;
42*cc02d7e2SAndroid Build Coastguard Worker bool ok;
43*cc02d7e2SAndroid Build Coastguard Worker const CompletionQueue::NextStatus status =
44*cc02d7e2SAndroid Build Coastguard Worker cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(10));
45*cc02d7e2SAndroid Build Coastguard Worker
46*cc02d7e2SAndroid Build Coastguard Worker EXPECT_EQ(status, CompletionQueue::GOT_EVENT);
47*cc02d7e2SAndroid Build Coastguard Worker EXPECT_TRUE(ok);
48*cc02d7e2SAndroid Build Coastguard Worker EXPECT_EQ(junk, output_tag);
49*cc02d7e2SAndroid Build Coastguard Worker }
50*cc02d7e2SAndroid Build Coastguard Worker
TEST(AlarmTest,RegularExpiryMultiSet)51*cc02d7e2SAndroid Build Coastguard Worker TEST(AlarmTest, RegularExpiryMultiSet) {
52*cc02d7e2SAndroid Build Coastguard Worker CompletionQueue cq;
53*cc02d7e2SAndroid Build Coastguard Worker void* junk = reinterpret_cast<void*>(1618033);
54*cc02d7e2SAndroid Build Coastguard Worker Alarm alarm;
55*cc02d7e2SAndroid Build Coastguard Worker
56*cc02d7e2SAndroid Build Coastguard Worker for (int i = 0; i < 3; i++) {
57*cc02d7e2SAndroid Build Coastguard Worker alarm.Set(&cq, grpc_timeout_seconds_to_deadline(1), junk);
58*cc02d7e2SAndroid Build Coastguard Worker
59*cc02d7e2SAndroid Build Coastguard Worker void* output_tag;
60*cc02d7e2SAndroid Build Coastguard Worker bool ok;
61*cc02d7e2SAndroid Build Coastguard Worker const CompletionQueue::NextStatus status =
62*cc02d7e2SAndroid Build Coastguard Worker cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(10));
63*cc02d7e2SAndroid Build Coastguard Worker
64*cc02d7e2SAndroid Build Coastguard Worker EXPECT_EQ(status, CompletionQueue::GOT_EVENT);
65*cc02d7e2SAndroid Build Coastguard Worker EXPECT_TRUE(ok);
66*cc02d7e2SAndroid Build Coastguard Worker EXPECT_EQ(junk, output_tag);
67*cc02d7e2SAndroid Build Coastguard Worker }
68*cc02d7e2SAndroid Build Coastguard Worker }
69*cc02d7e2SAndroid Build Coastguard Worker
TEST(AlarmTest,RegularExpiryMultiSetMultiCQ)70*cc02d7e2SAndroid Build Coastguard Worker TEST(AlarmTest, RegularExpiryMultiSetMultiCQ) {
71*cc02d7e2SAndroid Build Coastguard Worker void* junk = reinterpret_cast<void*>(1618033);
72*cc02d7e2SAndroid Build Coastguard Worker Alarm alarm;
73*cc02d7e2SAndroid Build Coastguard Worker
74*cc02d7e2SAndroid Build Coastguard Worker for (int i = 0; i < 3; i++) {
75*cc02d7e2SAndroid Build Coastguard Worker CompletionQueue cq;
76*cc02d7e2SAndroid Build Coastguard Worker alarm.Set(&cq, grpc_timeout_seconds_to_deadline(1), junk);
77*cc02d7e2SAndroid Build Coastguard Worker
78*cc02d7e2SAndroid Build Coastguard Worker void* output_tag;
79*cc02d7e2SAndroid Build Coastguard Worker bool ok;
80*cc02d7e2SAndroid Build Coastguard Worker const CompletionQueue::NextStatus status =
81*cc02d7e2SAndroid Build Coastguard Worker cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(10));
82*cc02d7e2SAndroid Build Coastguard Worker
83*cc02d7e2SAndroid Build Coastguard Worker EXPECT_EQ(status, CompletionQueue::GOT_EVENT);
84*cc02d7e2SAndroid Build Coastguard Worker EXPECT_TRUE(ok);
85*cc02d7e2SAndroid Build Coastguard Worker EXPECT_EQ(junk, output_tag);
86*cc02d7e2SAndroid Build Coastguard Worker }
87*cc02d7e2SAndroid Build Coastguard Worker }
88*cc02d7e2SAndroid Build Coastguard Worker
89*cc02d7e2SAndroid Build Coastguard Worker struct Completion {
90*cc02d7e2SAndroid Build Coastguard Worker bool completed = false;
91*cc02d7e2SAndroid Build Coastguard Worker std::mutex mu;
92*cc02d7e2SAndroid Build Coastguard Worker std::condition_variable cv;
93*cc02d7e2SAndroid Build Coastguard Worker };
94*cc02d7e2SAndroid Build Coastguard Worker
TEST(AlarmTest,CallbackRegularExpiry)95*cc02d7e2SAndroid Build Coastguard Worker TEST(AlarmTest, CallbackRegularExpiry) {
96*cc02d7e2SAndroid Build Coastguard Worker Alarm alarm;
97*cc02d7e2SAndroid Build Coastguard Worker
98*cc02d7e2SAndroid Build Coastguard Worker auto c = std::make_shared<Completion>();
99*cc02d7e2SAndroid Build Coastguard Worker alarm.Set(std::chrono::system_clock::now() + std::chrono::seconds(1),
100*cc02d7e2SAndroid Build Coastguard Worker [c](bool ok) {
101*cc02d7e2SAndroid Build Coastguard Worker EXPECT_TRUE(ok);
102*cc02d7e2SAndroid Build Coastguard Worker std::lock_guard<std::mutex> l(c->mu);
103*cc02d7e2SAndroid Build Coastguard Worker c->completed = true;
104*cc02d7e2SAndroid Build Coastguard Worker c->cv.notify_one();
105*cc02d7e2SAndroid Build Coastguard Worker });
106*cc02d7e2SAndroid Build Coastguard Worker
107*cc02d7e2SAndroid Build Coastguard Worker std::unique_lock<std::mutex> l(c->mu);
108*cc02d7e2SAndroid Build Coastguard Worker EXPECT_TRUE(c->cv.wait_until(
109*cc02d7e2SAndroid Build Coastguard Worker l, std::chrono::system_clock::now() + std::chrono::seconds(10),
110*cc02d7e2SAndroid Build Coastguard Worker [c] { return c->completed; }));
111*cc02d7e2SAndroid Build Coastguard Worker }
112*cc02d7e2SAndroid Build Coastguard Worker
TEST(AlarmTest,CallbackZeroExpiry)113*cc02d7e2SAndroid Build Coastguard Worker TEST(AlarmTest, CallbackZeroExpiry) {
114*cc02d7e2SAndroid Build Coastguard Worker Alarm alarm;
115*cc02d7e2SAndroid Build Coastguard Worker
116*cc02d7e2SAndroid Build Coastguard Worker auto c = std::make_shared<Completion>();
117*cc02d7e2SAndroid Build Coastguard Worker alarm.Set(grpc_timeout_seconds_to_deadline(0), [c](bool ok) {
118*cc02d7e2SAndroid Build Coastguard Worker EXPECT_TRUE(ok);
119*cc02d7e2SAndroid Build Coastguard Worker std::lock_guard<std::mutex> l(c->mu);
120*cc02d7e2SAndroid Build Coastguard Worker c->completed = true;
121*cc02d7e2SAndroid Build Coastguard Worker c->cv.notify_one();
122*cc02d7e2SAndroid Build Coastguard Worker });
123*cc02d7e2SAndroid Build Coastguard Worker
124*cc02d7e2SAndroid Build Coastguard Worker std::unique_lock<std::mutex> l(c->mu);
125*cc02d7e2SAndroid Build Coastguard Worker EXPECT_TRUE(c->cv.wait_until(
126*cc02d7e2SAndroid Build Coastguard Worker l, std::chrono::system_clock::now() + std::chrono::seconds(10),
127*cc02d7e2SAndroid Build Coastguard Worker [c] { return c->completed; }));
128*cc02d7e2SAndroid Build Coastguard Worker }
129*cc02d7e2SAndroid Build Coastguard Worker
TEST(AlarmTest,CallbackNegativeExpiry)130*cc02d7e2SAndroid Build Coastguard Worker TEST(AlarmTest, CallbackNegativeExpiry) {
131*cc02d7e2SAndroid Build Coastguard Worker Alarm alarm;
132*cc02d7e2SAndroid Build Coastguard Worker
133*cc02d7e2SAndroid Build Coastguard Worker auto c = std::make_shared<Completion>();
134*cc02d7e2SAndroid Build Coastguard Worker alarm.Set(std::chrono::system_clock::now() + std::chrono::seconds(-1),
135*cc02d7e2SAndroid Build Coastguard Worker [c](bool ok) {
136*cc02d7e2SAndroid Build Coastguard Worker EXPECT_TRUE(ok);
137*cc02d7e2SAndroid Build Coastguard Worker std::lock_guard<std::mutex> l(c->mu);
138*cc02d7e2SAndroid Build Coastguard Worker c->completed = true;
139*cc02d7e2SAndroid Build Coastguard Worker c->cv.notify_one();
140*cc02d7e2SAndroid Build Coastguard Worker });
141*cc02d7e2SAndroid Build Coastguard Worker
142*cc02d7e2SAndroid Build Coastguard Worker std::unique_lock<std::mutex> l(c->mu);
143*cc02d7e2SAndroid Build Coastguard Worker EXPECT_TRUE(c->cv.wait_until(
144*cc02d7e2SAndroid Build Coastguard Worker l, std::chrono::system_clock::now() + std::chrono::seconds(10),
145*cc02d7e2SAndroid Build Coastguard Worker [c] { return c->completed; }));
146*cc02d7e2SAndroid Build Coastguard Worker }
147*cc02d7e2SAndroid Build Coastguard Worker
TEST(AlarmTest,MultithreadedRegularExpiry)148*cc02d7e2SAndroid Build Coastguard Worker TEST(AlarmTest, MultithreadedRegularExpiry) {
149*cc02d7e2SAndroid Build Coastguard Worker CompletionQueue cq;
150*cc02d7e2SAndroid Build Coastguard Worker void* junk = reinterpret_cast<void*>(1618033);
151*cc02d7e2SAndroid Build Coastguard Worker void* output_tag;
152*cc02d7e2SAndroid Build Coastguard Worker bool ok;
153*cc02d7e2SAndroid Build Coastguard Worker CompletionQueue::NextStatus status;
154*cc02d7e2SAndroid Build Coastguard Worker Alarm alarm;
155*cc02d7e2SAndroid Build Coastguard Worker
156*cc02d7e2SAndroid Build Coastguard Worker std::thread t1([&alarm, &cq, &junk] {
157*cc02d7e2SAndroid Build Coastguard Worker alarm.Set(&cq, grpc_timeout_seconds_to_deadline(1), junk);
158*cc02d7e2SAndroid Build Coastguard Worker });
159*cc02d7e2SAndroid Build Coastguard Worker
160*cc02d7e2SAndroid Build Coastguard Worker std::thread t2([&cq, &ok, &output_tag, &status] {
161*cc02d7e2SAndroid Build Coastguard Worker status =
162*cc02d7e2SAndroid Build Coastguard Worker cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(10));
163*cc02d7e2SAndroid Build Coastguard Worker });
164*cc02d7e2SAndroid Build Coastguard Worker
165*cc02d7e2SAndroid Build Coastguard Worker t1.join();
166*cc02d7e2SAndroid Build Coastguard Worker t2.join();
167*cc02d7e2SAndroid Build Coastguard Worker EXPECT_EQ(status, CompletionQueue::GOT_EVENT);
168*cc02d7e2SAndroid Build Coastguard Worker EXPECT_TRUE(ok);
169*cc02d7e2SAndroid Build Coastguard Worker EXPECT_EQ(junk, output_tag);
170*cc02d7e2SAndroid Build Coastguard Worker }
171*cc02d7e2SAndroid Build Coastguard Worker
TEST(AlarmTest,DeprecatedRegularExpiry)172*cc02d7e2SAndroid Build Coastguard Worker TEST(AlarmTest, DeprecatedRegularExpiry) {
173*cc02d7e2SAndroid Build Coastguard Worker CompletionQueue cq;
174*cc02d7e2SAndroid Build Coastguard Worker void* junk = reinterpret_cast<void*>(1618033);
175*cc02d7e2SAndroid Build Coastguard Worker Alarm alarm(&cq, grpc_timeout_seconds_to_deadline(1), junk);
176*cc02d7e2SAndroid Build Coastguard Worker
177*cc02d7e2SAndroid Build Coastguard Worker void* output_tag;
178*cc02d7e2SAndroid Build Coastguard Worker bool ok;
179*cc02d7e2SAndroid Build Coastguard Worker const CompletionQueue::NextStatus status =
180*cc02d7e2SAndroid Build Coastguard Worker cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(10));
181*cc02d7e2SAndroid Build Coastguard Worker
182*cc02d7e2SAndroid Build Coastguard Worker EXPECT_EQ(status, CompletionQueue::GOT_EVENT);
183*cc02d7e2SAndroid Build Coastguard Worker EXPECT_TRUE(ok);
184*cc02d7e2SAndroid Build Coastguard Worker EXPECT_EQ(junk, output_tag);
185*cc02d7e2SAndroid Build Coastguard Worker }
186*cc02d7e2SAndroid Build Coastguard Worker
TEST(AlarmTest,MoveConstructor)187*cc02d7e2SAndroid Build Coastguard Worker TEST(AlarmTest, MoveConstructor) {
188*cc02d7e2SAndroid Build Coastguard Worker CompletionQueue cq;
189*cc02d7e2SAndroid Build Coastguard Worker void* junk = reinterpret_cast<void*>(1618033);
190*cc02d7e2SAndroid Build Coastguard Worker Alarm first;
191*cc02d7e2SAndroid Build Coastguard Worker first.Set(&cq, grpc_timeout_seconds_to_deadline(1), junk);
192*cc02d7e2SAndroid Build Coastguard Worker Alarm second(std::move(first));
193*cc02d7e2SAndroid Build Coastguard Worker void* output_tag;
194*cc02d7e2SAndroid Build Coastguard Worker bool ok;
195*cc02d7e2SAndroid Build Coastguard Worker const CompletionQueue::NextStatus status =
196*cc02d7e2SAndroid Build Coastguard Worker cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(10));
197*cc02d7e2SAndroid Build Coastguard Worker EXPECT_EQ(status, CompletionQueue::GOT_EVENT);
198*cc02d7e2SAndroid Build Coastguard Worker EXPECT_TRUE(ok);
199*cc02d7e2SAndroid Build Coastguard Worker EXPECT_EQ(junk, output_tag);
200*cc02d7e2SAndroid Build Coastguard Worker }
201*cc02d7e2SAndroid Build Coastguard Worker
TEST(AlarmTest,MoveAssignment)202*cc02d7e2SAndroid Build Coastguard Worker TEST(AlarmTest, MoveAssignment) {
203*cc02d7e2SAndroid Build Coastguard Worker CompletionQueue cq;
204*cc02d7e2SAndroid Build Coastguard Worker void* junk = reinterpret_cast<void*>(1618033);
205*cc02d7e2SAndroid Build Coastguard Worker Alarm first;
206*cc02d7e2SAndroid Build Coastguard Worker first.Set(&cq, grpc_timeout_seconds_to_deadline(1), junk);
207*cc02d7e2SAndroid Build Coastguard Worker Alarm second(std::move(first));
208*cc02d7e2SAndroid Build Coastguard Worker first = std::move(second);
209*cc02d7e2SAndroid Build Coastguard Worker
210*cc02d7e2SAndroid Build Coastguard Worker void* output_tag;
211*cc02d7e2SAndroid Build Coastguard Worker bool ok;
212*cc02d7e2SAndroid Build Coastguard Worker const CompletionQueue::NextStatus status =
213*cc02d7e2SAndroid Build Coastguard Worker cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(10));
214*cc02d7e2SAndroid Build Coastguard Worker
215*cc02d7e2SAndroid Build Coastguard Worker EXPECT_EQ(status, CompletionQueue::GOT_EVENT);
216*cc02d7e2SAndroid Build Coastguard Worker EXPECT_TRUE(ok);
217*cc02d7e2SAndroid Build Coastguard Worker EXPECT_EQ(junk, output_tag);
218*cc02d7e2SAndroid Build Coastguard Worker }
219*cc02d7e2SAndroid Build Coastguard Worker
TEST(AlarmTest,RegularExpiryChrono)220*cc02d7e2SAndroid Build Coastguard Worker TEST(AlarmTest, RegularExpiryChrono) {
221*cc02d7e2SAndroid Build Coastguard Worker CompletionQueue cq;
222*cc02d7e2SAndroid Build Coastguard Worker void* junk = reinterpret_cast<void*>(1618033);
223*cc02d7e2SAndroid Build Coastguard Worker std::chrono::system_clock::time_point one_sec_deadline =
224*cc02d7e2SAndroid Build Coastguard Worker std::chrono::system_clock::now() + std::chrono::seconds(1);
225*cc02d7e2SAndroid Build Coastguard Worker Alarm alarm;
226*cc02d7e2SAndroid Build Coastguard Worker alarm.Set(&cq, one_sec_deadline, junk);
227*cc02d7e2SAndroid Build Coastguard Worker
228*cc02d7e2SAndroid Build Coastguard Worker void* output_tag;
229*cc02d7e2SAndroid Build Coastguard Worker bool ok;
230*cc02d7e2SAndroid Build Coastguard Worker const CompletionQueue::NextStatus status =
231*cc02d7e2SAndroid Build Coastguard Worker cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(10));
232*cc02d7e2SAndroid Build Coastguard Worker
233*cc02d7e2SAndroid Build Coastguard Worker EXPECT_EQ(status, CompletionQueue::GOT_EVENT);
234*cc02d7e2SAndroid Build Coastguard Worker EXPECT_TRUE(ok);
235*cc02d7e2SAndroid Build Coastguard Worker EXPECT_EQ(junk, output_tag);
236*cc02d7e2SAndroid Build Coastguard Worker }
237*cc02d7e2SAndroid Build Coastguard Worker
TEST(AlarmTest,ZeroExpiry)238*cc02d7e2SAndroid Build Coastguard Worker TEST(AlarmTest, ZeroExpiry) {
239*cc02d7e2SAndroid Build Coastguard Worker CompletionQueue cq;
240*cc02d7e2SAndroid Build Coastguard Worker void* junk = reinterpret_cast<void*>(1618033);
241*cc02d7e2SAndroid Build Coastguard Worker Alarm alarm;
242*cc02d7e2SAndroid Build Coastguard Worker alarm.Set(&cq, grpc_timeout_seconds_to_deadline(0), junk);
243*cc02d7e2SAndroid Build Coastguard Worker
244*cc02d7e2SAndroid Build Coastguard Worker void* output_tag;
245*cc02d7e2SAndroid Build Coastguard Worker bool ok;
246*cc02d7e2SAndroid Build Coastguard Worker const CompletionQueue::NextStatus status =
247*cc02d7e2SAndroid Build Coastguard Worker cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(1));
248*cc02d7e2SAndroid Build Coastguard Worker
249*cc02d7e2SAndroid Build Coastguard Worker EXPECT_EQ(status, CompletionQueue::GOT_EVENT);
250*cc02d7e2SAndroid Build Coastguard Worker EXPECT_TRUE(ok);
251*cc02d7e2SAndroid Build Coastguard Worker EXPECT_EQ(junk, output_tag);
252*cc02d7e2SAndroid Build Coastguard Worker }
253*cc02d7e2SAndroid Build Coastguard Worker
TEST(AlarmTest,NegativeExpiry)254*cc02d7e2SAndroid Build Coastguard Worker TEST(AlarmTest, NegativeExpiry) {
255*cc02d7e2SAndroid Build Coastguard Worker CompletionQueue cq;
256*cc02d7e2SAndroid Build Coastguard Worker void* junk = reinterpret_cast<void*>(1618033);
257*cc02d7e2SAndroid Build Coastguard Worker Alarm alarm;
258*cc02d7e2SAndroid Build Coastguard Worker alarm.Set(&cq, grpc_timeout_seconds_to_deadline(-1), junk);
259*cc02d7e2SAndroid Build Coastguard Worker
260*cc02d7e2SAndroid Build Coastguard Worker void* output_tag;
261*cc02d7e2SAndroid Build Coastguard Worker bool ok;
262*cc02d7e2SAndroid Build Coastguard Worker const CompletionQueue::NextStatus status =
263*cc02d7e2SAndroid Build Coastguard Worker cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(1));
264*cc02d7e2SAndroid Build Coastguard Worker
265*cc02d7e2SAndroid Build Coastguard Worker EXPECT_EQ(status, CompletionQueue::GOT_EVENT);
266*cc02d7e2SAndroid Build Coastguard Worker EXPECT_TRUE(ok);
267*cc02d7e2SAndroid Build Coastguard Worker EXPECT_EQ(junk, output_tag);
268*cc02d7e2SAndroid Build Coastguard Worker }
269*cc02d7e2SAndroid Build Coastguard Worker
270*cc02d7e2SAndroid Build Coastguard Worker // Infinite past or unix epoch should fire immediately.
TEST(AlarmTest,InfPastExpiry)271*cc02d7e2SAndroid Build Coastguard Worker TEST(AlarmTest, InfPastExpiry) {
272*cc02d7e2SAndroid Build Coastguard Worker CompletionQueue cq;
273*cc02d7e2SAndroid Build Coastguard Worker void* junk = reinterpret_cast<void*>(1618033);
274*cc02d7e2SAndroid Build Coastguard Worker Alarm alarm;
275*cc02d7e2SAndroid Build Coastguard Worker alarm.Set(&cq, gpr_inf_past(GPR_CLOCK_REALTIME), junk);
276*cc02d7e2SAndroid Build Coastguard Worker
277*cc02d7e2SAndroid Build Coastguard Worker void* output_tag;
278*cc02d7e2SAndroid Build Coastguard Worker bool ok;
279*cc02d7e2SAndroid Build Coastguard Worker CompletionQueue::NextStatus status =
280*cc02d7e2SAndroid Build Coastguard Worker cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(10));
281*cc02d7e2SAndroid Build Coastguard Worker
282*cc02d7e2SAndroid Build Coastguard Worker EXPECT_EQ(status, CompletionQueue::GOT_EVENT);
283*cc02d7e2SAndroid Build Coastguard Worker EXPECT_TRUE(ok);
284*cc02d7e2SAndroid Build Coastguard Worker EXPECT_EQ(junk, output_tag);
285*cc02d7e2SAndroid Build Coastguard Worker
286*cc02d7e2SAndroid Build Coastguard Worker alarm.Set(&cq, std::chrono::system_clock::time_point(), junk);
287*cc02d7e2SAndroid Build Coastguard Worker status = cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(10));
288*cc02d7e2SAndroid Build Coastguard Worker
289*cc02d7e2SAndroid Build Coastguard Worker EXPECT_EQ(status, CompletionQueue::GOT_EVENT);
290*cc02d7e2SAndroid Build Coastguard Worker EXPECT_TRUE(ok);
291*cc02d7e2SAndroid Build Coastguard Worker EXPECT_EQ(junk, output_tag);
292*cc02d7e2SAndroid Build Coastguard Worker }
293*cc02d7e2SAndroid Build Coastguard Worker
TEST(AlarmTest,Cancellation)294*cc02d7e2SAndroid Build Coastguard Worker TEST(AlarmTest, Cancellation) {
295*cc02d7e2SAndroid Build Coastguard Worker CompletionQueue cq;
296*cc02d7e2SAndroid Build Coastguard Worker void* junk = reinterpret_cast<void*>(1618033);
297*cc02d7e2SAndroid Build Coastguard Worker Alarm alarm;
298*cc02d7e2SAndroid Build Coastguard Worker alarm.Set(&cq, grpc_timeout_seconds_to_deadline(10), junk);
299*cc02d7e2SAndroid Build Coastguard Worker alarm.Cancel();
300*cc02d7e2SAndroid Build Coastguard Worker
301*cc02d7e2SAndroid Build Coastguard Worker void* output_tag;
302*cc02d7e2SAndroid Build Coastguard Worker bool ok;
303*cc02d7e2SAndroid Build Coastguard Worker const CompletionQueue::NextStatus status =
304*cc02d7e2SAndroid Build Coastguard Worker cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(1));
305*cc02d7e2SAndroid Build Coastguard Worker
306*cc02d7e2SAndroid Build Coastguard Worker EXPECT_EQ(status, CompletionQueue::GOT_EVENT);
307*cc02d7e2SAndroid Build Coastguard Worker EXPECT_FALSE(ok);
308*cc02d7e2SAndroid Build Coastguard Worker EXPECT_EQ(junk, output_tag);
309*cc02d7e2SAndroid Build Coastguard Worker }
310*cc02d7e2SAndroid Build Coastguard Worker
TEST(AlarmTest,CancellationMultiSet)311*cc02d7e2SAndroid Build Coastguard Worker TEST(AlarmTest, CancellationMultiSet) {
312*cc02d7e2SAndroid Build Coastguard Worker // Tests the cancellation and re-Set paths together.
313*cc02d7e2SAndroid Build Coastguard Worker CompletionQueue cq;
314*cc02d7e2SAndroid Build Coastguard Worker void* junk = reinterpret_cast<void*>(1618033);
315*cc02d7e2SAndroid Build Coastguard Worker Alarm alarm;
316*cc02d7e2SAndroid Build Coastguard Worker // First iteration
317*cc02d7e2SAndroid Build Coastguard Worker alarm.Set(&cq, grpc_timeout_seconds_to_deadline(5), junk);
318*cc02d7e2SAndroid Build Coastguard Worker alarm.Cancel();
319*cc02d7e2SAndroid Build Coastguard Worker void* output_tag;
320*cc02d7e2SAndroid Build Coastguard Worker bool ok;
321*cc02d7e2SAndroid Build Coastguard Worker CompletionQueue::NextStatus status =
322*cc02d7e2SAndroid Build Coastguard Worker cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(10));
323*cc02d7e2SAndroid Build Coastguard Worker EXPECT_EQ(status, CompletionQueue::GOT_EVENT);
324*cc02d7e2SAndroid Build Coastguard Worker EXPECT_FALSE(ok);
325*cc02d7e2SAndroid Build Coastguard Worker EXPECT_EQ(junk, output_tag);
326*cc02d7e2SAndroid Build Coastguard Worker // Second iteration
327*cc02d7e2SAndroid Build Coastguard Worker alarm.Set(&cq, grpc_timeout_seconds_to_deadline(5), junk);
328*cc02d7e2SAndroid Build Coastguard Worker alarm.Cancel();
329*cc02d7e2SAndroid Build Coastguard Worker status = cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(10));
330*cc02d7e2SAndroid Build Coastguard Worker EXPECT_EQ(status, CompletionQueue::GOT_EVENT);
331*cc02d7e2SAndroid Build Coastguard Worker EXPECT_FALSE(ok);
332*cc02d7e2SAndroid Build Coastguard Worker EXPECT_EQ(junk, output_tag);
333*cc02d7e2SAndroid Build Coastguard Worker }
334*cc02d7e2SAndroid Build Coastguard Worker
TEST(AlarmTest,CallbackCancellation)335*cc02d7e2SAndroid Build Coastguard Worker TEST(AlarmTest, CallbackCancellation) {
336*cc02d7e2SAndroid Build Coastguard Worker Alarm alarm;
337*cc02d7e2SAndroid Build Coastguard Worker
338*cc02d7e2SAndroid Build Coastguard Worker auto c = std::make_shared<Completion>();
339*cc02d7e2SAndroid Build Coastguard Worker alarm.Set(std::chrono::system_clock::now() + std::chrono::seconds(10),
340*cc02d7e2SAndroid Build Coastguard Worker [c](bool ok) {
341*cc02d7e2SAndroid Build Coastguard Worker EXPECT_FALSE(ok);
342*cc02d7e2SAndroid Build Coastguard Worker std::lock_guard<std::mutex> l(c->mu);
343*cc02d7e2SAndroid Build Coastguard Worker c->completed = true;
344*cc02d7e2SAndroid Build Coastguard Worker c->cv.notify_one();
345*cc02d7e2SAndroid Build Coastguard Worker });
346*cc02d7e2SAndroid Build Coastguard Worker alarm.Cancel();
347*cc02d7e2SAndroid Build Coastguard Worker
348*cc02d7e2SAndroid Build Coastguard Worker std::unique_lock<std::mutex> l(c->mu);
349*cc02d7e2SAndroid Build Coastguard Worker EXPECT_TRUE(c->cv.wait_until(
350*cc02d7e2SAndroid Build Coastguard Worker l, std::chrono::system_clock::now() + std::chrono::seconds(1),
351*cc02d7e2SAndroid Build Coastguard Worker [c] { return c->completed; }));
352*cc02d7e2SAndroid Build Coastguard Worker }
353*cc02d7e2SAndroid Build Coastguard Worker
TEST(AlarmTest,CallbackCancellationMultiSet)354*cc02d7e2SAndroid Build Coastguard Worker TEST(AlarmTest, CallbackCancellationMultiSet) {
355*cc02d7e2SAndroid Build Coastguard Worker // Tests the cancellation and re-Set paths.
356*cc02d7e2SAndroid Build Coastguard Worker Alarm alarm;
357*cc02d7e2SAndroid Build Coastguard Worker // First iteration
358*cc02d7e2SAndroid Build Coastguard Worker {
359*cc02d7e2SAndroid Build Coastguard Worker grpc_core::Notification notification;
360*cc02d7e2SAndroid Build Coastguard Worker alarm.Set(std::chrono::system_clock::now() + std::chrono::seconds(10),
361*cc02d7e2SAndroid Build Coastguard Worker [¬ification](bool ok) {
362*cc02d7e2SAndroid Build Coastguard Worker EXPECT_FALSE(ok);
363*cc02d7e2SAndroid Build Coastguard Worker notification.Notify();
364*cc02d7e2SAndroid Build Coastguard Worker });
365*cc02d7e2SAndroid Build Coastguard Worker alarm.Cancel();
366*cc02d7e2SAndroid Build Coastguard Worker notification.WaitForNotification();
367*cc02d7e2SAndroid Build Coastguard Worker }
368*cc02d7e2SAndroid Build Coastguard Worker // First iteration
369*cc02d7e2SAndroid Build Coastguard Worker {
370*cc02d7e2SAndroid Build Coastguard Worker grpc_core::Notification notification;
371*cc02d7e2SAndroid Build Coastguard Worker alarm.Set(std::chrono::system_clock::now() + std::chrono::seconds(10),
372*cc02d7e2SAndroid Build Coastguard Worker [¬ification](bool ok) {
373*cc02d7e2SAndroid Build Coastguard Worker EXPECT_FALSE(ok);
374*cc02d7e2SAndroid Build Coastguard Worker notification.Notify();
375*cc02d7e2SAndroid Build Coastguard Worker });
376*cc02d7e2SAndroid Build Coastguard Worker alarm.Cancel();
377*cc02d7e2SAndroid Build Coastguard Worker notification.WaitForNotification();
378*cc02d7e2SAndroid Build Coastguard Worker }
379*cc02d7e2SAndroid Build Coastguard Worker }
380*cc02d7e2SAndroid Build Coastguard Worker
TEST(AlarmTest,CallbackCancellationLocked)381*cc02d7e2SAndroid Build Coastguard Worker TEST(AlarmTest, CallbackCancellationLocked) {
382*cc02d7e2SAndroid Build Coastguard Worker Alarm alarm;
383*cc02d7e2SAndroid Build Coastguard Worker
384*cc02d7e2SAndroid Build Coastguard Worker auto c = std::make_shared<Completion>();
385*cc02d7e2SAndroid Build Coastguard Worker alarm.Set(std::chrono::system_clock::now() + std::chrono::seconds(10),
386*cc02d7e2SAndroid Build Coastguard Worker [c](bool ok) {
387*cc02d7e2SAndroid Build Coastguard Worker EXPECT_FALSE(ok);
388*cc02d7e2SAndroid Build Coastguard Worker std::lock_guard<std::mutex> l(c->mu);
389*cc02d7e2SAndroid Build Coastguard Worker c->completed = true;
390*cc02d7e2SAndroid Build Coastguard Worker c->cv.notify_one();
391*cc02d7e2SAndroid Build Coastguard Worker });
392*cc02d7e2SAndroid Build Coastguard Worker std::unique_lock<std::mutex> l(c->mu);
393*cc02d7e2SAndroid Build Coastguard Worker alarm.Cancel();
394*cc02d7e2SAndroid Build Coastguard Worker
395*cc02d7e2SAndroid Build Coastguard Worker EXPECT_TRUE(c->cv.wait_until(
396*cc02d7e2SAndroid Build Coastguard Worker l, std::chrono::system_clock::now() + std::chrono::seconds(1),
397*cc02d7e2SAndroid Build Coastguard Worker [c] { return c->completed; }));
398*cc02d7e2SAndroid Build Coastguard Worker }
399*cc02d7e2SAndroid Build Coastguard Worker
TEST(AlarmTest,SetDestruction)400*cc02d7e2SAndroid Build Coastguard Worker TEST(AlarmTest, SetDestruction) {
401*cc02d7e2SAndroid Build Coastguard Worker CompletionQueue cq;
402*cc02d7e2SAndroid Build Coastguard Worker void* junk = reinterpret_cast<void*>(1618033);
403*cc02d7e2SAndroid Build Coastguard Worker {
404*cc02d7e2SAndroid Build Coastguard Worker Alarm alarm;
405*cc02d7e2SAndroid Build Coastguard Worker alarm.Set(&cq, grpc_timeout_seconds_to_deadline(10), junk);
406*cc02d7e2SAndroid Build Coastguard Worker }
407*cc02d7e2SAndroid Build Coastguard Worker
408*cc02d7e2SAndroid Build Coastguard Worker void* output_tag;
409*cc02d7e2SAndroid Build Coastguard Worker bool ok;
410*cc02d7e2SAndroid Build Coastguard Worker const CompletionQueue::NextStatus status =
411*cc02d7e2SAndroid Build Coastguard Worker cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(1));
412*cc02d7e2SAndroid Build Coastguard Worker
413*cc02d7e2SAndroid Build Coastguard Worker EXPECT_EQ(status, CompletionQueue::GOT_EVENT);
414*cc02d7e2SAndroid Build Coastguard Worker EXPECT_FALSE(ok);
415*cc02d7e2SAndroid Build Coastguard Worker EXPECT_EQ(junk, output_tag);
416*cc02d7e2SAndroid Build Coastguard Worker }
417*cc02d7e2SAndroid Build Coastguard Worker
TEST(AlarmTest,CallbackSetDestruction)418*cc02d7e2SAndroid Build Coastguard Worker TEST(AlarmTest, CallbackSetDestruction) {
419*cc02d7e2SAndroid Build Coastguard Worker auto c = std::make_shared<Completion>();
420*cc02d7e2SAndroid Build Coastguard Worker {
421*cc02d7e2SAndroid Build Coastguard Worker Alarm alarm;
422*cc02d7e2SAndroid Build Coastguard Worker alarm.Set(std::chrono::system_clock::now() + std::chrono::seconds(10),
423*cc02d7e2SAndroid Build Coastguard Worker [c](bool ok) {
424*cc02d7e2SAndroid Build Coastguard Worker EXPECT_FALSE(ok);
425*cc02d7e2SAndroid Build Coastguard Worker std::lock_guard<std::mutex> l(c->mu);
426*cc02d7e2SAndroid Build Coastguard Worker c->completed = true;
427*cc02d7e2SAndroid Build Coastguard Worker c->cv.notify_one();
428*cc02d7e2SAndroid Build Coastguard Worker });
429*cc02d7e2SAndroid Build Coastguard Worker }
430*cc02d7e2SAndroid Build Coastguard Worker
431*cc02d7e2SAndroid Build Coastguard Worker std::unique_lock<std::mutex> l(c->mu);
432*cc02d7e2SAndroid Build Coastguard Worker EXPECT_TRUE(c->cv.wait_until(
433*cc02d7e2SAndroid Build Coastguard Worker l, std::chrono::system_clock::now() + std::chrono::seconds(1),
434*cc02d7e2SAndroid Build Coastguard Worker [c] { return c->completed; }));
435*cc02d7e2SAndroid Build Coastguard Worker }
436*cc02d7e2SAndroid Build Coastguard Worker
TEST(AlarmTest,UnsetDestruction)437*cc02d7e2SAndroid Build Coastguard Worker TEST(AlarmTest, UnsetDestruction) {
438*cc02d7e2SAndroid Build Coastguard Worker CompletionQueue cq;
439*cc02d7e2SAndroid Build Coastguard Worker Alarm alarm;
440*cc02d7e2SAndroid Build Coastguard Worker }
441*cc02d7e2SAndroid Build Coastguard Worker
442*cc02d7e2SAndroid Build Coastguard Worker } // namespace
443*cc02d7e2SAndroid Build Coastguard Worker } // namespace grpc
444*cc02d7e2SAndroid Build Coastguard Worker
main(int argc,char ** argv)445*cc02d7e2SAndroid Build Coastguard Worker int main(int argc, char** argv) {
446*cc02d7e2SAndroid Build Coastguard Worker grpc::testing::TestEnvironment env(&argc, argv);
447*cc02d7e2SAndroid Build Coastguard Worker ::testing::InitGoogleTest(&argc, argv);
448*cc02d7e2SAndroid Build Coastguard Worker return RUN_ALL_TESTS();
449*cc02d7e2SAndroid Build Coastguard Worker }
450