1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/base/backoff_entry.h"
7 #include "base/logging.h"
8 #include "base/macros.h"
9 #include "base/time/tick_clock.h"
10 #include "base/values.h"
11 #include "net/base/backoff_entry_serializer.h"
12 #include "testing/gtest/include/gtest/gtest.h"
19 using base::TimeDelta
;
20 using base::TimeTicks
;
22 BackoffEntry::Policy base_policy
= {
23 0 /* num_errors_to_ignore */,
24 1000 /* initial_delay_ms */,
25 2.0 /* multiply_factor */,
26 0.0 /* jitter_factor */,
27 20000 /* maximum_backoff_ms */,
28 2000 /* entry_lifetime_ms */,
29 false /* always_use_initial_delay */
32 class TestTickClock
: public base::TickClock
{
35 ~TestTickClock() override
{}
37 TimeTicks
NowTicks() override
{ return now_ticks_
; }
38 void set_now(TimeTicks now
) { now_ticks_
= now
; }
43 DISALLOW_COPY_AND_ASSIGN(TestTickClock
);
46 TEST(BackoffEntrySerializerTest
, SerializeNoFailures
) {
47 Time original_time
= Time::Now();
48 TestTickClock original_ticks
;
49 original_ticks
.set_now(TimeTicks::Now());
50 BackoffEntry
original(&base_policy
, &original_ticks
);
51 scoped_ptr
<base::Value
> serialized
=
52 BackoffEntrySerializer::SerializeToValue(original
, original_time
);
54 scoped_ptr
<BackoffEntry
> deserialized
=
55 BackoffEntrySerializer::DeserializeFromValue(*serialized
, &base_policy
,
58 ASSERT_TRUE(deserialized
.get());
59 EXPECT_EQ(original
.failure_count(), deserialized
->failure_count());
60 EXPECT_EQ(original
.GetReleaseTime(), deserialized
->GetReleaseTime());
63 TEST(BackoffEntrySerializerTest
, SerializeTimeOffsets
) {
64 Time original_time
= Time::FromJsTime(1430907555111); // May 2015 for realism
65 TestTickClock original_ticks
;
66 BackoffEntry
original(&base_policy
, &original_ticks
);
68 original
.InformOfRequest(false);
69 original
.InformOfRequest(false);
70 scoped_ptr
<base::Value
> serialized
=
71 BackoffEntrySerializer::SerializeToValue(original
, original_time
);
74 // Test that immediate deserialization round-trips.
75 scoped_ptr
<BackoffEntry
> deserialized
=
76 BackoffEntrySerializer::DeserializeFromValue(*serialized
, &base_policy
,
79 ASSERT_TRUE(deserialized
.get());
80 EXPECT_EQ(original
.failure_count(), deserialized
->failure_count());
81 EXPECT_EQ(original
.GetReleaseTime(), deserialized
->GetReleaseTime());
85 // Test deserialization when wall clock has advanced but TimeTicks::Now()
86 // hasn't (e.g. device was rebooted).
87 Time later_time
= original_time
+ TimeDelta::FromDays(1);
88 scoped_ptr
<BackoffEntry
> deserialized
=
89 BackoffEntrySerializer::DeserializeFromValue(*serialized
, &base_policy
,
92 ASSERT_TRUE(deserialized
.get());
93 EXPECT_EQ(original
.failure_count(), deserialized
->failure_count());
94 // Remaining backoff duration continues decreasing while device is off.
95 // Since TimeTicks::Now() has not advanced, the absolute release time ticks
96 // will decrease accordingly.
97 EXPECT_GT(original
.GetTimeUntilRelease(),
98 deserialized
->GetTimeUntilRelease());
99 EXPECT_EQ(original
.GetReleaseTime() - TimeDelta::FromDays(1),
100 deserialized
->GetReleaseTime());
104 // Test deserialization when TimeTicks::Now() has advanced but wall clock
105 // hasn't (e.g. it's an hour later, but a DST change cancelled that out).
106 TestTickClock later_ticks
;
107 later_ticks
.set_now(TimeTicks() + TimeDelta::FromDays(1));
108 scoped_ptr
<BackoffEntry
> deserialized
=
109 BackoffEntrySerializer::DeserializeFromValue(*serialized
, &base_policy
,
112 ASSERT_TRUE(deserialized
.get());
113 EXPECT_EQ(original
.failure_count(), deserialized
->failure_count());
114 // According to the wall clock, no time has passed. So remaining backoff
115 // duration is preserved, hence the absolute release time ticks increases.
116 // This isn't ideal - by also serializing the current time and time ticks,
117 // it would be possible to detect that time has passed but the wall clock
118 // went backwards, and reduce the remaining backoff duration accordingly,
119 // however the current implementation does not do this as the benefit would
120 // be somewhat marginal.
121 EXPECT_EQ(original
.GetTimeUntilRelease(),
122 deserialized
->GetTimeUntilRelease());
123 EXPECT_EQ(original
.GetReleaseTime() + TimeDelta::FromDays(1),
124 deserialized
->GetReleaseTime());
128 // Test deserialization when both wall clock and TimeTicks::Now() have
129 // advanced (e.g. it's just later than it used to be).
130 TestTickClock later_ticks
;
131 later_ticks
.set_now(TimeTicks() + TimeDelta::FromDays(1));
132 Time later_time
= original_time
+ TimeDelta::FromDays(1);
133 scoped_ptr
<BackoffEntry
> deserialized
=
134 BackoffEntrySerializer::DeserializeFromValue(*serialized
, &base_policy
,
135 &later_ticks
, later_time
);
136 ASSERT_TRUE(deserialized
.get());
137 EXPECT_EQ(original
.failure_count(), deserialized
->failure_count());
138 // Since both have advanced by the same amount, the absolute release time
139 // ticks should be preserved; the remaining backoff duration will have
140 // decreased of course, since time has passed.
141 EXPECT_GT(original
.GetTimeUntilRelease(),
142 deserialized
->GetTimeUntilRelease());
143 EXPECT_EQ(original
.GetReleaseTime(), deserialized
->GetReleaseTime());
147 // Test deserialization when wall clock has gone backwards but TimeTicks
148 // haven't (e.g. the system clock was fast but they fixed it).
149 EXPECT_LT(TimeDelta::FromSeconds(1), original
.GetTimeUntilRelease());
150 Time earlier_time
= original_time
- TimeDelta::FromSeconds(1);
151 scoped_ptr
<BackoffEntry
> deserialized
=
152 BackoffEntrySerializer::DeserializeFromValue(*serialized
, &base_policy
,
155 ASSERT_TRUE(deserialized
.get());
156 EXPECT_EQ(original
.failure_count(), deserialized
->failure_count());
157 // If only the absolute wall clock time was serialized, subtracting the
158 // (decreased) current wall clock time from the serialized wall clock time
159 // could give very large (incorrect) values for remaining backoff duration.
160 // But instead the implementation also serializes the remaining backoff
161 // duration, and doesn't allow the duration to increase beyond it's previous
162 // value during deserialization. Hence when the wall clock goes backwards
163 // the remaining backoff duration will be preserved.
164 EXPECT_EQ(original
.GetTimeUntilRelease(),
165 deserialized
->GetTimeUntilRelease());
166 // Since TimeTicks::Now() hasn't changed, the absolute release time ticks
167 // will be equal too in this particular case.
168 EXPECT_EQ(original
.GetReleaseTime(), deserialized
->GetReleaseTime());