xref: /aosp_15_r20/external/grpc-grpc/test/core/transport/chttp2/ping_callbacks_test.cc (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1 // Copyright 2023 gRPC authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "src/core/ext/transport/chttp2/transport/ping_callbacks.h"
16 
17 #include <chrono>
18 
19 #include "absl/random/random.h"
20 #include "gmock/gmock.h"
21 #include "gtest/gtest.h"
22 
23 #include "src/core/lib/gprpp/crash.h"
24 #include "test/core/event_engine/mock_event_engine.h"
25 
26 using grpc_event_engine::experimental::EventEngine;
27 using grpc_event_engine::experimental::MockEventEngine;
28 using testing::_;
29 using testing::Matcher;
30 using testing::Return;
31 using testing::StrictMock;
32 
33 namespace grpc_core {
34 namespace {
35 
TEST(PingCallbacksTest,RequestPingRequestsPing)36 TEST(PingCallbacksTest, RequestPingRequestsPing) {
37   Chttp2PingCallbacks callbacks;
38   EXPECT_FALSE(callbacks.ping_requested());
39   callbacks.RequestPing();
40   EXPECT_TRUE(callbacks.ping_requested());
41 }
42 
TEST(PingCallbacksTest,OnPingRequestsPing)43 TEST(PingCallbacksTest, OnPingRequestsPing) {
44   Chttp2PingCallbacks callbacks;
45   EXPECT_FALSE(callbacks.ping_requested());
46   callbacks.OnPing([] {}, [] {});
47   EXPECT_TRUE(callbacks.ping_requested());
48 }
49 
TEST(PingCallbacksTest,OnPingAckRequestsPing)50 TEST(PingCallbacksTest, OnPingAckRequestsPing) {
51   Chttp2PingCallbacks callbacks;
52   EXPECT_FALSE(callbacks.ping_requested());
53   callbacks.OnPingAck([] {});
54   EXPECT_TRUE(callbacks.ping_requested());
55 }
56 
TEST(PingCallbacksTest,PingAckBeforeTimerStarted)57 TEST(PingCallbacksTest, PingAckBeforeTimerStarted) {
58   StrictMock<MockEventEngine> event_engine;
59   absl::BitGen bitgen;
60   Chttp2PingCallbacks callbacks;
61   bool started = false;
62   bool acked = false;
63   EXPECT_FALSE(callbacks.ping_requested());
64   EXPECT_FALSE(callbacks.started_new_ping_without_setting_timeout());
65   // Request ping
66   callbacks.OnPing(
67       [&started] {
68         EXPECT_FALSE(started);
69         started = true;
70       },
71       [&acked] {
72         EXPECT_FALSE(acked);
73         acked = true;
74       });
75   EXPECT_TRUE(callbacks.ping_requested());
76   EXPECT_FALSE(callbacks.started_new_ping_without_setting_timeout());
77   EXPECT_EQ(callbacks.pings_inflight(), 0);
78   EXPECT_FALSE(started);
79   EXPECT_FALSE(acked);
80   auto id = callbacks.StartPing(bitgen);
81   EXPECT_TRUE(callbacks.started_new_ping_without_setting_timeout());
82   EXPECT_FALSE(callbacks.ping_requested());
83   EXPECT_EQ(callbacks.pings_inflight(), 1);
84   EXPECT_TRUE(started);
85   EXPECT_FALSE(acked);
86   callbacks.AckPing(id, &event_engine);
87   EXPECT_TRUE(callbacks.started_new_ping_without_setting_timeout());
88   EXPECT_FALSE(callbacks.ping_requested());
89   EXPECT_EQ(callbacks.pings_inflight(), 0);
90   EXPECT_TRUE(started);
91   EXPECT_TRUE(acked);
92   callbacks.OnPingTimeout(Duration::Milliseconds(1), &event_engine,
93                           [] { Crash("should never reach here"); });
94 }
95 
TEST(PingCallbacksTest,PingRoundtrips)96 TEST(PingCallbacksTest, PingRoundtrips) {
97   StrictMock<MockEventEngine> event_engine;
98   absl::BitGen bitgen;
99   Chttp2PingCallbacks callbacks;
100   bool started = false;
101   bool acked = false;
102   EXPECT_FALSE(callbacks.ping_requested());
103   // Request ping
104   callbacks.OnPing(
105       [&started] {
106         EXPECT_FALSE(started);
107         started = true;
108       },
109       [&acked] {
110         EXPECT_FALSE(acked);
111         acked = true;
112       });
113   EXPECT_TRUE(callbacks.ping_requested());
114   EXPECT_EQ(callbacks.pings_inflight(), 0);
115   EXPECT_FALSE(started);
116   EXPECT_FALSE(acked);
117   // Start ping should call the start methods, set a timeout, and clear the
118   // request
119   EXPECT_CALL(event_engine, RunAfter(EventEngine::Duration(Duration::Hours(24)),
120                                      Matcher<absl::AnyInvocable<void()>>(_)))
121       .WillOnce([]() {
122         return EventEngine::TaskHandle{123, 456};
123       });
124   auto id = callbacks.StartPing(bitgen);
125   callbacks.OnPingTimeout(Duration::Hours(24), &event_engine,
126                           [] { Crash("should not reach here"); });
127   EXPECT_FALSE(callbacks.ping_requested());
128   EXPECT_EQ(callbacks.pings_inflight(), 1);
129   EXPECT_TRUE(started);
130   EXPECT_FALSE(acked);
131   // Ack should cancel the timeout
132   EXPECT_CALL(event_engine, Cancel(EventEngine::TaskHandle{123, 456}))
133       .WillOnce(Return(true));
134   EXPECT_TRUE(callbacks.AckPing(id, &event_engine));
135   EXPECT_EQ(callbacks.pings_inflight(), 0);
136   EXPECT_FALSE(callbacks.ping_requested());
137   EXPECT_TRUE(started);
138   EXPECT_TRUE(acked);
139 }
140 
TEST(PingCallbacksTest,PingRoundtripsWithInfiniteTimeout)141 TEST(PingCallbacksTest, PingRoundtripsWithInfiniteTimeout) {
142   StrictMock<MockEventEngine> event_engine;
143   absl::BitGen bitgen;
144   Chttp2PingCallbacks callbacks;
145   bool started = false;
146   bool acked = false;
147   EXPECT_FALSE(callbacks.ping_requested());
148   // Request ping
149   callbacks.OnPing(
150       [&started] {
151         EXPECT_FALSE(started);
152         started = true;
153       },
154       [&acked] {
155         EXPECT_FALSE(acked);
156         acked = true;
157       });
158   EXPECT_TRUE(callbacks.ping_requested());
159   EXPECT_EQ(callbacks.pings_inflight(), 0);
160   EXPECT_FALSE(started);
161   EXPECT_FALSE(acked);
162   auto id = callbacks.StartPing(bitgen);
163   EXPECT_FALSE(callbacks.ping_requested());
164   EXPECT_EQ(callbacks.pings_inflight(), 1);
165   EXPECT_TRUE(started);
166   EXPECT_FALSE(acked);
167   EXPECT_TRUE(callbacks.AckPing(id, &event_engine));
168   EXPECT_EQ(callbacks.pings_inflight(), 0);
169   EXPECT_FALSE(callbacks.ping_requested());
170   EXPECT_TRUE(started);
171   EXPECT_TRUE(acked);
172 }
173 
TEST(PingCallbacksTest,InvalidPingIdFlagsError)174 TEST(PingCallbacksTest, InvalidPingIdFlagsError) {
175   StrictMock<MockEventEngine> event_engine;
176   Chttp2PingCallbacks callbacks;
177   EXPECT_FALSE(callbacks.AckPing(1234, &event_engine));
178 }
179 
TEST(PingCallbacksTest,DuplicatePingIdFlagsError)180 TEST(PingCallbacksTest, DuplicatePingIdFlagsError) {
181   StrictMock<MockEventEngine> event_engine;
182   absl::BitGen bitgen;
183   Chttp2PingCallbacks callbacks;
184   bool started = false;
185   bool acked = false;
186   EXPECT_FALSE(callbacks.ping_requested());
187   callbacks.OnPing(
188       [&started] {
189         EXPECT_FALSE(started);
190         started = true;
191       },
192       [&acked] {
193         EXPECT_FALSE(acked);
194         acked = true;
195       });
196   EXPECT_TRUE(callbacks.ping_requested());
197   EXPECT_FALSE(started);
198   EXPECT_FALSE(acked);
199   EXPECT_CALL(event_engine, RunAfter(EventEngine::Duration(Duration::Hours(24)),
200                                      Matcher<absl::AnyInvocable<void()>>(_)))
201       .WillOnce([]() {
202         return EventEngine::TaskHandle{123, 456};
203       });
204   auto id = callbacks.StartPing(bitgen);
205   callbacks.OnPingTimeout(Duration::Hours(24), &event_engine,
206                           [] { Crash("should not reach here"); });
207   EXPECT_FALSE(callbacks.ping_requested());
208   EXPECT_TRUE(started);
209   EXPECT_FALSE(acked);
210   EXPECT_CALL(event_engine, Cancel(EventEngine::TaskHandle{123, 456}))
211       .WillOnce(Return(true));
212   EXPECT_TRUE(callbacks.AckPing(id, &event_engine));
213   EXPECT_FALSE(callbacks.ping_requested());
214   EXPECT_TRUE(started);
215   EXPECT_TRUE(acked);
216   // Second ping ack on the same id should fail
217   EXPECT_FALSE(callbacks.AckPing(id, &event_engine));
218 }
219 
TEST(PingCallbacksTest,OnPingAckCanPiggybackInflightPings)220 TEST(PingCallbacksTest, OnPingAckCanPiggybackInflightPings) {
221   StrictMock<MockEventEngine> event_engine;
222   absl::BitGen bitgen;
223   Chttp2PingCallbacks callbacks;
224   bool started = false;
225   bool acked_first = false;
226   bool acked_second = false;
227   EXPECT_FALSE(callbacks.ping_requested());
228   callbacks.OnPing(
229       [&started] {
230         EXPECT_FALSE(started);
231         started = true;
232       },
233       [&acked_first] {
234         EXPECT_FALSE(acked_first);
235         acked_first = true;
236       });
237   EXPECT_TRUE(callbacks.ping_requested());
238   EXPECT_FALSE(started);
239   EXPECT_FALSE(acked_first);
240   EXPECT_FALSE(acked_second);
241   EXPECT_CALL(event_engine, RunAfter(EventEngine::Duration(Duration::Hours(24)),
242                                      Matcher<absl::AnyInvocable<void()>>(_)))
243       .WillOnce([]() {
244         return EventEngine::TaskHandle{123, 456};
245       });
246   auto id = callbacks.StartPing(bitgen);
247   callbacks.OnPingTimeout(Duration::Hours(24), &event_engine,
248                           [] { Crash("should not reach here"); });
249   EXPECT_FALSE(callbacks.ping_requested());
250   EXPECT_TRUE(started);
251   EXPECT_FALSE(acked_first);
252   EXPECT_FALSE(acked_second);
253   callbacks.OnPingAck([&acked_second] {
254     EXPECT_FALSE(acked_second);
255     acked_second = true;
256   });
257   EXPECT_FALSE(callbacks.ping_requested());
258   EXPECT_TRUE(started);
259   EXPECT_FALSE(acked_first);
260   EXPECT_FALSE(acked_second);
261   EXPECT_CALL(event_engine, Cancel(EventEngine::TaskHandle{123, 456}))
262       .WillOnce(Return(true));
263   EXPECT_TRUE(callbacks.AckPing(id, &event_engine));
264   EXPECT_FALSE(callbacks.ping_requested());
265   EXPECT_TRUE(started);
266   EXPECT_TRUE(acked_first);
267   EXPECT_TRUE(acked_second);
268 }
269 
TEST(PingCallbacksTest,PingAckRoundtrips)270 TEST(PingCallbacksTest, PingAckRoundtrips) {
271   StrictMock<MockEventEngine> event_engine;
272   absl::BitGen bitgen;
273   Chttp2PingCallbacks callbacks;
274   bool acked = false;
275   EXPECT_FALSE(callbacks.ping_requested());
276   callbacks.OnPingAck([&acked] {
277     EXPECT_FALSE(acked);
278     acked = true;
279   });
280   EXPECT_TRUE(callbacks.ping_requested());
281   EXPECT_FALSE(acked);
282   EXPECT_CALL(event_engine, RunAfter(EventEngine::Duration(Duration::Hours(24)),
283                                      Matcher<absl::AnyInvocable<void()>>(_)))
284       .WillOnce([]() {
285         return EventEngine::TaskHandle{123, 456};
286       });
287   auto id = callbacks.StartPing(bitgen);
288   callbacks.OnPingTimeout(Duration::Hours(24), &event_engine,
289                           [] { Crash("should not reach here"); });
290   EXPECT_FALSE(callbacks.ping_requested());
291   EXPECT_FALSE(acked);
292   EXPECT_CALL(event_engine, Cancel(EventEngine::TaskHandle{123, 456}))
293       .WillOnce(Return(true));
294   EXPECT_TRUE(callbacks.AckPing(id, &event_engine));
295   EXPECT_FALSE(callbacks.ping_requested());
296   EXPECT_TRUE(acked);
297 }
298 
TEST(PingCallbacksTest,MultiPingRoundtrips)299 TEST(PingCallbacksTest, MultiPingRoundtrips) {
300   StrictMock<MockEventEngine> event_engine;
301   absl::BitGen bitgen;
302   Chttp2PingCallbacks callbacks;
303   bool started1 = false;
304   bool acked1 = false;
305   bool started2 = false;
306   bool acked2 = false;
307   EXPECT_FALSE(callbacks.ping_requested());
308   callbacks.OnPing(
309       [&started1] {
310         EXPECT_FALSE(started1);
311         started1 = true;
312       },
313       [&acked1] {
314         EXPECT_FALSE(acked1);
315         acked1 = true;
316       });
317   EXPECT_TRUE(callbacks.ping_requested());
318   EXPECT_FALSE(started1);
319   EXPECT_FALSE(acked1);
320   EXPECT_FALSE(started2);
321   EXPECT_FALSE(acked2);
322   EXPECT_CALL(event_engine, RunAfter(EventEngine::Duration(Duration::Hours(24)),
323                                      Matcher<absl::AnyInvocable<void()>>(_)))
324       .WillOnce([]() {
325         return EventEngine::TaskHandle{123, 456};
326       });
327   auto id1 = callbacks.StartPing(bitgen);
328   callbacks.OnPingTimeout(Duration::Hours(24), &event_engine,
329                           [] { Crash("should not reach here"); });
330   EXPECT_FALSE(callbacks.ping_requested());
331   EXPECT_TRUE(started1);
332   EXPECT_FALSE(acked1);
333   EXPECT_FALSE(started2);
334   EXPECT_FALSE(acked2);
335   callbacks.OnPing(
336       [&started2] {
337         EXPECT_FALSE(started2);
338         started2 = true;
339       },
340       [&acked2] {
341         EXPECT_FALSE(acked2);
342         acked2 = true;
343       });
344   EXPECT_TRUE(callbacks.ping_requested());
345   EXPECT_TRUE(started1);
346   EXPECT_FALSE(acked1);
347   EXPECT_FALSE(started2);
348   EXPECT_FALSE(acked2);
349   EXPECT_CALL(event_engine, RunAfter(EventEngine::Duration(Duration::Hours(24)),
350                                      Matcher<absl::AnyInvocable<void()>>(_)))
351       .WillOnce([]() {
352         return EventEngine::TaskHandle{123, 789};
353       });
354   auto id2 = callbacks.StartPing(bitgen);
355   callbacks.OnPingTimeout(Duration::Hours(24), &event_engine,
356                           [] { Crash("should not reach here"); });
357   EXPECT_NE(id1, id2);
358   EXPECT_TRUE(started1);
359   EXPECT_FALSE(acked1);
360   EXPECT_TRUE(started2);
361   EXPECT_FALSE(acked2);
362   EXPECT_CALL(event_engine, Cancel(EventEngine::TaskHandle{123, 456}))
363       .WillOnce(Return(true));
364   EXPECT_TRUE(callbacks.AckPing(id1, &event_engine));
365   EXPECT_FALSE(callbacks.ping_requested());
366   EXPECT_TRUE(started1);
367   EXPECT_TRUE(acked1);
368   EXPECT_TRUE(started2);
369   EXPECT_FALSE(acked2);
370   EXPECT_CALL(event_engine, Cancel(EventEngine::TaskHandle{123, 789}))
371       .WillOnce(Return(true));
372   EXPECT_TRUE(callbacks.AckPing(id2, &event_engine));
373   EXPECT_FALSE(callbacks.ping_requested());
374   EXPECT_TRUE(started1);
375   EXPECT_TRUE(acked1);
376   EXPECT_TRUE(started2);
377   EXPECT_TRUE(acked2);
378 }
379 
TEST(PingCallbacksTest,MultiPingRoundtripsWithOutOfOrderAcks)380 TEST(PingCallbacksTest, MultiPingRoundtripsWithOutOfOrderAcks) {
381   StrictMock<MockEventEngine> event_engine;
382   absl::BitGen bitgen;
383   Chttp2PingCallbacks callbacks;
384   bool started1 = false;
385   bool acked1 = false;
386   bool started2 = false;
387   bool acked2 = false;
388   EXPECT_FALSE(callbacks.ping_requested());
389   callbacks.OnPing(
390       [&started1] {
391         EXPECT_FALSE(started1);
392         started1 = true;
393       },
394       [&acked1] {
395         EXPECT_FALSE(acked1);
396         acked1 = true;
397       });
398   EXPECT_TRUE(callbacks.ping_requested());
399   EXPECT_FALSE(started1);
400   EXPECT_FALSE(acked1);
401   EXPECT_FALSE(started2);
402   EXPECT_FALSE(acked2);
403   EXPECT_CALL(event_engine, RunAfter(EventEngine::Duration(Duration::Hours(24)),
404                                      Matcher<absl::AnyInvocable<void()>>(_)))
405       .WillOnce([]() {
406         return EventEngine::TaskHandle{123, 456};
407       });
408   auto id1 = callbacks.StartPing(bitgen);
409   callbacks.OnPingTimeout(Duration::Hours(24), &event_engine,
410                           [] { Crash("should not reach here"); });
411   EXPECT_FALSE(callbacks.ping_requested());
412   EXPECT_TRUE(started1);
413   EXPECT_FALSE(acked1);
414   EXPECT_FALSE(started2);
415   EXPECT_FALSE(acked2);
416   callbacks.OnPing(
417       [&started2] {
418         EXPECT_FALSE(started2);
419         started2 = true;
420       },
421       [&acked2] {
422         EXPECT_FALSE(acked2);
423         acked2 = true;
424       });
425   EXPECT_TRUE(callbacks.ping_requested());
426   EXPECT_TRUE(started1);
427   EXPECT_FALSE(acked1);
428   EXPECT_FALSE(started2);
429   EXPECT_FALSE(acked2);
430   EXPECT_CALL(event_engine, RunAfter(EventEngine::Duration(Duration::Hours(24)),
431                                      Matcher<absl::AnyInvocable<void()>>(_)))
432       .WillOnce([]() {
433         return EventEngine::TaskHandle{123, 789};
434       });
435   auto id2 = callbacks.StartPing(bitgen);
436   callbacks.OnPingTimeout(Duration::Hours(24), &event_engine,
437                           [] { Crash("should not reach here"); });
438   EXPECT_NE(id1, id2);
439   EXPECT_TRUE(started1);
440   EXPECT_FALSE(acked1);
441   EXPECT_TRUE(started2);
442   EXPECT_FALSE(acked2);
443   EXPECT_CALL(event_engine, Cancel(EventEngine::TaskHandle{123, 789}))
444       .WillOnce(Return(true));
445   EXPECT_TRUE(callbacks.AckPing(id2, &event_engine));
446   EXPECT_FALSE(callbacks.ping_requested());
447   EXPECT_TRUE(started1);
448   EXPECT_FALSE(acked1);
449   EXPECT_TRUE(started2);
450   EXPECT_TRUE(acked2);
451   EXPECT_CALL(event_engine, Cancel(EventEngine::TaskHandle{123, 456}))
452       .WillOnce(Return(true));
453   EXPECT_TRUE(callbacks.AckPing(id1, &event_engine));
454   EXPECT_FALSE(callbacks.ping_requested());
455   EXPECT_TRUE(started1);
456   EXPECT_TRUE(acked1);
457   EXPECT_TRUE(started2);
458   EXPECT_TRUE(acked2);
459 }
460 
TEST(PingCallbacksTest,CoalescedPingsRoundtrip)461 TEST(PingCallbacksTest, CoalescedPingsRoundtrip) {
462   StrictMock<MockEventEngine> event_engine;
463   absl::BitGen bitgen;
464   Chttp2PingCallbacks callbacks;
465   bool started1 = false;
466   bool acked1 = false;
467   bool started2 = false;
468   bool acked2 = false;
469   EXPECT_FALSE(callbacks.ping_requested());
470   callbacks.OnPing(
471       [&started1] {
472         EXPECT_FALSE(started1);
473         started1 = true;
474       },
475       [&acked1] {
476         EXPECT_FALSE(acked1);
477         acked1 = true;
478       });
479   callbacks.OnPing(
480       [&started2] {
481         EXPECT_FALSE(started2);
482         started2 = true;
483       },
484       [&acked2] {
485         EXPECT_FALSE(acked2);
486         acked2 = true;
487       });
488   EXPECT_TRUE(callbacks.ping_requested());
489   EXPECT_FALSE(started1);
490   EXPECT_FALSE(acked1);
491   EXPECT_FALSE(started2);
492   EXPECT_FALSE(acked2);
493   EXPECT_CALL(event_engine, RunAfter(EventEngine::Duration(Duration::Hours(24)),
494                                      Matcher<absl::AnyInvocable<void()>>(_)))
495       .WillOnce([]() {
496         return EventEngine::TaskHandle{123, 456};
497       });
498   auto id = callbacks.StartPing(bitgen);
499   callbacks.OnPingTimeout(Duration::Hours(24), &event_engine,
500                           [] { Crash("should not reach here"); });
501   EXPECT_FALSE(callbacks.ping_requested());
502   EXPECT_TRUE(started1);
503   EXPECT_FALSE(acked1);
504   EXPECT_TRUE(started2);
505   EXPECT_FALSE(acked2);
506   EXPECT_CALL(event_engine, Cancel(EventEngine::TaskHandle{123, 456}))
507       .WillOnce(Return(true));
508   EXPECT_TRUE(callbacks.AckPing(id, &event_engine));
509   EXPECT_FALSE(callbacks.ping_requested());
510   EXPECT_TRUE(started1);
511   EXPECT_TRUE(acked1);
512   EXPECT_TRUE(started2);
513   EXPECT_TRUE(acked2);
514 }
515 
TEST(PingCallbacksTest,CancelAllCancelsCallbacks)516 TEST(PingCallbacksTest, CancelAllCancelsCallbacks) {
517   StrictMock<MockEventEngine> event_engine;
518   absl::BitGen bitgen;
519   Chttp2PingCallbacks callbacks;
520   bool started = false;
521   bool acked = false;
522   EXPECT_FALSE(callbacks.ping_requested());
523   callbacks.OnPing(
524       [&started] {
525         EXPECT_FALSE(started);
526         started = true;
527       },
528       [&acked] {
529         EXPECT_FALSE(acked);
530         acked = true;
531       });
532   EXPECT_TRUE(callbacks.ping_requested());
533   callbacks.CancelAll(&event_engine);
534   EXPECT_FALSE(started);
535   EXPECT_FALSE(acked);
536   EXPECT_FALSE(callbacks.ping_requested());
537   // Can still send a ping, no callback should be invoked
538   EXPECT_CALL(event_engine, RunAfter(EventEngine::Duration(Duration::Hours(24)),
539                                      Matcher<absl::AnyInvocable<void()>>(_)))
540       .WillOnce([]() {
541         return EventEngine::TaskHandle{123, 456};
542       });
543   auto id = callbacks.StartPing(bitgen);
544   callbacks.OnPingTimeout(Duration::Hours(24), &event_engine,
545                           [] { Crash("should not reach here"); });
546   EXPECT_FALSE(started);
547   EXPECT_FALSE(acked);
548   EXPECT_CALL(event_engine, Cancel(EventEngine::TaskHandle{123, 456}))
549       .WillOnce(Return(true));
550   EXPECT_TRUE(callbacks.AckPing(id, &event_engine));
551   EXPECT_FALSE(started);
552   EXPECT_FALSE(acked);
553   EXPECT_FALSE(callbacks.ping_requested());
554 }
555 
TEST(PingCallbacksTest,CancelAllCancelsInflightPings)556 TEST(PingCallbacksTest, CancelAllCancelsInflightPings) {
557   StrictMock<MockEventEngine> event_engine;
558   absl::BitGen bitgen;
559   Chttp2PingCallbacks callbacks;
560   bool started = false;
561   bool acked = false;
562   EXPECT_FALSE(callbacks.ping_requested());
563   callbacks.OnPing(
564       [&started] {
565         EXPECT_FALSE(started);
566         started = true;
567       },
568       [&acked] {
569         EXPECT_FALSE(acked);
570         acked = true;
571       });
572   EXPECT_TRUE(callbacks.ping_requested());
573   EXPECT_FALSE(started);
574   EXPECT_FALSE(acked);
575   EXPECT_CALL(event_engine, RunAfter(EventEngine::Duration(Duration::Hours(24)),
576                                      Matcher<absl::AnyInvocable<void()>>(_)))
577       .WillOnce([]() {
578         return EventEngine::TaskHandle{123, 456};
579       });
580   auto id = callbacks.StartPing(bitgen);
581   callbacks.OnPingTimeout(Duration::Hours(24), &event_engine,
582                           [] { Crash("should not reach here"); });
583   EXPECT_FALSE(callbacks.ping_requested());
584   EXPECT_TRUE(started);
585   EXPECT_FALSE(acked);
586   EXPECT_CALL(event_engine, Cancel(EventEngine::TaskHandle{123, 456}))
587       .WillOnce(Return(true));
588   callbacks.CancelAll(&event_engine);
589   // Ensure Cancel call comes from CancelAll
590   ::testing::Mock::VerifyAndClearExpectations(&event_engine);
591   EXPECT_FALSE(acked);
592   EXPECT_FALSE(callbacks.ping_requested());
593   // Ping should still be valid, but no callback should be invoked
594   EXPECT_TRUE(callbacks.AckPing(id, &event_engine));
595   EXPECT_FALSE(acked);
596   EXPECT_FALSE(callbacks.ping_requested());
597 }
598 
599 }  // namespace
600 }  // namespace grpc_core
601 
main(int argc,char ** argv)602 int main(int argc, char** argv) {
603   ::testing::InitGoogleTest(&argc, argv);
604   return RUN_ALL_TESTS();
605 }
606