xref: /aosp_15_r20/external/cronet/net/base/backoff_entry_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "net/base/backoff_entry.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include "base/time/tick_clock.h"
8*6777b538SAndroid Build Coastguard Worker #include "base/time/time.h"
9*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
10*6777b538SAndroid Build Coastguard Worker 
11*6777b538SAndroid Build Coastguard Worker namespace net {
12*6777b538SAndroid Build Coastguard Worker 
13*6777b538SAndroid Build Coastguard Worker namespace {
14*6777b538SAndroid Build Coastguard Worker 
15*6777b538SAndroid Build Coastguard Worker using base::TimeTicks;
16*6777b538SAndroid Build Coastguard Worker 
17*6777b538SAndroid Build Coastguard Worker BackoffEntry::Policy base_policy = { 0, 1000, 2.0, 0.0, 20000, 2000, false };
18*6777b538SAndroid Build Coastguard Worker 
19*6777b538SAndroid Build Coastguard Worker class TestTickClock : public base::TickClock {
20*6777b538SAndroid Build Coastguard Worker  public:
21*6777b538SAndroid Build Coastguard Worker   TestTickClock() = default;
22*6777b538SAndroid Build Coastguard Worker   TestTickClock(const TestTickClock&) = delete;
23*6777b538SAndroid Build Coastguard Worker   TestTickClock& operator=(const TestTickClock&) = delete;
24*6777b538SAndroid Build Coastguard Worker   ~TestTickClock() override = default;
25*6777b538SAndroid Build Coastguard Worker 
NowTicks() const26*6777b538SAndroid Build Coastguard Worker   TimeTicks NowTicks() const override { return now_ticks_; }
set_now(TimeTicks now)27*6777b538SAndroid Build Coastguard Worker   void set_now(TimeTicks now) { now_ticks_ = now; }
28*6777b538SAndroid Build Coastguard Worker 
29*6777b538SAndroid Build Coastguard Worker  private:
30*6777b538SAndroid Build Coastguard Worker   TimeTicks now_ticks_;
31*6777b538SAndroid Build Coastguard Worker };
32*6777b538SAndroid Build Coastguard Worker 
TEST(BackoffEntryTest,BaseTest)33*6777b538SAndroid Build Coastguard Worker TEST(BackoffEntryTest, BaseTest) {
34*6777b538SAndroid Build Coastguard Worker   TestTickClock now_ticks;
35*6777b538SAndroid Build Coastguard Worker   BackoffEntry entry(&base_policy, &now_ticks);
36*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(entry.ShouldRejectRequest());
37*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(base::TimeDelta(), entry.GetTimeUntilRelease());
38*6777b538SAndroid Build Coastguard Worker 
39*6777b538SAndroid Build Coastguard Worker   entry.InformOfRequest(false);
40*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(entry.ShouldRejectRequest());
41*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(base::Milliseconds(1000), entry.GetTimeUntilRelease());
42*6777b538SAndroid Build Coastguard Worker }
43*6777b538SAndroid Build Coastguard Worker 
TEST(BackoffEntryTest,CanDiscardNeverExpires)44*6777b538SAndroid Build Coastguard Worker TEST(BackoffEntryTest, CanDiscardNeverExpires) {
45*6777b538SAndroid Build Coastguard Worker   BackoffEntry::Policy never_expires_policy = base_policy;
46*6777b538SAndroid Build Coastguard Worker   never_expires_policy.entry_lifetime_ms = -1;
47*6777b538SAndroid Build Coastguard Worker   TestTickClock now_ticks;
48*6777b538SAndroid Build Coastguard Worker   BackoffEntry never_expires(&never_expires_policy, &now_ticks);
49*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(never_expires.CanDiscard());
50*6777b538SAndroid Build Coastguard Worker   now_ticks.set_now(TimeTicks() + base::Days(100));
51*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(never_expires.CanDiscard());
52*6777b538SAndroid Build Coastguard Worker }
53*6777b538SAndroid Build Coastguard Worker 
TEST(BackoffEntryTest,CanDiscard)54*6777b538SAndroid Build Coastguard Worker TEST(BackoffEntryTest, CanDiscard) {
55*6777b538SAndroid Build Coastguard Worker   TestTickClock now_ticks;
56*6777b538SAndroid Build Coastguard Worker   BackoffEntry entry(&base_policy, &now_ticks);
57*6777b538SAndroid Build Coastguard Worker   // Because lifetime is non-zero, we shouldn't be able to discard yet.
58*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(entry.CanDiscard());
59*6777b538SAndroid Build Coastguard Worker 
60*6777b538SAndroid Build Coastguard Worker   // Test the "being used" case.
61*6777b538SAndroid Build Coastguard Worker   entry.InformOfRequest(false);
62*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(entry.CanDiscard());
63*6777b538SAndroid Build Coastguard Worker 
64*6777b538SAndroid Build Coastguard Worker   // Test the case where there are errors but we can time out.
65*6777b538SAndroid Build Coastguard Worker   now_ticks.set_now(entry.GetReleaseTime() + base::Milliseconds(1));
66*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(entry.CanDiscard());
67*6777b538SAndroid Build Coastguard Worker   now_ticks.set_now(entry.GetReleaseTime() +
68*6777b538SAndroid Build Coastguard Worker                     base::Milliseconds(base_policy.maximum_backoff_ms + 1));
69*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(entry.CanDiscard());
70*6777b538SAndroid Build Coastguard Worker 
71*6777b538SAndroid Build Coastguard Worker   // Test the final case (no errors, dependent only on specified lifetime).
72*6777b538SAndroid Build Coastguard Worker   now_ticks.set_now(entry.GetReleaseTime() +
73*6777b538SAndroid Build Coastguard Worker                     base::Milliseconds(base_policy.entry_lifetime_ms - 1));
74*6777b538SAndroid Build Coastguard Worker   entry.InformOfRequest(true);
75*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(entry.CanDiscard());
76*6777b538SAndroid Build Coastguard Worker   now_ticks.set_now(entry.GetReleaseTime() +
77*6777b538SAndroid Build Coastguard Worker                     base::Milliseconds(base_policy.entry_lifetime_ms));
78*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(entry.CanDiscard());
79*6777b538SAndroid Build Coastguard Worker }
80*6777b538SAndroid Build Coastguard Worker 
TEST(BackoffEntryTest,CanDiscardAlwaysDelay)81*6777b538SAndroid Build Coastguard Worker TEST(BackoffEntryTest, CanDiscardAlwaysDelay) {
82*6777b538SAndroid Build Coastguard Worker   BackoffEntry::Policy always_delay_policy = base_policy;
83*6777b538SAndroid Build Coastguard Worker   always_delay_policy.always_use_initial_delay = true;
84*6777b538SAndroid Build Coastguard Worker   always_delay_policy.entry_lifetime_ms = 0;
85*6777b538SAndroid Build Coastguard Worker 
86*6777b538SAndroid Build Coastguard Worker   TestTickClock now_ticks;
87*6777b538SAndroid Build Coastguard Worker   BackoffEntry entry(&always_delay_policy, &now_ticks);
88*6777b538SAndroid Build Coastguard Worker 
89*6777b538SAndroid Build Coastguard Worker   // Because lifetime is non-zero, we shouldn't be able to discard yet.
90*6777b538SAndroid Build Coastguard Worker   now_ticks.set_now(entry.GetReleaseTime() + base::Milliseconds(2000));
91*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(entry.CanDiscard());
92*6777b538SAndroid Build Coastguard Worker 
93*6777b538SAndroid Build Coastguard Worker   // Even with no failures, we wait until the delay before we allow discard.
94*6777b538SAndroid Build Coastguard Worker   entry.InformOfRequest(true);
95*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(entry.CanDiscard());
96*6777b538SAndroid Build Coastguard Worker 
97*6777b538SAndroid Build Coastguard Worker   // Wait until the delay expires, and we can discard the entry again.
98*6777b538SAndroid Build Coastguard Worker   now_ticks.set_now(entry.GetReleaseTime() + base::Milliseconds(1000));
99*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(entry.CanDiscard());
100*6777b538SAndroid Build Coastguard Worker }
101*6777b538SAndroid Build Coastguard Worker 
TEST(BackoffEntryTest,CanDiscardNotStored)102*6777b538SAndroid Build Coastguard Worker TEST(BackoffEntryTest, CanDiscardNotStored) {
103*6777b538SAndroid Build Coastguard Worker   BackoffEntry::Policy no_store_policy = base_policy;
104*6777b538SAndroid Build Coastguard Worker   no_store_policy.entry_lifetime_ms = 0;
105*6777b538SAndroid Build Coastguard Worker   TestTickClock now_ticks;
106*6777b538SAndroid Build Coastguard Worker   BackoffEntry not_stored(&no_store_policy, &now_ticks);
107*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(not_stored.CanDiscard());
108*6777b538SAndroid Build Coastguard Worker }
109*6777b538SAndroid Build Coastguard Worker 
TEST(BackoffEntryTest,ShouldIgnoreFirstTwo)110*6777b538SAndroid Build Coastguard Worker TEST(BackoffEntryTest, ShouldIgnoreFirstTwo) {
111*6777b538SAndroid Build Coastguard Worker   BackoffEntry::Policy lenient_policy = base_policy;
112*6777b538SAndroid Build Coastguard Worker   lenient_policy.num_errors_to_ignore = 2;
113*6777b538SAndroid Build Coastguard Worker 
114*6777b538SAndroid Build Coastguard Worker   BackoffEntry entry(&lenient_policy);
115*6777b538SAndroid Build Coastguard Worker 
116*6777b538SAndroid Build Coastguard Worker   entry.InformOfRequest(false);
117*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(entry.ShouldRejectRequest());
118*6777b538SAndroid Build Coastguard Worker 
119*6777b538SAndroid Build Coastguard Worker   entry.InformOfRequest(false);
120*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(entry.ShouldRejectRequest());
121*6777b538SAndroid Build Coastguard Worker 
122*6777b538SAndroid Build Coastguard Worker   entry.InformOfRequest(false);
123*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(entry.ShouldRejectRequest());
124*6777b538SAndroid Build Coastguard Worker }
125*6777b538SAndroid Build Coastguard Worker 
TEST(BackoffEntryTest,ReleaseTimeCalculation)126*6777b538SAndroid Build Coastguard Worker TEST(BackoffEntryTest, ReleaseTimeCalculation) {
127*6777b538SAndroid Build Coastguard Worker   TestTickClock now_ticks;
128*6777b538SAndroid Build Coastguard Worker   BackoffEntry entry(&base_policy, &now_ticks);
129*6777b538SAndroid Build Coastguard Worker 
130*6777b538SAndroid Build Coastguard Worker   // With zero errors, should return "now".
131*6777b538SAndroid Build Coastguard Worker   TimeTicks result = entry.GetReleaseTime();
132*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(now_ticks.NowTicks(), result);
133*6777b538SAndroid Build Coastguard Worker 
134*6777b538SAndroid Build Coastguard Worker   // 1 error.
135*6777b538SAndroid Build Coastguard Worker   entry.InformOfRequest(false);
136*6777b538SAndroid Build Coastguard Worker   result = entry.GetReleaseTime();
137*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(now_ticks.NowTicks() + base::Milliseconds(1000), result);
138*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(base::Milliseconds(1000), entry.GetTimeUntilRelease());
139*6777b538SAndroid Build Coastguard Worker 
140*6777b538SAndroid Build Coastguard Worker   // 2 errors.
141*6777b538SAndroid Build Coastguard Worker   entry.InformOfRequest(false);
142*6777b538SAndroid Build Coastguard Worker   result = entry.GetReleaseTime();
143*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(now_ticks.NowTicks() + base::Milliseconds(2000), result);
144*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(base::Milliseconds(2000), entry.GetTimeUntilRelease());
145*6777b538SAndroid Build Coastguard Worker 
146*6777b538SAndroid Build Coastguard Worker   // 3 errors.
147*6777b538SAndroid Build Coastguard Worker   entry.InformOfRequest(false);
148*6777b538SAndroid Build Coastguard Worker   result = entry.GetReleaseTime();
149*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(now_ticks.NowTicks() + base::Milliseconds(4000), result);
150*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(base::Milliseconds(4000), entry.GetTimeUntilRelease());
151*6777b538SAndroid Build Coastguard Worker 
152*6777b538SAndroid Build Coastguard Worker   // 6 errors (to check it doesn't pass maximum).
153*6777b538SAndroid Build Coastguard Worker   entry.InformOfRequest(false);
154*6777b538SAndroid Build Coastguard Worker   entry.InformOfRequest(false);
155*6777b538SAndroid Build Coastguard Worker   entry.InformOfRequest(false);
156*6777b538SAndroid Build Coastguard Worker   result = entry.GetReleaseTime();
157*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(now_ticks.NowTicks() + base::Milliseconds(20000), result);
158*6777b538SAndroid Build Coastguard Worker }
159*6777b538SAndroid Build Coastguard Worker 
TEST(BackoffEntryTest,ReleaseTimeCalculationAlwaysDelay)160*6777b538SAndroid Build Coastguard Worker TEST(BackoffEntryTest, ReleaseTimeCalculationAlwaysDelay) {
161*6777b538SAndroid Build Coastguard Worker   BackoffEntry::Policy always_delay_policy = base_policy;
162*6777b538SAndroid Build Coastguard Worker   always_delay_policy.always_use_initial_delay = true;
163*6777b538SAndroid Build Coastguard Worker   always_delay_policy.num_errors_to_ignore = 2;
164*6777b538SAndroid Build Coastguard Worker 
165*6777b538SAndroid Build Coastguard Worker   TestTickClock now_ticks;
166*6777b538SAndroid Build Coastguard Worker   BackoffEntry entry(&always_delay_policy, &now_ticks);
167*6777b538SAndroid Build Coastguard Worker 
168*6777b538SAndroid Build Coastguard Worker   // With previous requests, should return "now".
169*6777b538SAndroid Build Coastguard Worker   TimeTicks result = entry.GetReleaseTime();
170*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(base::TimeDelta(), entry.GetTimeUntilRelease());
171*6777b538SAndroid Build Coastguard Worker 
172*6777b538SAndroid Build Coastguard Worker   // 1 error.
173*6777b538SAndroid Build Coastguard Worker   entry.InformOfRequest(false);
174*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(base::Milliseconds(1000), entry.GetTimeUntilRelease());
175*6777b538SAndroid Build Coastguard Worker 
176*6777b538SAndroid Build Coastguard Worker   // 2 errors.
177*6777b538SAndroid Build Coastguard Worker   entry.InformOfRequest(false);
178*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(base::Milliseconds(1000), entry.GetTimeUntilRelease());
179*6777b538SAndroid Build Coastguard Worker 
180*6777b538SAndroid Build Coastguard Worker   // 3 errors, exponential backoff starts.
181*6777b538SAndroid Build Coastguard Worker   entry.InformOfRequest(false);
182*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(base::Milliseconds(2000), entry.GetTimeUntilRelease());
183*6777b538SAndroid Build Coastguard Worker 
184*6777b538SAndroid Build Coastguard Worker   // 4 errors.
185*6777b538SAndroid Build Coastguard Worker   entry.InformOfRequest(false);
186*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(base::Milliseconds(4000), entry.GetTimeUntilRelease());
187*6777b538SAndroid Build Coastguard Worker 
188*6777b538SAndroid Build Coastguard Worker   // 8 errors (to check it doesn't pass maximum).
189*6777b538SAndroid Build Coastguard Worker   entry.InformOfRequest(false);
190*6777b538SAndroid Build Coastguard Worker   entry.InformOfRequest(false);
191*6777b538SAndroid Build Coastguard Worker   entry.InformOfRequest(false);
192*6777b538SAndroid Build Coastguard Worker   entry.InformOfRequest(false);
193*6777b538SAndroid Build Coastguard Worker   result = entry.GetReleaseTime();
194*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(base::Milliseconds(20000), entry.GetTimeUntilRelease());
195*6777b538SAndroid Build Coastguard Worker }
196*6777b538SAndroid Build Coastguard Worker 
TEST(BackoffEntryTest,ReleaseTimeCalculationWithJitter)197*6777b538SAndroid Build Coastguard Worker TEST(BackoffEntryTest, ReleaseTimeCalculationWithJitter) {
198*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < 10; ++i) {
199*6777b538SAndroid Build Coastguard Worker     BackoffEntry::Policy jittery_policy = base_policy;
200*6777b538SAndroid Build Coastguard Worker     jittery_policy.jitter_factor = 0.2;
201*6777b538SAndroid Build Coastguard Worker 
202*6777b538SAndroid Build Coastguard Worker     TestTickClock now_ticks;
203*6777b538SAndroid Build Coastguard Worker     BackoffEntry entry(&jittery_policy, &now_ticks);
204*6777b538SAndroid Build Coastguard Worker 
205*6777b538SAndroid Build Coastguard Worker     entry.InformOfRequest(false);
206*6777b538SAndroid Build Coastguard Worker     entry.InformOfRequest(false);
207*6777b538SAndroid Build Coastguard Worker     entry.InformOfRequest(false);
208*6777b538SAndroid Build Coastguard Worker     TimeTicks result = entry.GetReleaseTime();
209*6777b538SAndroid Build Coastguard Worker     EXPECT_LE(now_ticks.NowTicks() + base::Milliseconds(3200), result);
210*6777b538SAndroid Build Coastguard Worker     EXPECT_GE(now_ticks.NowTicks() + base::Milliseconds(4000), result);
211*6777b538SAndroid Build Coastguard Worker   }
212*6777b538SAndroid Build Coastguard Worker }
213*6777b538SAndroid Build Coastguard Worker 
TEST(BackoffEntryTest,FailureThenSuccess)214*6777b538SAndroid Build Coastguard Worker TEST(BackoffEntryTest, FailureThenSuccess) {
215*6777b538SAndroid Build Coastguard Worker   TestTickClock now_ticks;
216*6777b538SAndroid Build Coastguard Worker   BackoffEntry entry(&base_policy, &now_ticks);
217*6777b538SAndroid Build Coastguard Worker 
218*6777b538SAndroid Build Coastguard Worker   // Failure count 1, establishes horizon.
219*6777b538SAndroid Build Coastguard Worker   entry.InformOfRequest(false);
220*6777b538SAndroid Build Coastguard Worker   TimeTicks release_time = entry.GetReleaseTime();
221*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(TimeTicks() + base::Milliseconds(1000), release_time);
222*6777b538SAndroid Build Coastguard Worker 
223*6777b538SAndroid Build Coastguard Worker   // Success, failure count 0, should not advance past
224*6777b538SAndroid Build Coastguard Worker   // the horizon that was already set.
225*6777b538SAndroid Build Coastguard Worker   now_ticks.set_now(release_time - base::Milliseconds(200));
226*6777b538SAndroid Build Coastguard Worker   entry.InformOfRequest(true);
227*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(release_time, entry.GetReleaseTime());
228*6777b538SAndroid Build Coastguard Worker 
229*6777b538SAndroid Build Coastguard Worker   // Failure, failure count 1.
230*6777b538SAndroid Build Coastguard Worker   entry.InformOfRequest(false);
231*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(release_time + base::Milliseconds(800), entry.GetReleaseTime());
232*6777b538SAndroid Build Coastguard Worker }
233*6777b538SAndroid Build Coastguard Worker 
TEST(BackoffEntryTest,FailureThenSuccessAlwaysDelay)234*6777b538SAndroid Build Coastguard Worker TEST(BackoffEntryTest, FailureThenSuccessAlwaysDelay) {
235*6777b538SAndroid Build Coastguard Worker   BackoffEntry::Policy always_delay_policy = base_policy;
236*6777b538SAndroid Build Coastguard Worker   always_delay_policy.always_use_initial_delay = true;
237*6777b538SAndroid Build Coastguard Worker   always_delay_policy.num_errors_to_ignore = 1;
238*6777b538SAndroid Build Coastguard Worker 
239*6777b538SAndroid Build Coastguard Worker   TestTickClock now_ticks;
240*6777b538SAndroid Build Coastguard Worker   BackoffEntry entry(&always_delay_policy, &now_ticks);
241*6777b538SAndroid Build Coastguard Worker 
242*6777b538SAndroid Build Coastguard Worker   // Failure count 1.
243*6777b538SAndroid Build Coastguard Worker   entry.InformOfRequest(false);
244*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(base::Milliseconds(1000), entry.GetTimeUntilRelease());
245*6777b538SAndroid Build Coastguard Worker 
246*6777b538SAndroid Build Coastguard Worker   // Failure count 2.
247*6777b538SAndroid Build Coastguard Worker   entry.InformOfRequest(false);
248*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(base::Milliseconds(2000), entry.GetTimeUntilRelease());
249*6777b538SAndroid Build Coastguard Worker   now_ticks.set_now(entry.GetReleaseTime() + base::Milliseconds(2000));
250*6777b538SAndroid Build Coastguard Worker 
251*6777b538SAndroid Build Coastguard Worker   // Success.  We should go back to the original delay.
252*6777b538SAndroid Build Coastguard Worker   entry.InformOfRequest(true);
253*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(base::Milliseconds(1000), entry.GetTimeUntilRelease());
254*6777b538SAndroid Build Coastguard Worker 
255*6777b538SAndroid Build Coastguard Worker   // Failure count reaches 2 again.  We should increase the delay once more.
256*6777b538SAndroid Build Coastguard Worker   entry.InformOfRequest(false);
257*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(base::Milliseconds(2000), entry.GetTimeUntilRelease());
258*6777b538SAndroid Build Coastguard Worker   now_ticks.set_now(entry.GetReleaseTime() + base::Milliseconds(2000));
259*6777b538SAndroid Build Coastguard Worker }
260*6777b538SAndroid Build Coastguard Worker 
TEST(BackoffEntryTest,RetainCustomHorizon)261*6777b538SAndroid Build Coastguard Worker TEST(BackoffEntryTest, RetainCustomHorizon) {
262*6777b538SAndroid Build Coastguard Worker   TestTickClock now_ticks;
263*6777b538SAndroid Build Coastguard Worker   BackoffEntry custom(&base_policy, &now_ticks);
264*6777b538SAndroid Build Coastguard Worker   TimeTicks custom_horizon = TimeTicks() + base::Days(3);
265*6777b538SAndroid Build Coastguard Worker   custom.SetCustomReleaseTime(custom_horizon);
266*6777b538SAndroid Build Coastguard Worker   custom.InformOfRequest(false);
267*6777b538SAndroid Build Coastguard Worker   custom.InformOfRequest(true);
268*6777b538SAndroid Build Coastguard Worker   now_ticks.set_now(TimeTicks() + base::Days(2));
269*6777b538SAndroid Build Coastguard Worker   custom.InformOfRequest(false);
270*6777b538SAndroid Build Coastguard Worker   custom.InformOfRequest(true);
271*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(custom_horizon, custom.GetReleaseTime());
272*6777b538SAndroid Build Coastguard Worker 
273*6777b538SAndroid Build Coastguard Worker   // Now check that once we are at or past the custom horizon,
274*6777b538SAndroid Build Coastguard Worker   // we get normal behavior.
275*6777b538SAndroid Build Coastguard Worker   now_ticks.set_now(TimeTicks() + base::Days(3));
276*6777b538SAndroid Build Coastguard Worker   custom.InformOfRequest(false);
277*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(TimeTicks() + base::Days(3) + base::Milliseconds(1000),
278*6777b538SAndroid Build Coastguard Worker             custom.GetReleaseTime());
279*6777b538SAndroid Build Coastguard Worker }
280*6777b538SAndroid Build Coastguard Worker 
TEST(BackoffEntryTest,RetainCustomHorizonWhenInitialErrorsIgnored)281*6777b538SAndroid Build Coastguard Worker TEST(BackoffEntryTest, RetainCustomHorizonWhenInitialErrorsIgnored) {
282*6777b538SAndroid Build Coastguard Worker   // Regression test for a bug discovered during code review.
283*6777b538SAndroid Build Coastguard Worker   BackoffEntry::Policy lenient_policy = base_policy;
284*6777b538SAndroid Build Coastguard Worker   lenient_policy.num_errors_to_ignore = 1;
285*6777b538SAndroid Build Coastguard Worker   TestTickClock now_ticks;
286*6777b538SAndroid Build Coastguard Worker   BackoffEntry custom(&lenient_policy, &now_ticks);
287*6777b538SAndroid Build Coastguard Worker   TimeTicks custom_horizon = TimeTicks() + base::Days(3);
288*6777b538SAndroid Build Coastguard Worker   custom.SetCustomReleaseTime(custom_horizon);
289*6777b538SAndroid Build Coastguard Worker   custom.InformOfRequest(false);  // This must not reset the horizon.
290*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(custom_horizon, custom.GetReleaseTime());
291*6777b538SAndroid Build Coastguard Worker }
292*6777b538SAndroid Build Coastguard Worker 
TEST(BackoffEntryTest,OverflowProtection)293*6777b538SAndroid Build Coastguard Worker TEST(BackoffEntryTest, OverflowProtection) {
294*6777b538SAndroid Build Coastguard Worker   BackoffEntry::Policy large_multiply_policy = base_policy;
295*6777b538SAndroid Build Coastguard Worker   large_multiply_policy.multiply_factor = 256;
296*6777b538SAndroid Build Coastguard Worker   TestTickClock now_ticks;
297*6777b538SAndroid Build Coastguard Worker   BackoffEntry custom(&large_multiply_policy, &now_ticks);
298*6777b538SAndroid Build Coastguard Worker 
299*6777b538SAndroid Build Coastguard Worker   // Trigger enough failures such that more than 11 bits of exponent are used
300*6777b538SAndroid Build Coastguard Worker   // to represent the exponential backoff intermediate values. Given a multiply
301*6777b538SAndroid Build Coastguard Worker   // factor of 256 (2^8), 129 iterations is enough: 2^(8*(129-1)) = 2^1024.
302*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < 129; ++i) {
303*6777b538SAndroid Build Coastguard Worker      now_ticks.set_now(now_ticks.NowTicks() + custom.GetTimeUntilRelease());
304*6777b538SAndroid Build Coastguard Worker      custom.InformOfRequest(false);
305*6777b538SAndroid Build Coastguard Worker      ASSERT_TRUE(custom.ShouldRejectRequest());
306*6777b538SAndroid Build Coastguard Worker   }
307*6777b538SAndroid Build Coastguard Worker 
308*6777b538SAndroid Build Coastguard Worker   // Max delay should still be respected.
309*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(20000, custom.GetTimeUntilRelease().InMilliseconds());
310*6777b538SAndroid Build Coastguard Worker }
311*6777b538SAndroid Build Coastguard Worker 
312*6777b538SAndroid Build Coastguard Worker }  // namespace
313*6777b538SAndroid Build Coastguard Worker 
314*6777b538SAndroid Build Coastguard Worker }  // namespace net
315