15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/backoff_entry.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::TimeDelta;
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::TimeTicks;
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using net::BackoffEntry;
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BackoffEntry::Policy base_policy = { 0, 1000, 2.0, 0.0, 20000, 2000, false };
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestBackoffEntry : public BackoffEntry {
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit TestBackoffEntry(const Policy* const policy)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : BackoffEntry(policy),
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        now_(TimeTicks()) {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Work around initialization in constructor not picking up
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // fake time.
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetCustomReleaseTime(TimeTicks());
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~TestBackoffEntry() {}
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual TimeTicks ImplGetTimeNow() const OVERRIDE {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return now_;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_now(const TimeTicks& now) {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    now_ = now;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeTicks now_;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TestBackoffEntry);
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(BackoffEntryTest, BaseTest) {
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestBackoffEntry entry(&base_policy);
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(entry.ShouldRejectRequest());
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(TimeDelta(), entry.GetTimeUntilRelease());
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry.InformOfRequest(false);
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(entry.ShouldRejectRequest());
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(TimeDelta::FromMilliseconds(1000), entry.GetTimeUntilRelease());
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(BackoffEntryTest, CanDiscardNeverExpires) {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BackoffEntry::Policy never_expires_policy = base_policy;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  never_expires_policy.entry_lifetime_ms = -1;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestBackoffEntry never_expires(&never_expires_policy);
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(never_expires.CanDiscard());
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  never_expires.set_now(TimeTicks() + TimeDelta::FromDays(100));
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(never_expires.CanDiscard());
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(BackoffEntryTest, CanDiscard) {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestBackoffEntry entry(&base_policy);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Because lifetime is non-zero, we shouldn't be able to discard yet.
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(entry.CanDiscard());
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test the "being used" case.
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry.InformOfRequest(false);
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(entry.CanDiscard());
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test the case where there are errors but we can time out.
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry.set_now(
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entry.GetReleaseTime() + TimeDelta::FromMilliseconds(1));
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(entry.CanDiscard());
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry.set_now(entry.GetReleaseTime() + TimeDelta::FromMilliseconds(
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base_policy.maximum_backoff_ms + 1));
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(entry.CanDiscard());
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test the final case (no errors, dependent only on specified lifetime).
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry.set_now(entry.GetReleaseTime() + TimeDelta::FromMilliseconds(
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base_policy.entry_lifetime_ms - 1));
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry.InformOfRequest(true);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(entry.CanDiscard());
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry.set_now(entry.GetReleaseTime() + TimeDelta::FromMilliseconds(
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base_policy.entry_lifetime_ms));
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(entry.CanDiscard());
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(BackoffEntryTest, CanDiscardAlwaysDelay) {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BackoffEntry::Policy always_delay_policy = base_policy;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  always_delay_policy.always_use_initial_delay = true;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  always_delay_policy.entry_lifetime_ms = 0;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestBackoffEntry entry(&always_delay_policy);
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Because lifetime is non-zero, we shouldn't be able to discard yet.
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry.set_now(entry.GetReleaseTime() + TimeDelta::FromMilliseconds(2000));
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(entry.CanDiscard());
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Even with no failures, we wait until the delay before we allow discard.
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry.InformOfRequest(true);
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(entry.CanDiscard());
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wait until the delay expires, and we can discard the entry again.
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry.set_now(entry.GetReleaseTime() + TimeDelta::FromMilliseconds(1000));
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(entry.CanDiscard());
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(BackoffEntryTest, CanDiscardNotStored) {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BackoffEntry::Policy no_store_policy = base_policy;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  no_store_policy.entry_lifetime_ms = 0;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestBackoffEntry not_stored(&no_store_policy);
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(not_stored.CanDiscard());
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(BackoffEntryTest, ShouldIgnoreFirstTwo) {
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BackoffEntry::Policy lenient_policy = base_policy;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  lenient_policy.num_errors_to_ignore = 2;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BackoffEntry entry(&lenient_policy);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry.InformOfRequest(false);
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(entry.ShouldRejectRequest());
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry.InformOfRequest(false);
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(entry.ShouldRejectRequest());
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry.InformOfRequest(false);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(entry.ShouldRejectRequest());
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(BackoffEntryTest, ReleaseTimeCalculation) {
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestBackoffEntry entry(&base_policy);
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // With zero errors, should return "now".
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeTicks result = entry.GetReleaseTime();
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(entry.ImplGetTimeNow(), result);
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 1 error.
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry.InformOfRequest(false);
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result = entry.GetReleaseTime();
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(entry.ImplGetTimeNow() + TimeDelta::FromMilliseconds(1000), result);
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(TimeDelta::FromMilliseconds(1000), entry.GetTimeUntilRelease());
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 2 errors.
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry.InformOfRequest(false);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result = entry.GetReleaseTime();
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(entry.ImplGetTimeNow() + TimeDelta::FromMilliseconds(2000), result);
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(TimeDelta::FromMilliseconds(2000), entry.GetTimeUntilRelease());
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 3 errors.
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry.InformOfRequest(false);
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result = entry.GetReleaseTime();
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(entry.ImplGetTimeNow() + TimeDelta::FromMilliseconds(4000), result);
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(TimeDelta::FromMilliseconds(4000), entry.GetTimeUntilRelease());
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 6 errors (to check it doesn't pass maximum).
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry.InformOfRequest(false);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry.InformOfRequest(false);
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry.InformOfRequest(false);
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result = entry.GetReleaseTime();
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entry.ImplGetTimeNow() + TimeDelta::FromMilliseconds(20000), result);
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(BackoffEntryTest, ReleaseTimeCalculationAlwaysDelay) {
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BackoffEntry::Policy always_delay_policy = base_policy;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  always_delay_policy.always_use_initial_delay = true;
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  always_delay_policy.num_errors_to_ignore = 2;
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestBackoffEntry entry(&always_delay_policy);
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // With previous requests, should return "now".
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeTicks result = entry.GetReleaseTime();
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(TimeDelta(), entry.GetTimeUntilRelease());
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 1 error.
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry.InformOfRequest(false);
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(TimeDelta::FromMilliseconds(1000), entry.GetTimeUntilRelease());
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 2 errors.
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry.InformOfRequest(false);
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(TimeDelta::FromMilliseconds(1000), entry.GetTimeUntilRelease());
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 3 errors, exponential backoff starts.
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry.InformOfRequest(false);
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(TimeDelta::FromMilliseconds(2000), entry.GetTimeUntilRelease());
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 4 errors.
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry.InformOfRequest(false);
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(TimeDelta::FromMilliseconds(4000), entry.GetTimeUntilRelease());
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 8 errors (to check it doesn't pass maximum).
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry.InformOfRequest(false);
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry.InformOfRequest(false);
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry.InformOfRequest(false);
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry.InformOfRequest(false);
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result = entry.GetReleaseTime();
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(TimeDelta::FromMilliseconds(20000), entry.GetTimeUntilRelease());
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(BackoffEntryTest, ReleaseTimeCalculationWithJitter) {
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < 10; ++i) {
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BackoffEntry::Policy jittery_policy = base_policy;
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    jittery_policy.jitter_factor = 0.2;
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestBackoffEntry entry(&jittery_policy);
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    entry.InformOfRequest(false);
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    entry.InformOfRequest(false);
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    entry.InformOfRequest(false);
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TimeTicks result = entry.GetReleaseTime();
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_LE(
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        entry.ImplGetTimeNow() + TimeDelta::FromMilliseconds(3200), result);
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_GE(
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        entry.ImplGetTimeNow() + TimeDelta::FromMilliseconds(4000), result);
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(BackoffEntryTest, FailureThenSuccess) {
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestBackoffEntry entry(&base_policy);
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Failure count 1, establishes horizon.
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry.InformOfRequest(false);
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeTicks release_time = entry.GetReleaseTime();
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(TimeTicks() + TimeDelta::FromMilliseconds(1000), release_time);
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Success, failure count 0, should not advance past
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the horizon that was already set.
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry.set_now(release_time - TimeDelta::FromMilliseconds(200));
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry.InformOfRequest(true);
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(release_time, entry.GetReleaseTime());
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Failure, failure count 1.
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry.InformOfRequest(false);
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(release_time + TimeDelta::FromMilliseconds(800),
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            entry.GetReleaseTime());
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(BackoffEntryTest, FailureThenSuccessAlwaysDelay) {
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BackoffEntry::Policy always_delay_policy = base_policy;
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  always_delay_policy.always_use_initial_delay = true;
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  always_delay_policy.num_errors_to_ignore = 1;
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestBackoffEntry entry(&always_delay_policy);
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Failure count 1.
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry.InformOfRequest(false);
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(TimeDelta::FromMilliseconds(1000), entry.GetTimeUntilRelease());
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Failure count 2.
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry.InformOfRequest(false);
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(TimeDelta::FromMilliseconds(2000), entry.GetTimeUntilRelease());
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry.set_now(entry.GetReleaseTime() + TimeDelta::FromMilliseconds(2000));
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Success.  We should go back to the original delay.
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry.InformOfRequest(true);
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(TimeDelta::FromMilliseconds(1000), entry.GetTimeUntilRelease());
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Failure count reaches 2 again.  We should increase the delay once more.
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry.InformOfRequest(false);
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(TimeDelta::FromMilliseconds(2000), entry.GetTimeUntilRelease());
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry.set_now(entry.GetReleaseTime() + TimeDelta::FromMilliseconds(2000));
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(BackoffEntryTest, RetainCustomHorizon) {
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestBackoffEntry custom(&base_policy);
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeTicks custom_horizon = TimeTicks() + TimeDelta::FromDays(3);
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  custom.SetCustomReleaseTime(custom_horizon);
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  custom.InformOfRequest(false);
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  custom.InformOfRequest(true);
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  custom.set_now(TimeTicks() + TimeDelta::FromDays(2));
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  custom.InformOfRequest(false);
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  custom.InformOfRequest(true);
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(custom_horizon, custom.GetReleaseTime());
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now check that once we are at or past the custom horizon,
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // we get normal behavior.
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  custom.set_now(TimeTicks() + TimeDelta::FromDays(3));
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  custom.InformOfRequest(false);
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TimeTicks() + TimeDelta::FromDays(3) + TimeDelta::FromMilliseconds(1000),
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      custom.GetReleaseTime());
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(BackoffEntryTest, RetainCustomHorizonWhenInitialErrorsIgnored) {
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Regression test for a bug discovered during code review.
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BackoffEntry::Policy lenient_policy = base_policy;
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  lenient_policy.num_errors_to_ignore = 1;
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestBackoffEntry custom(&lenient_policy);
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeTicks custom_horizon = TimeTicks() + TimeDelta::FromDays(3);
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  custom.SetCustomReleaseTime(custom_horizon);
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  custom.InformOfRequest(false);  // This must not reset the horizon.
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(custom_horizon, custom.GetReleaseTime());
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
296f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST(BackoffEntryTest, OverflowProtection) {
297f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  BackoffEntry::Policy large_multiply_policy = base_policy;
298f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  large_multiply_policy.multiply_factor = 256;
299f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  TestBackoffEntry custom(&large_multiply_policy);
300f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
301f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Trigger enough failures such that more than 11 bits of exponent are used
302f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // to represent the exponential backoff intermediate values. Given a multiply
303f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // factor of 256 (2^8), 129 iterations is enough: 2^(8*(129-1)) = 2^1024.
304f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  for (int i = 0; i < 129; ++i) {
305f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)     custom.set_now(custom.ImplGetTimeNow() + custom.GetTimeUntilRelease());
306f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)     custom.InformOfRequest(false);
307f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)     ASSERT_TRUE(custom.ShouldRejectRequest());
308f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
309f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
310f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Max delay should still be respected.
311f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(20000, custom.GetTimeUntilRelease().InMilliseconds());
312f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
313f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
315