diff options
Diffstat (limited to 'net/base/backoff_entry_unittest.cc')
-rw-r--r-- | net/base/backoff_entry_unittest.cc | 111 |
1 files changed, 56 insertions, 55 deletions
diff --git a/net/base/backoff_entry_unittest.cc b/net/base/backoff_entry_unittest.cc index 89ec2c4..cca7c45 100644 --- a/net/base/backoff_entry_unittest.cc +++ b/net/base/backoff_entry_unittest.cc @@ -3,6 +3,9 @@ // found in the LICENSE file. #include "net/base/backoff_entry.h" + +#include "base/macros.h" +#include "base/time/tick_clock.h" #include "testing/gtest/include/gtest/gtest.h" namespace { @@ -13,32 +16,22 @@ using net::BackoffEntry; BackoffEntry::Policy base_policy = { 0, 1000, 2.0, 0.0, 20000, 2000, false }; -class TestBackoffEntry : public BackoffEntry { +class TestTickClock : public base::TickClock { public: - explicit TestBackoffEntry(const Policy* const policy) - : BackoffEntry(policy), - now_(TimeTicks()) { - // Work around initialization in constructor not picking up - // fake time. - SetCustomReleaseTime(TimeTicks()); - } + TestTickClock() {} + ~TestTickClock() override {} - ~TestBackoffEntry() override {} - - TimeTicks ImplGetTimeNow() const override { return now_; } - - void set_now(const TimeTicks& now) { - now_ = now; - } + TimeTicks NowTicks() override { return now_ticks_; } + void set_now(TimeTicks now) { now_ticks_ = now; } private: - TimeTicks now_; - - DISALLOW_COPY_AND_ASSIGN(TestBackoffEntry); + TimeTicks now_ticks_; + DISALLOW_COPY_AND_ASSIGN(TestTickClock); }; TEST(BackoffEntryTest, BaseTest) { - TestBackoffEntry entry(&base_policy); + TestTickClock now_ticks; + BackoffEntry entry(&base_policy, &now_ticks); EXPECT_FALSE(entry.ShouldRejectRequest()); EXPECT_EQ(TimeDelta(), entry.GetTimeUntilRelease()); @@ -50,14 +43,16 @@ TEST(BackoffEntryTest, BaseTest) { TEST(BackoffEntryTest, CanDiscardNeverExpires) { BackoffEntry::Policy never_expires_policy = base_policy; never_expires_policy.entry_lifetime_ms = -1; - TestBackoffEntry never_expires(&never_expires_policy); + TestTickClock now_ticks; + BackoffEntry never_expires(&never_expires_policy, &now_ticks); EXPECT_FALSE(never_expires.CanDiscard()); - never_expires.set_now(TimeTicks() + TimeDelta::FromDays(100)); + now_ticks.set_now(TimeTicks() + TimeDelta::FromDays(100)); EXPECT_FALSE(never_expires.CanDiscard()); } TEST(BackoffEntryTest, CanDiscard) { - TestBackoffEntry entry(&base_policy); + TestTickClock now_ticks; + BackoffEntry entry(&base_policy, &now_ticks); // Because lifetime is non-zero, we shouldn't be able to discard yet. EXPECT_FALSE(entry.CanDiscard()); @@ -66,19 +61,18 @@ TEST(BackoffEntryTest, CanDiscard) { EXPECT_FALSE(entry.CanDiscard()); // Test the case where there are errors but we can time out. - entry.set_now( - entry.GetReleaseTime() + TimeDelta::FromMilliseconds(1)); + now_ticks.set_now(entry.GetReleaseTime() + TimeDelta::FromMilliseconds(1)); EXPECT_FALSE(entry.CanDiscard()); - entry.set_now(entry.GetReleaseTime() + TimeDelta::FromMilliseconds( + now_ticks.set_now(entry.GetReleaseTime() + TimeDelta::FromMilliseconds( base_policy.maximum_backoff_ms + 1)); EXPECT_TRUE(entry.CanDiscard()); // Test the final case (no errors, dependent only on specified lifetime). - entry.set_now(entry.GetReleaseTime() + TimeDelta::FromMilliseconds( + now_ticks.set_now(entry.GetReleaseTime() + TimeDelta::FromMilliseconds( base_policy.entry_lifetime_ms - 1)); entry.InformOfRequest(true); EXPECT_FALSE(entry.CanDiscard()); - entry.set_now(entry.GetReleaseTime() + TimeDelta::FromMilliseconds( + now_ticks.set_now(entry.GetReleaseTime() + TimeDelta::FromMilliseconds( base_policy.entry_lifetime_ms)); EXPECT_TRUE(entry.CanDiscard()); } @@ -88,10 +82,11 @@ TEST(BackoffEntryTest, CanDiscardAlwaysDelay) { always_delay_policy.always_use_initial_delay = true; always_delay_policy.entry_lifetime_ms = 0; - TestBackoffEntry entry(&always_delay_policy); + TestTickClock now_ticks; + BackoffEntry entry(&always_delay_policy, &now_ticks); // Because lifetime is non-zero, we shouldn't be able to discard yet. - entry.set_now(entry.GetReleaseTime() + TimeDelta::FromMilliseconds(2000)); + now_ticks.set_now(entry.GetReleaseTime() + TimeDelta::FromMilliseconds(2000)); EXPECT_TRUE(entry.CanDiscard()); // Even with no failures, we wait until the delay before we allow discard. @@ -99,14 +94,15 @@ TEST(BackoffEntryTest, CanDiscardAlwaysDelay) { EXPECT_FALSE(entry.CanDiscard()); // Wait until the delay expires, and we can discard the entry again. - entry.set_now(entry.GetReleaseTime() + TimeDelta::FromMilliseconds(1000)); + now_ticks.set_now(entry.GetReleaseTime() + TimeDelta::FromMilliseconds(1000)); EXPECT_TRUE(entry.CanDiscard()); } TEST(BackoffEntryTest, CanDiscardNotStored) { BackoffEntry::Policy no_store_policy = base_policy; no_store_policy.entry_lifetime_ms = 0; - TestBackoffEntry not_stored(&no_store_policy); + TestTickClock now_ticks; + BackoffEntry not_stored(&no_store_policy, &now_ticks); EXPECT_TRUE(not_stored.CanDiscard()); } @@ -127,28 +123,29 @@ TEST(BackoffEntryTest, ShouldIgnoreFirstTwo) { } TEST(BackoffEntryTest, ReleaseTimeCalculation) { - TestBackoffEntry entry(&base_policy); + TestTickClock now_ticks; + BackoffEntry entry(&base_policy, &now_ticks); // With zero errors, should return "now". TimeTicks result = entry.GetReleaseTime(); - EXPECT_EQ(entry.ImplGetTimeNow(), result); + EXPECT_EQ(now_ticks.NowTicks(), result); // 1 error. entry.InformOfRequest(false); result = entry.GetReleaseTime(); - EXPECT_EQ(entry.ImplGetTimeNow() + TimeDelta::FromMilliseconds(1000), result); + EXPECT_EQ(now_ticks.NowTicks() + TimeDelta::FromMilliseconds(1000), result); EXPECT_EQ(TimeDelta::FromMilliseconds(1000), entry.GetTimeUntilRelease()); // 2 errors. entry.InformOfRequest(false); result = entry.GetReleaseTime(); - EXPECT_EQ(entry.ImplGetTimeNow() + TimeDelta::FromMilliseconds(2000), result); + EXPECT_EQ(now_ticks.NowTicks() + TimeDelta::FromMilliseconds(2000), result); EXPECT_EQ(TimeDelta::FromMilliseconds(2000), entry.GetTimeUntilRelease()); // 3 errors. entry.InformOfRequest(false); result = entry.GetReleaseTime(); - EXPECT_EQ(entry.ImplGetTimeNow() + TimeDelta::FromMilliseconds(4000), result); + EXPECT_EQ(now_ticks.NowTicks() + TimeDelta::FromMilliseconds(4000), result); EXPECT_EQ(TimeDelta::FromMilliseconds(4000), entry.GetTimeUntilRelease()); // 6 errors (to check it doesn't pass maximum). @@ -156,8 +153,7 @@ TEST(BackoffEntryTest, ReleaseTimeCalculation) { entry.InformOfRequest(false); entry.InformOfRequest(false); result = entry.GetReleaseTime(); - EXPECT_EQ( - entry.ImplGetTimeNow() + TimeDelta::FromMilliseconds(20000), result); + EXPECT_EQ(now_ticks.NowTicks() + TimeDelta::FromMilliseconds(20000), result); } TEST(BackoffEntryTest, ReleaseTimeCalculationAlwaysDelay) { @@ -165,7 +161,8 @@ TEST(BackoffEntryTest, ReleaseTimeCalculationAlwaysDelay) { always_delay_policy.always_use_initial_delay = true; always_delay_policy.num_errors_to_ignore = 2; - TestBackoffEntry entry(&always_delay_policy); + TestTickClock now_ticks; + BackoffEntry entry(&always_delay_policy, &now_ticks); // With previous requests, should return "now". TimeTicks result = entry.GetReleaseTime(); @@ -201,21 +198,21 @@ TEST(BackoffEntryTest, ReleaseTimeCalculationWithJitter) { BackoffEntry::Policy jittery_policy = base_policy; jittery_policy.jitter_factor = 0.2; - TestBackoffEntry entry(&jittery_policy); + TestTickClock now_ticks; + BackoffEntry entry(&jittery_policy, &now_ticks); entry.InformOfRequest(false); entry.InformOfRequest(false); entry.InformOfRequest(false); TimeTicks result = entry.GetReleaseTime(); - EXPECT_LE( - entry.ImplGetTimeNow() + TimeDelta::FromMilliseconds(3200), result); - EXPECT_GE( - entry.ImplGetTimeNow() + TimeDelta::FromMilliseconds(4000), result); + EXPECT_LE(now_ticks.NowTicks() + TimeDelta::FromMilliseconds(3200), result); + EXPECT_GE(now_ticks.NowTicks() + TimeDelta::FromMilliseconds(4000), result); } } TEST(BackoffEntryTest, FailureThenSuccess) { - TestBackoffEntry entry(&base_policy); + TestTickClock now_ticks; + BackoffEntry entry(&base_policy, &now_ticks); // Failure count 1, establishes horizon. entry.InformOfRequest(false); @@ -224,7 +221,7 @@ TEST(BackoffEntryTest, FailureThenSuccess) { // Success, failure count 0, should not advance past // the horizon that was already set. - entry.set_now(release_time - TimeDelta::FromMilliseconds(200)); + now_ticks.set_now(release_time - TimeDelta::FromMilliseconds(200)); entry.InformOfRequest(true); EXPECT_EQ(release_time, entry.GetReleaseTime()); @@ -239,7 +236,8 @@ TEST(BackoffEntryTest, FailureThenSuccessAlwaysDelay) { always_delay_policy.always_use_initial_delay = true; always_delay_policy.num_errors_to_ignore = 1; - TestBackoffEntry entry(&always_delay_policy); + TestTickClock now_ticks; + BackoffEntry entry(&always_delay_policy, &now_ticks); // Failure count 1. entry.InformOfRequest(false); @@ -248,7 +246,7 @@ TEST(BackoffEntryTest, FailureThenSuccessAlwaysDelay) { // Failure count 2. entry.InformOfRequest(false); EXPECT_EQ(TimeDelta::FromMilliseconds(2000), entry.GetTimeUntilRelease()); - entry.set_now(entry.GetReleaseTime() + TimeDelta::FromMilliseconds(2000)); + now_ticks.set_now(entry.GetReleaseTime() + TimeDelta::FromMilliseconds(2000)); // Success. We should go back to the original delay. entry.InformOfRequest(true); @@ -257,23 +255,24 @@ TEST(BackoffEntryTest, FailureThenSuccessAlwaysDelay) { // Failure count reaches 2 again. We should increase the delay once more. entry.InformOfRequest(false); EXPECT_EQ(TimeDelta::FromMilliseconds(2000), entry.GetTimeUntilRelease()); - entry.set_now(entry.GetReleaseTime() + TimeDelta::FromMilliseconds(2000)); + now_ticks.set_now(entry.GetReleaseTime() + TimeDelta::FromMilliseconds(2000)); } TEST(BackoffEntryTest, RetainCustomHorizon) { - TestBackoffEntry custom(&base_policy); + TestTickClock now_ticks; + BackoffEntry custom(&base_policy, &now_ticks); TimeTicks custom_horizon = TimeTicks() + TimeDelta::FromDays(3); custom.SetCustomReleaseTime(custom_horizon); custom.InformOfRequest(false); custom.InformOfRequest(true); - custom.set_now(TimeTicks() + TimeDelta::FromDays(2)); + now_ticks.set_now(TimeTicks() + TimeDelta::FromDays(2)); custom.InformOfRequest(false); custom.InformOfRequest(true); EXPECT_EQ(custom_horizon, custom.GetReleaseTime()); // Now check that once we are at or past the custom horizon, // we get normal behavior. - custom.set_now(TimeTicks() + TimeDelta::FromDays(3)); + now_ticks.set_now(TimeTicks() + TimeDelta::FromDays(3)); custom.InformOfRequest(false); EXPECT_EQ( TimeTicks() + TimeDelta::FromDays(3) + TimeDelta::FromMilliseconds(1000), @@ -284,7 +283,8 @@ TEST(BackoffEntryTest, RetainCustomHorizonWhenInitialErrorsIgnored) { // Regression test for a bug discovered during code review. BackoffEntry::Policy lenient_policy = base_policy; lenient_policy.num_errors_to_ignore = 1; - TestBackoffEntry custom(&lenient_policy); + TestTickClock now_ticks; + BackoffEntry custom(&lenient_policy, &now_ticks); TimeTicks custom_horizon = TimeTicks() + TimeDelta::FromDays(3); custom.SetCustomReleaseTime(custom_horizon); custom.InformOfRequest(false); // This must not reset the horizon. @@ -294,13 +294,14 @@ TEST(BackoffEntryTest, RetainCustomHorizonWhenInitialErrorsIgnored) { TEST(BackoffEntryTest, OverflowProtection) { BackoffEntry::Policy large_multiply_policy = base_policy; large_multiply_policy.multiply_factor = 256; - TestBackoffEntry custom(&large_multiply_policy); + TestTickClock now_ticks; + BackoffEntry custom(&large_multiply_policy, &now_ticks); // Trigger enough failures such that more than 11 bits of exponent are used // to represent the exponential backoff intermediate values. Given a multiply // factor of 256 (2^8), 129 iterations is enough: 2^(8*(129-1)) = 2^1024. for (int i = 0; i < 129; ++i) { - custom.set_now(custom.ImplGetTimeNow() + custom.GetTimeUntilRelease()); + now_ticks.set_now(now_ticks.NowTicks() + custom.GetTimeUntilRelease()); custom.InformOfRequest(false); ASSERT_TRUE(custom.ShouldRejectRequest()); } |