Chromium Code Reviews| Index: net/base/backoff_entry_serializer_unittest.cc |
| diff --git a/net/base/backoff_entry_serializer_unittest.cc b/net/base/backoff_entry_serializer_unittest.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..ea418476e0daf36ab599b5a934b946ebe1d00a13 |
| --- /dev/null |
| +++ b/net/base/backoff_entry_serializer_unittest.cc |
| @@ -0,0 +1,172 @@ |
| +// Copyright 2015 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "net/base/backoff_entry.h" |
| + |
| +#include "base/logging.h" |
| +#include "base/macros.h" |
| +#include "base/time/tick_clock.h" |
| +#include "base/values.h" |
| +#include "net/base/backoff_entry_serializer.h" |
| +#include "testing/gtest/include/gtest/gtest.h" |
| + |
| +namespace net { |
| + |
| +namespace { |
| + |
| +using base::Time; |
| +using base::TimeDelta; |
| +using base::TimeTicks; |
| + |
| +BackoffEntry::Policy base_policy = { |
| + 0 /* num_errors_to_ignore */, |
| + 1000 /* initial_delay_ms */, |
| + 2.0 /* multiply_factor */, |
| + 0.0 /* jitter_factor */, |
| + 20000 /* maximum_backoff_ms */, |
| + 2000 /* entry_lifetime_ms */, |
| + false /* always_use_initial_delay */ |
| +}; |
| + |
| +class TestTickClock : public base::TickClock { |
| + public: |
| + TestTickClock() {} |
| + ~TestTickClock() override {} |
| + |
| + TimeTicks NowTicks() override { return now_ticks_; } |
| + void set_now(TimeTicks now) { now_ticks_ = now; } |
| + |
| + private: |
| + TimeTicks now_ticks_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(TestTickClock); |
| +}; |
| + |
| +TEST(BackoffEntrySerializerTest, SerializeNoFailures) { |
| + Time original_time = Time::Now(); |
| + TestTickClock original_ticks; |
| + original_ticks.set_now(TimeTicks::Now()); |
| + BackoffEntry original(&base_policy, &original_ticks); |
| + scoped_ptr<base::Value> serialized = |
| + BackoffEntrySerializer::SerializeToValue(original, original_time); |
| + |
| + scoped_ptr<BackoffEntry> deserialized = |
| + BackoffEntrySerializer::DeserializeFromValue(*serialized, &base_policy, |
| + &original_ticks, |
| + original_time); |
| + ASSERT_TRUE(deserialized.get()); |
| + EXPECT_EQ(original.failure_count(), deserialized->failure_count()); |
| + EXPECT_EQ(original.GetReleaseTime(), deserialized->GetReleaseTime()); |
| +} |
| + |
| +TEST(BackoffEntrySerializerTest, SerializeTimeOffsets) { |
| + Time original_time = Time::FromJsTime(1430907555111); // May 2015 for realism |
| + TestTickClock original_ticks; |
| + BackoffEntry original(&base_policy, &original_ticks); |
| + // 2 errors. |
| + original.InformOfRequest(false); |
| + original.InformOfRequest(false); |
| + scoped_ptr<base::Value> serialized = |
| + BackoffEntrySerializer::SerializeToValue(original, original_time); |
| + |
| + { |
| + // Test that immediate deserialization round-trips. |
| + scoped_ptr<BackoffEntry> deserialized = |
| + BackoffEntrySerializer::DeserializeFromValue(*serialized, &base_policy, |
| + &original_ticks, |
| + original_time); |
| + ASSERT_TRUE(deserialized.get()); |
| + EXPECT_EQ(original.failure_count(), deserialized->failure_count()); |
| + EXPECT_EQ(original.GetReleaseTime(), deserialized->GetReleaseTime()); |
| + } |
| + |
| + { |
| + // Test deserialization when wall clock has advanced but TimeTicks::Now() |
| + // hasn't (e.g. device was rebooted). |
| + Time later_time = original_time + TimeDelta::FromDays(1); |
| + scoped_ptr<BackoffEntry> deserialized = |
| + BackoffEntrySerializer::DeserializeFromValue(*serialized, &base_policy, |
| + &original_ticks, |
| + later_time); |
| + ASSERT_TRUE(deserialized.get()); |
| + EXPECT_EQ(original.failure_count(), deserialized->failure_count()); |
| + // Remaining backoff duration continues decreasing while device is off. |
| + // Since TimeTicks::Now() has not advanced, the absolute release time ticks |
| + // will decrease accordingly. |
| + EXPECT_GT(original.GetTimeUntilRelease(), |
| + deserialized->GetTimeUntilRelease()); |
| + EXPECT_EQ(original.GetReleaseTime() - TimeDelta::FromDays(1), |
| + deserialized->GetReleaseTime()); |
| + } |
| + |
| + { |
| + // Test deserialization when TimeTicks::Now() has advanced but wall clock |
| + // hasn't (e.g. it's an hour later, but a DST change cancelled that out). |
| + TestTickClock later_ticks; |
| + later_ticks.set_now(TimeTicks() + TimeDelta::FromDays(1)); |
| + scoped_ptr<BackoffEntry> deserialized = |
| + BackoffEntrySerializer::DeserializeFromValue(*serialized, &base_policy, |
| + &later_ticks, |
| + original_time); |
| + ASSERT_TRUE(deserialized.get()); |
| + EXPECT_EQ(original.failure_count(), deserialized->failure_count()); |
| + // According to the wall clock, no time has passed. So remaining backoff |
| + // duration is preserved, hence the absolute release time ticks increases. |
| + // This isn't ideal - if we also serialized the current time and time ticks, |
|
mmenke
2015/05/06 20:48:44
nit: Don't use we in comments (x2)
johnme
2015/05/07 12:16:01
Done (oops, old habits).
|
| + // we could detect that time had passed but the wall clock went backwards, |
| + // and reduce the remaining backoff duration accordingly. |
| + EXPECT_EQ(original.GetTimeUntilRelease(), |
| + deserialized->GetTimeUntilRelease()); |
| + EXPECT_EQ(original.GetReleaseTime() + TimeDelta::FromDays(1), |
| + deserialized->GetReleaseTime()); |
| + } |
| + |
| + { |
| + // Test deserialization when both wall clock and TimeTicks::Now() have |
| + // advanced (e.g. it's just later than it used to be). |
| + TestTickClock later_ticks; |
| + later_ticks.set_now(TimeTicks() + TimeDelta::FromDays(1)); |
| + Time later_time = original_time + TimeDelta::FromDays(1); |
| + scoped_ptr<BackoffEntry> deserialized = |
| + BackoffEntrySerializer::DeserializeFromValue(*serialized, &base_policy, |
| + &later_ticks, later_time); |
| + ASSERT_TRUE(deserialized.get()); |
| + EXPECT_EQ(original.failure_count(), deserialized->failure_count()); |
| + // Since both have advanced by the same amount, the absolute release time |
| + // ticks should be preserved; the remaining backoff duration will have |
| + // decreased of course, since time has passed. |
| + EXPECT_GT(original.GetTimeUntilRelease(), |
| + deserialized->GetTimeUntilRelease()); |
| + EXPECT_EQ(original.GetReleaseTime(), deserialized->GetReleaseTime()); |
| + } |
| + |
| + { |
| + // Test deserialization when wall clock has gone backwards but TimeTicks |
| + // haven't (e.g. the system clock was fast but they fixed it). |
| + EXPECT_LT(TimeDelta::FromSeconds(1), original.GetTimeUntilRelease()); |
| + Time earlier_time = original_time - TimeDelta::FromSeconds(1); |
| + scoped_ptr<BackoffEntry> deserialized = |
| + BackoffEntrySerializer::DeserializeFromValue(*serialized, &base_policy, |
| + &original_ticks, |
| + earlier_time); |
| + ASSERT_TRUE(deserialized.get()); |
| + EXPECT_EQ(original.failure_count(), deserialized->failure_count()); |
| + // If we just serialized the absolute wall clock time, subtracting the |
|
mmenke
2015/05/06 20:48:44
nit: -we
johnme
2015/05/07 12:16:01
Done.
|
| + // (decreased) current wall clock time from the serialized wall clock time |
| + // could give very large (incorrect) values for remaining backoff duration. |
| + // But we actually serialize the remaining backoff duration as well, and |
| + // don't allow the duration to increase beyond it's previous value during |
| + // deserialization. Hence when the wall clock goes backwards the remaining |
| + // backoff duration will be preserved. |
| + EXPECT_EQ(original.GetTimeUntilRelease(), |
| + deserialized->GetTimeUntilRelease()); |
| + // Since TimeTicks::Now() hasn't changed, the absolute release time ticks |
| + // will be equal too in this particular case. |
| + EXPECT_EQ(original.GetReleaseTime(), deserialized->GetReleaseTime()); |
| + } |
| +} |
| + |
| +} // namespace |
| + |
| +} // namespace net |