OLD | NEW |
(Empty) | |
| 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. |
| 4 |
| 5 #include "net/base/backoff_entry.h" |
| 6 |
| 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" |
| 13 |
| 14 namespace net { |
| 15 |
| 16 namespace { |
| 17 |
| 18 using base::Time; |
| 19 using base::TimeDelta; |
| 20 using base::TimeTicks; |
| 21 |
| 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 */ |
| 30 }; |
| 31 |
| 32 class TestTickClock : public base::TickClock { |
| 33 public: |
| 34 TestTickClock() {} |
| 35 ~TestTickClock() override {} |
| 36 |
| 37 TimeTicks NowTicks() override { return now_ticks_; } |
| 38 void set_now(TimeTicks now) { now_ticks_ = now; } |
| 39 |
| 40 private: |
| 41 TimeTicks now_ticks_; |
| 42 |
| 43 DISALLOW_COPY_AND_ASSIGN(TestTickClock); |
| 44 }; |
| 45 |
| 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); |
| 53 |
| 54 scoped_ptr<BackoffEntry> deserialized = |
| 55 BackoffEntrySerializer::DeserializeFromValue(*serialized, &base_policy, |
| 56 &original_ticks, |
| 57 original_time); |
| 58 ASSERT_TRUE(deserialized.get()); |
| 59 EXPECT_EQ(original.failure_count(), deserialized->failure_count()); |
| 60 EXPECT_EQ(original.GetReleaseTime(), deserialized->GetReleaseTime()); |
| 61 } |
| 62 |
| 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); |
| 67 // 2 errors. |
| 68 original.InformOfRequest(false); |
| 69 original.InformOfRequest(false); |
| 70 scoped_ptr<base::Value> serialized = |
| 71 BackoffEntrySerializer::SerializeToValue(original, original_time); |
| 72 |
| 73 { |
| 74 // Test that immediate deserialization round-trips. |
| 75 scoped_ptr<BackoffEntry> deserialized = |
| 76 BackoffEntrySerializer::DeserializeFromValue(*serialized, &base_policy, |
| 77 &original_ticks, |
| 78 original_time); |
| 79 ASSERT_TRUE(deserialized.get()); |
| 80 EXPECT_EQ(original.failure_count(), deserialized->failure_count()); |
| 81 EXPECT_EQ(original.GetReleaseTime(), deserialized->GetReleaseTime()); |
| 82 } |
| 83 |
| 84 { |
| 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, |
| 90 &original_ticks, |
| 91 later_time); |
| 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()); |
| 101 } |
| 102 |
| 103 { |
| 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, |
| 110 &later_ticks, |
| 111 original_time); |
| 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()); |
| 125 } |
| 126 |
| 127 { |
| 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()); |
| 144 } |
| 145 |
| 146 { |
| 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, |
| 153 &original_ticks, |
| 154 earlier_time); |
| 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()); |
| 169 } |
| 170 } |
| 171 |
| 172 } // namespace |
| 173 |
| 174 } // namespace net |
OLD | NEW |