| 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..9799c06e717f8e3061fd4920c61e6a7b7bd6f271
|
| --- /dev/null
|
| +++ b/net/base/backoff_entry_serializer_unittest.cc
|
| @@ -0,0 +1,174 @@
|
| +// 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 - by also serializing the current time and time ticks,
|
| + // it would be possible to detect that time has passed but the wall clock
|
| + // went backwards, and reduce the remaining backoff duration accordingly,
|
| + // however the current implementation does not do this as the benefit would
|
| + // be somewhat marginal.
|
| + 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 only the absolute wall clock time was serialized, subtracting the
|
| + // (decreased) current wall clock time from the serialized wall clock time
|
| + // could give very large (incorrect) values for remaining backoff duration.
|
| + // But instead the implementation also serializes the remaining backoff
|
| + // duration, and doesn'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
|
|
|