xref: /aosp_15_r20/external/webrtc/net/dcsctp/timer/timer_test.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
3*d9f75844SAndroid Build Coastguard Worker  *
4*d9f75844SAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker  */
10*d9f75844SAndroid Build Coastguard Worker #include "net/dcsctp/timer/timer.h"
11*d9f75844SAndroid Build Coastguard Worker 
12*d9f75844SAndroid Build Coastguard Worker #include <memory>
13*d9f75844SAndroid Build Coastguard Worker 
14*d9f75844SAndroid Build Coastguard Worker #include "absl/types/optional.h"
15*d9f75844SAndroid Build Coastguard Worker #include "api/task_queue/task_queue_base.h"
16*d9f75844SAndroid Build Coastguard Worker #include "net/dcsctp/public/timeout.h"
17*d9f75844SAndroid Build Coastguard Worker #include "net/dcsctp/timer/fake_timeout.h"
18*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/gunit.h"
19*d9f75844SAndroid Build Coastguard Worker #include "test/gmock.h"
20*d9f75844SAndroid Build Coastguard Worker 
21*d9f75844SAndroid Build Coastguard Worker namespace dcsctp {
22*d9f75844SAndroid Build Coastguard Worker namespace {
23*d9f75844SAndroid Build Coastguard Worker using ::testing::Return;
24*d9f75844SAndroid Build Coastguard Worker 
25*d9f75844SAndroid Build Coastguard Worker class TimerTest : public testing::Test {
26*d9f75844SAndroid Build Coastguard Worker  protected:
TimerTest()27*d9f75844SAndroid Build Coastguard Worker   TimerTest()
28*d9f75844SAndroid Build Coastguard Worker       : timeout_manager_([this]() { return now_; }),
__anon4d5868470302(webrtc::TaskQueueBase::DelayPrecision precision) 29*d9f75844SAndroid Build Coastguard Worker         manager_([this](webrtc::TaskQueueBase::DelayPrecision precision) {
30*d9f75844SAndroid Build Coastguard Worker           return timeout_manager_.CreateTimeout(precision);
31*d9f75844SAndroid Build Coastguard Worker         }) {
32*d9f75844SAndroid Build Coastguard Worker     ON_CALL(on_expired_, Call).WillByDefault(Return(absl::nullopt));
33*d9f75844SAndroid Build Coastguard Worker   }
34*d9f75844SAndroid Build Coastguard Worker 
AdvanceTimeAndRunTimers(DurationMs duration)35*d9f75844SAndroid Build Coastguard Worker   void AdvanceTimeAndRunTimers(DurationMs duration) {
36*d9f75844SAndroid Build Coastguard Worker     now_ = now_ + duration;
37*d9f75844SAndroid Build Coastguard Worker 
38*d9f75844SAndroid Build Coastguard Worker     for (;;) {
39*d9f75844SAndroid Build Coastguard Worker       absl::optional<TimeoutID> timeout_id =
40*d9f75844SAndroid Build Coastguard Worker           timeout_manager_.GetNextExpiredTimeout();
41*d9f75844SAndroid Build Coastguard Worker       if (!timeout_id.has_value()) {
42*d9f75844SAndroid Build Coastguard Worker         break;
43*d9f75844SAndroid Build Coastguard Worker       }
44*d9f75844SAndroid Build Coastguard Worker       manager_.HandleTimeout(*timeout_id);
45*d9f75844SAndroid Build Coastguard Worker     }
46*d9f75844SAndroid Build Coastguard Worker   }
47*d9f75844SAndroid Build Coastguard Worker 
48*d9f75844SAndroid Build Coastguard Worker   TimeMs now_ = TimeMs(0);
49*d9f75844SAndroid Build Coastguard Worker   FakeTimeoutManager timeout_manager_;
50*d9f75844SAndroid Build Coastguard Worker   TimerManager manager_;
51*d9f75844SAndroid Build Coastguard Worker   testing::MockFunction<absl::optional<DurationMs>()> on_expired_;
52*d9f75844SAndroid Build Coastguard Worker };
53*d9f75844SAndroid Build Coastguard Worker 
TEST_F(TimerTest,TimerIsInitiallyStopped)54*d9f75844SAndroid Build Coastguard Worker TEST_F(TimerTest, TimerIsInitiallyStopped) {
55*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<Timer> t1 = manager_.CreateTimer(
56*d9f75844SAndroid Build Coastguard Worker       "t1", on_expired_.AsStdFunction(),
57*d9f75844SAndroid Build Coastguard Worker       TimerOptions(DurationMs(5000), TimerBackoffAlgorithm::kFixed));
58*d9f75844SAndroid Build Coastguard Worker 
59*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(t1->is_running());
60*d9f75844SAndroid Build Coastguard Worker }
61*d9f75844SAndroid Build Coastguard Worker 
TEST_F(TimerTest,TimerExpiresAtGivenTime)62*d9f75844SAndroid Build Coastguard Worker TEST_F(TimerTest, TimerExpiresAtGivenTime) {
63*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<Timer> t1 = manager_.CreateTimer(
64*d9f75844SAndroid Build Coastguard Worker       "t1", on_expired_.AsStdFunction(),
65*d9f75844SAndroid Build Coastguard Worker       TimerOptions(DurationMs(5000), TimerBackoffAlgorithm::kFixed));
66*d9f75844SAndroid Build Coastguard Worker 
67*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(0);
68*d9f75844SAndroid Build Coastguard Worker   t1->Start();
69*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(t1->is_running());
70*d9f75844SAndroid Build Coastguard Worker 
71*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(4000));
72*d9f75844SAndroid Build Coastguard Worker 
73*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(1);
74*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(1000));
75*d9f75844SAndroid Build Coastguard Worker }
76*d9f75844SAndroid Build Coastguard Worker 
TEST_F(TimerTest,TimerReschedulesAfterExpiredWithFixedBackoff)77*d9f75844SAndroid Build Coastguard Worker TEST_F(TimerTest, TimerReschedulesAfterExpiredWithFixedBackoff) {
78*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<Timer> t1 = manager_.CreateTimer(
79*d9f75844SAndroid Build Coastguard Worker       "t1", on_expired_.AsStdFunction(),
80*d9f75844SAndroid Build Coastguard Worker       TimerOptions(DurationMs(5000), TimerBackoffAlgorithm::kFixed));
81*d9f75844SAndroid Build Coastguard Worker 
82*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(0);
83*d9f75844SAndroid Build Coastguard Worker   t1->Start();
84*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(t1->expiration_count(), 0);
85*d9f75844SAndroid Build Coastguard Worker 
86*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(4000));
87*d9f75844SAndroid Build Coastguard Worker 
88*d9f75844SAndroid Build Coastguard Worker   // Fire first time
89*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(1);
90*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(1000));
91*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(t1->is_running());
92*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(t1->expiration_count(), 1);
93*d9f75844SAndroid Build Coastguard Worker 
94*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(0);
95*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(4000));
96*d9f75844SAndroid Build Coastguard Worker 
97*d9f75844SAndroid Build Coastguard Worker   // Second time
98*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(1);
99*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(1000));
100*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(t1->is_running());
101*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(t1->expiration_count(), 2);
102*d9f75844SAndroid Build Coastguard Worker 
103*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(0);
104*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(4000));
105*d9f75844SAndroid Build Coastguard Worker 
106*d9f75844SAndroid Build Coastguard Worker   // Third time
107*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(1);
108*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(1000));
109*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(t1->is_running());
110*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(t1->expiration_count(), 3);
111*d9f75844SAndroid Build Coastguard Worker }
112*d9f75844SAndroid Build Coastguard Worker 
TEST_F(TimerTest,TimerWithNoRestarts)113*d9f75844SAndroid Build Coastguard Worker TEST_F(TimerTest, TimerWithNoRestarts) {
114*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<Timer> t1 = manager_.CreateTimer(
115*d9f75844SAndroid Build Coastguard Worker       "t1", on_expired_.AsStdFunction(),
116*d9f75844SAndroid Build Coastguard Worker       TimerOptions(DurationMs(5000), TimerBackoffAlgorithm::kFixed,
117*d9f75844SAndroid Build Coastguard Worker                    /*max_restart=*/0));
118*d9f75844SAndroid Build Coastguard Worker 
119*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(0);
120*d9f75844SAndroid Build Coastguard Worker   t1->Start();
121*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(4000));
122*d9f75844SAndroid Build Coastguard Worker 
123*d9f75844SAndroid Build Coastguard Worker   // Fire first time
124*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(1);
125*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(1000));
126*d9f75844SAndroid Build Coastguard Worker 
127*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(t1->is_running());
128*d9f75844SAndroid Build Coastguard Worker 
129*d9f75844SAndroid Build Coastguard Worker   // Second time - shouldn't fire
130*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(0);
131*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(5000));
132*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(t1->is_running());
133*d9f75844SAndroid Build Coastguard Worker }
134*d9f75844SAndroid Build Coastguard Worker 
TEST_F(TimerTest,TimerWithOneRestart)135*d9f75844SAndroid Build Coastguard Worker TEST_F(TimerTest, TimerWithOneRestart) {
136*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<Timer> t1 = manager_.CreateTimer(
137*d9f75844SAndroid Build Coastguard Worker       "t1", on_expired_.AsStdFunction(),
138*d9f75844SAndroid Build Coastguard Worker       TimerOptions(DurationMs(5000), TimerBackoffAlgorithm::kFixed,
139*d9f75844SAndroid Build Coastguard Worker                    /*max_restart=*/1));
140*d9f75844SAndroid Build Coastguard Worker 
141*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(0);
142*d9f75844SAndroid Build Coastguard Worker   t1->Start();
143*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(4000));
144*d9f75844SAndroid Build Coastguard Worker 
145*d9f75844SAndroid Build Coastguard Worker   // Fire first time
146*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(1);
147*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(1000));
148*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(t1->is_running());
149*d9f75844SAndroid Build Coastguard Worker 
150*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(0);
151*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(4000));
152*d9f75844SAndroid Build Coastguard Worker 
153*d9f75844SAndroid Build Coastguard Worker   // Second time - max restart limit reached.
154*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(1);
155*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(1000));
156*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(t1->is_running());
157*d9f75844SAndroid Build Coastguard Worker 
158*d9f75844SAndroid Build Coastguard Worker   // Third time - should not fire.
159*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(0);
160*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(5000));
161*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(t1->is_running());
162*d9f75844SAndroid Build Coastguard Worker }
163*d9f75844SAndroid Build Coastguard Worker 
TEST_F(TimerTest,TimerWithTwoRestart)164*d9f75844SAndroid Build Coastguard Worker TEST_F(TimerTest, TimerWithTwoRestart) {
165*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<Timer> t1 = manager_.CreateTimer(
166*d9f75844SAndroid Build Coastguard Worker       "t1", on_expired_.AsStdFunction(),
167*d9f75844SAndroid Build Coastguard Worker       TimerOptions(DurationMs(5000), TimerBackoffAlgorithm::kFixed,
168*d9f75844SAndroid Build Coastguard Worker                    /*max_restart=*/2));
169*d9f75844SAndroid Build Coastguard Worker 
170*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(0);
171*d9f75844SAndroid Build Coastguard Worker   t1->Start();
172*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(4000));
173*d9f75844SAndroid Build Coastguard Worker 
174*d9f75844SAndroid Build Coastguard Worker   // Fire first time
175*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(1);
176*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(1000));
177*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(t1->is_running());
178*d9f75844SAndroid Build Coastguard Worker 
179*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(0);
180*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(4000));
181*d9f75844SAndroid Build Coastguard Worker 
182*d9f75844SAndroid Build Coastguard Worker   // Second time
183*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(1);
184*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(1000));
185*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(t1->is_running());
186*d9f75844SAndroid Build Coastguard Worker 
187*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(0);
188*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(4000));
189*d9f75844SAndroid Build Coastguard Worker 
190*d9f75844SAndroid Build Coastguard Worker   // Third time
191*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(1);
192*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(1000));
193*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(t1->is_running());
194*d9f75844SAndroid Build Coastguard Worker }
195*d9f75844SAndroid Build Coastguard Worker 
TEST_F(TimerTest,TimerWithExponentialBackoff)196*d9f75844SAndroid Build Coastguard Worker TEST_F(TimerTest, TimerWithExponentialBackoff) {
197*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<Timer> t1 = manager_.CreateTimer(
198*d9f75844SAndroid Build Coastguard Worker       "t1", on_expired_.AsStdFunction(),
199*d9f75844SAndroid Build Coastguard Worker       TimerOptions(DurationMs(5000), TimerBackoffAlgorithm::kExponential));
200*d9f75844SAndroid Build Coastguard Worker 
201*d9f75844SAndroid Build Coastguard Worker   t1->Start();
202*d9f75844SAndroid Build Coastguard Worker 
203*d9f75844SAndroid Build Coastguard Worker   // Fire first time at 5 seconds
204*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(1);
205*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(5000));
206*d9f75844SAndroid Build Coastguard Worker 
207*d9f75844SAndroid Build Coastguard Worker   // Second time at 5*2^1 = 10 seconds later.
208*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(0);
209*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(9000));
210*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(1);
211*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(1000));
212*d9f75844SAndroid Build Coastguard Worker 
213*d9f75844SAndroid Build Coastguard Worker   // Third time at 5*2^2 = 20 seconds later.
214*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(0);
215*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(19000));
216*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(1);
217*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(1000));
218*d9f75844SAndroid Build Coastguard Worker 
219*d9f75844SAndroid Build Coastguard Worker   // Fourth time at 5*2^3 = 40 seconds later.
220*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(0);
221*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(39000));
222*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(1);
223*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(1000));
224*d9f75844SAndroid Build Coastguard Worker }
225*d9f75844SAndroid Build Coastguard Worker 
TEST_F(TimerTest,StartTimerWillStopAndStart)226*d9f75844SAndroid Build Coastguard Worker TEST_F(TimerTest, StartTimerWillStopAndStart) {
227*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<Timer> t1 = manager_.CreateTimer(
228*d9f75844SAndroid Build Coastguard Worker       "t1", on_expired_.AsStdFunction(),
229*d9f75844SAndroid Build Coastguard Worker       TimerOptions(DurationMs(5000), TimerBackoffAlgorithm::kExponential));
230*d9f75844SAndroid Build Coastguard Worker 
231*d9f75844SAndroid Build Coastguard Worker   t1->Start();
232*d9f75844SAndroid Build Coastguard Worker 
233*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(3000));
234*d9f75844SAndroid Build Coastguard Worker 
235*d9f75844SAndroid Build Coastguard Worker   t1->Start();
236*d9f75844SAndroid Build Coastguard Worker 
237*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(0);
238*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(2000));
239*d9f75844SAndroid Build Coastguard Worker 
240*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(1);
241*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(3000));
242*d9f75844SAndroid Build Coastguard Worker }
243*d9f75844SAndroid Build Coastguard Worker 
TEST_F(TimerTest,ExpirationCounterWillResetIfStopped)244*d9f75844SAndroid Build Coastguard Worker TEST_F(TimerTest, ExpirationCounterWillResetIfStopped) {
245*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<Timer> t1 = manager_.CreateTimer(
246*d9f75844SAndroid Build Coastguard Worker       "t1", on_expired_.AsStdFunction(),
247*d9f75844SAndroid Build Coastguard Worker       TimerOptions(DurationMs(5000), TimerBackoffAlgorithm::kExponential));
248*d9f75844SAndroid Build Coastguard Worker 
249*d9f75844SAndroid Build Coastguard Worker   t1->Start();
250*d9f75844SAndroid Build Coastguard Worker 
251*d9f75844SAndroid Build Coastguard Worker   // Fire first time at 5 seconds
252*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(1);
253*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(5000));
254*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(t1->expiration_count(), 1);
255*d9f75844SAndroid Build Coastguard Worker 
256*d9f75844SAndroid Build Coastguard Worker   // Second time at 5*2^1 = 10 seconds later.
257*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(0);
258*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(9000));
259*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(1);
260*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(1000));
261*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(t1->expiration_count(), 2);
262*d9f75844SAndroid Build Coastguard Worker 
263*d9f75844SAndroid Build Coastguard Worker   t1->Start();
264*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(t1->expiration_count(), 0);
265*d9f75844SAndroid Build Coastguard Worker 
266*d9f75844SAndroid Build Coastguard Worker   // Third time at 5*2^0 = 5 seconds later.
267*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(0);
268*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(4000));
269*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(1);
270*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(1000));
271*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(t1->expiration_count(), 1);
272*d9f75844SAndroid Build Coastguard Worker }
273*d9f75844SAndroid Build Coastguard Worker 
TEST_F(TimerTest,StopTimerWillMakeItNotExpire)274*d9f75844SAndroid Build Coastguard Worker TEST_F(TimerTest, StopTimerWillMakeItNotExpire) {
275*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<Timer> t1 = manager_.CreateTimer(
276*d9f75844SAndroid Build Coastguard Worker       "t1", on_expired_.AsStdFunction(),
277*d9f75844SAndroid Build Coastguard Worker       TimerOptions(DurationMs(5000), TimerBackoffAlgorithm::kExponential));
278*d9f75844SAndroid Build Coastguard Worker 
279*d9f75844SAndroid Build Coastguard Worker   t1->Start();
280*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(t1->is_running());
281*d9f75844SAndroid Build Coastguard Worker 
282*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(0);
283*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(4000));
284*d9f75844SAndroid Build Coastguard Worker   t1->Stop();
285*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(t1->is_running());
286*d9f75844SAndroid Build Coastguard Worker 
287*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(0);
288*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(1000));
289*d9f75844SAndroid Build Coastguard Worker }
290*d9f75844SAndroid Build Coastguard Worker 
TEST_F(TimerTest,ReturningNewDurationWhenExpired)291*d9f75844SAndroid Build Coastguard Worker TEST_F(TimerTest, ReturningNewDurationWhenExpired) {
292*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<Timer> t1 = manager_.CreateTimer(
293*d9f75844SAndroid Build Coastguard Worker       "t1", on_expired_.AsStdFunction(),
294*d9f75844SAndroid Build Coastguard Worker       TimerOptions(DurationMs(5000), TimerBackoffAlgorithm::kFixed));
295*d9f75844SAndroid Build Coastguard Worker 
296*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(0);
297*d9f75844SAndroid Build Coastguard Worker   t1->Start();
298*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(t1->duration(), DurationMs(5000));
299*d9f75844SAndroid Build Coastguard Worker 
300*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(4000));
301*d9f75844SAndroid Build Coastguard Worker 
302*d9f75844SAndroid Build Coastguard Worker   // Fire first time
303*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).WillOnce(Return(DurationMs(2000)));
304*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(1000));
305*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(t1->duration(), DurationMs(2000));
306*d9f75844SAndroid Build Coastguard Worker 
307*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(0);
308*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(1000));
309*d9f75844SAndroid Build Coastguard Worker 
310*d9f75844SAndroid Build Coastguard Worker   // Second time
311*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).WillOnce(Return(DurationMs(10000)));
312*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(1000));
313*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(t1->duration(), DurationMs(10000));
314*d9f75844SAndroid Build Coastguard Worker 
315*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(0);
316*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(9000));
317*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(1);
318*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(1000));
319*d9f75844SAndroid Build Coastguard Worker }
320*d9f75844SAndroid Build Coastguard Worker 
TEST_F(TimerTest,TimersHaveMaximumDuration)321*d9f75844SAndroid Build Coastguard Worker TEST_F(TimerTest, TimersHaveMaximumDuration) {
322*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<Timer> t1 = manager_.CreateTimer(
323*d9f75844SAndroid Build Coastguard Worker       "t1", on_expired_.AsStdFunction(),
324*d9f75844SAndroid Build Coastguard Worker       TimerOptions(DurationMs(1000), TimerBackoffAlgorithm::kExponential));
325*d9f75844SAndroid Build Coastguard Worker 
326*d9f75844SAndroid Build Coastguard Worker   t1->set_duration(DurationMs(2 * *Timer::kMaxTimerDuration));
327*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(t1->duration(), Timer::kMaxTimerDuration);
328*d9f75844SAndroid Build Coastguard Worker }
329*d9f75844SAndroid Build Coastguard Worker 
TEST_F(TimerTest,TimersHaveMaximumBackoffDuration)330*d9f75844SAndroid Build Coastguard Worker TEST_F(TimerTest, TimersHaveMaximumBackoffDuration) {
331*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<Timer> t1 = manager_.CreateTimer(
332*d9f75844SAndroid Build Coastguard Worker       "t1", on_expired_.AsStdFunction(),
333*d9f75844SAndroid Build Coastguard Worker       TimerOptions(DurationMs(1000), TimerBackoffAlgorithm::kExponential));
334*d9f75844SAndroid Build Coastguard Worker 
335*d9f75844SAndroid Build Coastguard Worker   t1->Start();
336*d9f75844SAndroid Build Coastguard Worker 
337*d9f75844SAndroid Build Coastguard Worker   int max_exponent = static_cast<int>(log2(*Timer::kMaxTimerDuration / 1000));
338*d9f75844SAndroid Build Coastguard Worker   for (int i = 0; i < max_exponent; ++i) {
339*d9f75844SAndroid Build Coastguard Worker     EXPECT_CALL(on_expired_, Call).Times(1);
340*d9f75844SAndroid Build Coastguard Worker     AdvanceTimeAndRunTimers(DurationMs(1000 * (1 << i)));
341*d9f75844SAndroid Build Coastguard Worker   }
342*d9f75844SAndroid Build Coastguard Worker 
343*d9f75844SAndroid Build Coastguard Worker   // Reached the maximum duration.
344*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(1);
345*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(Timer::kMaxTimerDuration);
346*d9f75844SAndroid Build Coastguard Worker 
347*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(1);
348*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(Timer::kMaxTimerDuration);
349*d9f75844SAndroid Build Coastguard Worker 
350*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(1);
351*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(Timer::kMaxTimerDuration);
352*d9f75844SAndroid Build Coastguard Worker 
353*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(1);
354*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(Timer::kMaxTimerDuration);
355*d9f75844SAndroid Build Coastguard Worker }
356*d9f75844SAndroid Build Coastguard Worker 
TEST_F(TimerTest,TimerCanBeStartedFromWithinExpirationHandler)357*d9f75844SAndroid Build Coastguard Worker TEST_F(TimerTest, TimerCanBeStartedFromWithinExpirationHandler) {
358*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<Timer> t1 = manager_.CreateTimer(
359*d9f75844SAndroid Build Coastguard Worker       "t1", on_expired_.AsStdFunction(),
360*d9f75844SAndroid Build Coastguard Worker       TimerOptions(DurationMs(1000), TimerBackoffAlgorithm::kFixed));
361*d9f75844SAndroid Build Coastguard Worker 
362*d9f75844SAndroid Build Coastguard Worker   t1->Start();
363*d9f75844SAndroid Build Coastguard Worker 
364*d9f75844SAndroid Build Coastguard Worker   // Start a timer, but don't return any new duration in callback.
365*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).WillOnce([&]() {
366*d9f75844SAndroid Build Coastguard Worker     EXPECT_TRUE(t1->is_running());
367*d9f75844SAndroid Build Coastguard Worker     t1->set_duration(DurationMs(5000));
368*d9f75844SAndroid Build Coastguard Worker     t1->Start();
369*d9f75844SAndroid Build Coastguard Worker     return absl::nullopt;
370*d9f75844SAndroid Build Coastguard Worker   });
371*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(1000));
372*d9f75844SAndroid Build Coastguard Worker 
373*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(0);
374*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(4999));
375*d9f75844SAndroid Build Coastguard Worker 
376*d9f75844SAndroid Build Coastguard Worker   // Start a timer, and return any new duration in callback.
377*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).WillOnce([&]() {
378*d9f75844SAndroid Build Coastguard Worker     EXPECT_TRUE(t1->is_running());
379*d9f75844SAndroid Build Coastguard Worker     t1->set_duration(DurationMs(5000));
380*d9f75844SAndroid Build Coastguard Worker     t1->Start();
381*d9f75844SAndroid Build Coastguard Worker     return absl::make_optional(DurationMs(8000));
382*d9f75844SAndroid Build Coastguard Worker   });
383*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(1));
384*d9f75844SAndroid Build Coastguard Worker 
385*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(0);
386*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(7999));
387*d9f75844SAndroid Build Coastguard Worker 
388*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(1);
389*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(1));
390*d9f75844SAndroid Build Coastguard Worker }
391*d9f75844SAndroid Build Coastguard Worker 
TEST_F(TimerTest,DurationStaysWithinMaxTimerBackOffDuration)392*d9f75844SAndroid Build Coastguard Worker TEST_F(TimerTest, DurationStaysWithinMaxTimerBackOffDuration) {
393*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<Timer> t1 = manager_.CreateTimer(
394*d9f75844SAndroid Build Coastguard Worker       "t1", on_expired_.AsStdFunction(),
395*d9f75844SAndroid Build Coastguard Worker       TimerOptions(DurationMs(1000), TimerBackoffAlgorithm::kExponential,
396*d9f75844SAndroid Build Coastguard Worker                    /*max_restarts=*/absl::nullopt, DurationMs(5000)));
397*d9f75844SAndroid Build Coastguard Worker 
398*d9f75844SAndroid Build Coastguard Worker   t1->Start();
399*d9f75844SAndroid Build Coastguard Worker 
400*d9f75844SAndroid Build Coastguard Worker   // Initial timeout, 1000 ms
401*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(1);
402*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(1000));
403*d9f75844SAndroid Build Coastguard Worker 
404*d9f75844SAndroid Build Coastguard Worker   // Exponential backoff -> 2000 ms
405*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(0);
406*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(1999));
407*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(1);
408*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(1));
409*d9f75844SAndroid Build Coastguard Worker 
410*d9f75844SAndroid Build Coastguard Worker   // Exponential backoff -> 4000 ms
411*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(0);
412*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(3999));
413*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(1);
414*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(1));
415*d9f75844SAndroid Build Coastguard Worker 
416*d9f75844SAndroid Build Coastguard Worker   // Limited backoff -> 5000ms
417*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(0);
418*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(4999));
419*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(1);
420*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(1));
421*d9f75844SAndroid Build Coastguard Worker 
422*d9f75844SAndroid Build Coastguard Worker   // ... where it plateaus
423*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(0);
424*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(4999));
425*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(on_expired_, Call).Times(1);
426*d9f75844SAndroid Build Coastguard Worker   AdvanceTimeAndRunTimers(DurationMs(1));
427*d9f75844SAndroid Build Coastguard Worker }
428*d9f75844SAndroid Build Coastguard Worker 
TEST(TimerManagerTest,TimerManagerPassesPrecisionToCreateTimeoutMethod)429*d9f75844SAndroid Build Coastguard Worker TEST(TimerManagerTest, TimerManagerPassesPrecisionToCreateTimeoutMethod) {
430*d9f75844SAndroid Build Coastguard Worker   FakeTimeoutManager timeout_manager([&]() { return TimeMs(0); });
431*d9f75844SAndroid Build Coastguard Worker   absl::optional<webrtc::TaskQueueBase::DelayPrecision> create_timer_precison;
432*d9f75844SAndroid Build Coastguard Worker   TimerManager manager([&](webrtc::TaskQueueBase::DelayPrecision precision) {
433*d9f75844SAndroid Build Coastguard Worker     create_timer_precison = precision;
434*d9f75844SAndroid Build Coastguard Worker     return timeout_manager.CreateTimeout(precision);
435*d9f75844SAndroid Build Coastguard Worker   });
436*d9f75844SAndroid Build Coastguard Worker   // Default TimerOptions.
437*d9f75844SAndroid Build Coastguard Worker   manager.CreateTimer(
438*d9f75844SAndroid Build Coastguard Worker       "test_timer", []() { return absl::optional<DurationMs>(); },
439*d9f75844SAndroid Build Coastguard Worker       TimerOptions(DurationMs(123)));
440*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(create_timer_precison, webrtc::TaskQueueBase::DelayPrecision::kLow);
441*d9f75844SAndroid Build Coastguard Worker   // High precision TimerOptions.
442*d9f75844SAndroid Build Coastguard Worker   manager.CreateTimer(
443*d9f75844SAndroid Build Coastguard Worker       "test_timer", []() { return absl::optional<DurationMs>(); },
444*d9f75844SAndroid Build Coastguard Worker       TimerOptions(DurationMs(123), TimerBackoffAlgorithm::kExponential,
445*d9f75844SAndroid Build Coastguard Worker                    absl::nullopt, absl::nullopt,
446*d9f75844SAndroid Build Coastguard Worker                    webrtc::TaskQueueBase::DelayPrecision::kHigh));
447*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(create_timer_precison,
448*d9f75844SAndroid Build Coastguard Worker             webrtc::TaskQueueBase::DelayPrecision::kHigh);
449*d9f75844SAndroid Build Coastguard Worker   // Low precision TimerOptions.
450*d9f75844SAndroid Build Coastguard Worker   manager.CreateTimer(
451*d9f75844SAndroid Build Coastguard Worker       "test_timer", []() { return absl::optional<DurationMs>(); },
452*d9f75844SAndroid Build Coastguard Worker       TimerOptions(DurationMs(123), TimerBackoffAlgorithm::kExponential,
453*d9f75844SAndroid Build Coastguard Worker                    absl::nullopt, absl::nullopt,
454*d9f75844SAndroid Build Coastguard Worker                    webrtc::TaskQueueBase::DelayPrecision::kLow));
455*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(create_timer_precison, webrtc::TaskQueueBase::DelayPrecision::kLow);
456*d9f75844SAndroid Build Coastguard Worker }
457*d9f75844SAndroid Build Coastguard Worker 
458*d9f75844SAndroid Build Coastguard Worker }  // namespace
459*d9f75844SAndroid Build Coastguard Worker }  // namespace dcsctp
460