1177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko// Copyright 2015 The Chromium OS Authors. All rights reserved. 2177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko// Use of this source code is governed by a BSD-style license that can be 3177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko// found in the LICENSE file. 4177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 59ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko#include <brillo/backoff_entry.h> 6177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko#include <gtest/gtest.h> 7177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 8177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenkousing base::TimeDelta; 9177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenkousing base::TimeTicks; 10177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 119ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenkonamespace brillo { 12177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 13177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex VakulenkoBackoffEntry::Policy base_policy = { 0, 1000, 2.0, 0.0, 20000, 2000, false }; 14177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 15177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenkoclass TestBackoffEntry : public BackoffEntry { 16177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko public: 17177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko explicit TestBackoffEntry(const Policy* const policy) 18177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko : BackoffEntry(policy), 19177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko now_(TimeTicks()) { 20177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko // Work around initialization in constructor not picking up 21177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko // fake time. 22177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko SetCustomReleaseTime(TimeTicks()); 23177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko } 24177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 25177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko ~TestBackoffEntry() override {} 26177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 27177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko TimeTicks ImplGetTimeNow() const override { return now_; } 28177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 29177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko void set_now(const TimeTicks& now) { 30177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko now_ = now; 31177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko } 32177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 33177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko private: 34177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko TimeTicks now_; 35177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 36177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko DISALLOW_COPY_AND_ASSIGN(TestBackoffEntry); 37177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko}; 38177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 39177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex VakulenkoTEST(BackoffEntryTest, BaseTest) { 40177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko TestBackoffEntry entry(&base_policy); 41177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko EXPECT_FALSE(entry.ShouldRejectRequest()); 42177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko EXPECT_EQ(TimeDelta(), entry.GetTimeUntilRelease()); 43177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 44177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko entry.InformOfRequest(false); 45177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko EXPECT_TRUE(entry.ShouldRejectRequest()); 46177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko EXPECT_EQ(TimeDelta::FromMilliseconds(1000), entry.GetTimeUntilRelease()); 47177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko} 48177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 49177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex VakulenkoTEST(BackoffEntryTest, CanDiscardNeverExpires) { 50177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko BackoffEntry::Policy never_expires_policy = base_policy; 51177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko never_expires_policy.entry_lifetime_ms = -1; 52177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko TestBackoffEntry never_expires(&never_expires_policy); 53177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko EXPECT_FALSE(never_expires.CanDiscard()); 54177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko never_expires.set_now(TimeTicks() + TimeDelta::FromDays(100)); 55177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko EXPECT_FALSE(never_expires.CanDiscard()); 56177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko} 57177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 58177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex VakulenkoTEST(BackoffEntryTest, CanDiscard) { 59177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko TestBackoffEntry entry(&base_policy); 60177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko // Because lifetime is non-zero, we shouldn't be able to discard yet. 61177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko EXPECT_FALSE(entry.CanDiscard()); 62177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 63177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko // Test the "being used" case. 64177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko entry.InformOfRequest(false); 65177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko EXPECT_FALSE(entry.CanDiscard()); 66177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 67177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko // Test the case where there are errors but we can time out. 68177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko entry.set_now( 69177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko entry.GetReleaseTime() + TimeDelta::FromMilliseconds(1)); 70177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko EXPECT_FALSE(entry.CanDiscard()); 71177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko entry.set_now(entry.GetReleaseTime() + TimeDelta::FromMilliseconds( 72177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko base_policy.maximum_backoff_ms + 1)); 73177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko EXPECT_TRUE(entry.CanDiscard()); 74177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 75177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko // Test the final case (no errors, dependent only on specified lifetime). 76177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko entry.set_now(entry.GetReleaseTime() + TimeDelta::FromMilliseconds( 77177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko base_policy.entry_lifetime_ms - 1)); 78177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko entry.InformOfRequest(true); 79177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko EXPECT_FALSE(entry.CanDiscard()); 80177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko entry.set_now(entry.GetReleaseTime() + TimeDelta::FromMilliseconds( 81177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko base_policy.entry_lifetime_ms)); 82177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko EXPECT_TRUE(entry.CanDiscard()); 83177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko} 84177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 85177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex VakulenkoTEST(BackoffEntryTest, CanDiscardAlwaysDelay) { 86177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko BackoffEntry::Policy always_delay_policy = base_policy; 87177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko always_delay_policy.always_use_initial_delay = true; 88177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko always_delay_policy.entry_lifetime_ms = 0; 89177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 90177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko TestBackoffEntry entry(&always_delay_policy); 91177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 92177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko // Because lifetime is non-zero, we shouldn't be able to discard yet. 93177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko entry.set_now(entry.GetReleaseTime() + TimeDelta::FromMilliseconds(2000)); 94177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko EXPECT_TRUE(entry.CanDiscard()); 95177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 96177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko // Even with no failures, we wait until the delay before we allow discard. 97177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko entry.InformOfRequest(true); 98177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko EXPECT_FALSE(entry.CanDiscard()); 99177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 100177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko // Wait until the delay expires, and we can discard the entry again. 101177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko entry.set_now(entry.GetReleaseTime() + TimeDelta::FromMilliseconds(1000)); 102177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko EXPECT_TRUE(entry.CanDiscard()); 103177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko} 104177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 105177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex VakulenkoTEST(BackoffEntryTest, CanDiscardNotStored) { 106177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko BackoffEntry::Policy no_store_policy = base_policy; 107177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko no_store_policy.entry_lifetime_ms = 0; 108177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko TestBackoffEntry not_stored(&no_store_policy); 109177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko EXPECT_TRUE(not_stored.CanDiscard()); 110177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko} 111177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 112177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex VakulenkoTEST(BackoffEntryTest, ShouldIgnoreFirstTwo) { 113177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko BackoffEntry::Policy lenient_policy = base_policy; 114177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko lenient_policy.num_errors_to_ignore = 2; 115177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 116177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko BackoffEntry entry(&lenient_policy); 117177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 118177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko entry.InformOfRequest(false); 119177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko EXPECT_FALSE(entry.ShouldRejectRequest()); 120177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 121177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko entry.InformOfRequest(false); 122177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko EXPECT_FALSE(entry.ShouldRejectRequest()); 123177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 124177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko entry.InformOfRequest(false); 125177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko EXPECT_TRUE(entry.ShouldRejectRequest()); 126177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko} 127177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 128177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex VakulenkoTEST(BackoffEntryTest, ReleaseTimeCalculation) { 129177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko TestBackoffEntry entry(&base_policy); 130177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 131177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko // With zero errors, should return "now". 132177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko TimeTicks result = entry.GetReleaseTime(); 133177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko EXPECT_EQ(entry.ImplGetTimeNow(), result); 134177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 135177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko // 1 error. 136177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko entry.InformOfRequest(false); 137177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko result = entry.GetReleaseTime(); 138177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko EXPECT_EQ(entry.ImplGetTimeNow() + TimeDelta::FromMilliseconds(1000), result); 139177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko EXPECT_EQ(TimeDelta::FromMilliseconds(1000), entry.GetTimeUntilRelease()); 140177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 141177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko // 2 errors. 142177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko entry.InformOfRequest(false); 143177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko result = entry.GetReleaseTime(); 144177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko EXPECT_EQ(entry.ImplGetTimeNow() + TimeDelta::FromMilliseconds(2000), result); 145177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko EXPECT_EQ(TimeDelta::FromMilliseconds(2000), entry.GetTimeUntilRelease()); 146177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 147177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko // 3 errors. 148177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko entry.InformOfRequest(false); 149177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko result = entry.GetReleaseTime(); 150177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko EXPECT_EQ(entry.ImplGetTimeNow() + TimeDelta::FromMilliseconds(4000), result); 151177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko EXPECT_EQ(TimeDelta::FromMilliseconds(4000), entry.GetTimeUntilRelease()); 152177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 153177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko // 6 errors (to check it doesn't pass maximum). 154177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko entry.InformOfRequest(false); 155177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko entry.InformOfRequest(false); 156177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko entry.InformOfRequest(false); 157177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko result = entry.GetReleaseTime(); 158177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko EXPECT_EQ( 159177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko entry.ImplGetTimeNow() + TimeDelta::FromMilliseconds(20000), result); 160177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko} 161177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 162177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex VakulenkoTEST(BackoffEntryTest, ReleaseTimeCalculationAlwaysDelay) { 163177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko BackoffEntry::Policy always_delay_policy = base_policy; 164177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko always_delay_policy.always_use_initial_delay = true; 165177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko always_delay_policy.num_errors_to_ignore = 2; 166177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 167177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko TestBackoffEntry entry(&always_delay_policy); 168177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 169177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko // With previous requests, should return "now". 170177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko TimeTicks result = entry.GetReleaseTime(); 171177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko EXPECT_EQ(TimeDelta(), entry.GetTimeUntilRelease()); 172177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 173177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko // 1 error. 174177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko entry.InformOfRequest(false); 175177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko EXPECT_EQ(TimeDelta::FromMilliseconds(1000), entry.GetTimeUntilRelease()); 176177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 177177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko // 2 errors. 178177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko entry.InformOfRequest(false); 179177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko EXPECT_EQ(TimeDelta::FromMilliseconds(1000), entry.GetTimeUntilRelease()); 180177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 181177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko // 3 errors, exponential backoff starts. 182177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko entry.InformOfRequest(false); 183177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko EXPECT_EQ(TimeDelta::FromMilliseconds(2000), entry.GetTimeUntilRelease()); 184177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 185177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko // 4 errors. 186177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko entry.InformOfRequest(false); 187177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko EXPECT_EQ(TimeDelta::FromMilliseconds(4000), entry.GetTimeUntilRelease()); 188177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 189177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko // 8 errors (to check it doesn't pass maximum). 190177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko entry.InformOfRequest(false); 191177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko entry.InformOfRequest(false); 192177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko entry.InformOfRequest(false); 193177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko entry.InformOfRequest(false); 194177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko result = entry.GetReleaseTime(); 195177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko EXPECT_EQ(TimeDelta::FromMilliseconds(20000), entry.GetTimeUntilRelease()); 196177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko} 197177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 198177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex VakulenkoTEST(BackoffEntryTest, ReleaseTimeCalculationWithJitter) { 199177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko for (int i = 0; i < 10; ++i) { 200177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko BackoffEntry::Policy jittery_policy = base_policy; 201177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko jittery_policy.jitter_factor = 0.2; 202177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 203177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko TestBackoffEntry entry(&jittery_policy); 204177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 205177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko entry.InformOfRequest(false); 206177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko entry.InformOfRequest(false); 207177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko entry.InformOfRequest(false); 208177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko TimeTicks result = entry.GetReleaseTime(); 209177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko EXPECT_LE( 210177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko entry.ImplGetTimeNow() + TimeDelta::FromMilliseconds(3200), result); 211177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko EXPECT_GE( 212177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko entry.ImplGetTimeNow() + TimeDelta::FromMilliseconds(4000), result); 213177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko } 214177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko} 215177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 216177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex VakulenkoTEST(BackoffEntryTest, FailureThenSuccess) { 217177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko TestBackoffEntry entry(&base_policy); 218177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 219177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko // Failure count 1, establishes horizon. 220177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko entry.InformOfRequest(false); 221177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko TimeTicks release_time = entry.GetReleaseTime(); 222177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko EXPECT_EQ(TimeTicks() + TimeDelta::FromMilliseconds(1000), release_time); 223177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 224177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko // Success, failure count 0, should not advance past 225177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko // the horizon that was already set. 226177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko entry.set_now(release_time - TimeDelta::FromMilliseconds(200)); 227177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko entry.InformOfRequest(true); 228177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko EXPECT_EQ(release_time, entry.GetReleaseTime()); 229177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 230177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko // Failure, failure count 1. 231177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko entry.InformOfRequest(false); 232177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko EXPECT_EQ(release_time + TimeDelta::FromMilliseconds(800), 233177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko entry.GetReleaseTime()); 234177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko} 235177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 236177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex VakulenkoTEST(BackoffEntryTest, FailureThenSuccessAlwaysDelay) { 237177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko BackoffEntry::Policy always_delay_policy = base_policy; 238177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko always_delay_policy.always_use_initial_delay = true; 239177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko always_delay_policy.num_errors_to_ignore = 1; 240177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 241177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko TestBackoffEntry entry(&always_delay_policy); 242177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 243177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko // Failure count 1. 244177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko entry.InformOfRequest(false); 245177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko EXPECT_EQ(TimeDelta::FromMilliseconds(1000), entry.GetTimeUntilRelease()); 246177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 247177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko // Failure count 2. 248177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko entry.InformOfRequest(false); 249177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko EXPECT_EQ(TimeDelta::FromMilliseconds(2000), entry.GetTimeUntilRelease()); 250177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko entry.set_now(entry.GetReleaseTime() + TimeDelta::FromMilliseconds(2000)); 251177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 252177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko // Success. We should go back to the original delay. 253177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko entry.InformOfRequest(true); 254177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko EXPECT_EQ(TimeDelta::FromMilliseconds(1000), entry.GetTimeUntilRelease()); 255177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 256177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko // Failure count reaches 2 again. We should increase the delay once more. 257177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko entry.InformOfRequest(false); 258177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko EXPECT_EQ(TimeDelta::FromMilliseconds(2000), entry.GetTimeUntilRelease()); 259177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko entry.set_now(entry.GetReleaseTime() + TimeDelta::FromMilliseconds(2000)); 260177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko} 261177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 262177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex VakulenkoTEST(BackoffEntryTest, RetainCustomHorizon) { 263177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko TestBackoffEntry custom(&base_policy); 264177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko TimeTicks custom_horizon = TimeTicks() + TimeDelta::FromDays(3); 265177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko custom.SetCustomReleaseTime(custom_horizon); 266177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko custom.InformOfRequest(false); 267177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko custom.InformOfRequest(true); 268177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko custom.set_now(TimeTicks() + TimeDelta::FromDays(2)); 269177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko custom.InformOfRequest(false); 270177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko custom.InformOfRequest(true); 271177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko EXPECT_EQ(custom_horizon, custom.GetReleaseTime()); 272177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 273177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko // Now check that once we are at or past the custom horizon, 274177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko // we get normal behavior. 275177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko custom.set_now(TimeTicks() + TimeDelta::FromDays(3)); 276177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko custom.InformOfRequest(false); 277177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko EXPECT_EQ( 278177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko TimeTicks() + TimeDelta::FromDays(3) + TimeDelta::FromMilliseconds(1000), 279177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko custom.GetReleaseTime()); 280177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko} 281177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 282177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex VakulenkoTEST(BackoffEntryTest, RetainCustomHorizonWhenInitialErrorsIgnored) { 283177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko // Regression test for a bug discovered during code review. 284177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko BackoffEntry::Policy lenient_policy = base_policy; 285177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko lenient_policy.num_errors_to_ignore = 1; 286177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko TestBackoffEntry custom(&lenient_policy); 287177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko TimeTicks custom_horizon = TimeTicks() + TimeDelta::FromDays(3); 288177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko custom.SetCustomReleaseTime(custom_horizon); 289177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko custom.InformOfRequest(false); // This must not reset the horizon. 290177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko EXPECT_EQ(custom_horizon, custom.GetReleaseTime()); 291177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko} 292177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 293177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex VakulenkoTEST(BackoffEntryTest, OverflowProtection) { 294177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko BackoffEntry::Policy large_multiply_policy = base_policy; 295177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko large_multiply_policy.multiply_factor = 256; 296177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko TestBackoffEntry custom(&large_multiply_policy); 297177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 298177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko // Trigger enough failures such that more than 11 bits of exponent are used 299177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko // to represent the exponential backoff intermediate values. Given a multiply 300177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko // factor of 256 (2^8), 129 iterations is enough: 2^(8*(129-1)) = 2^1024. 301177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko for (int i = 0; i < 129; ++i) { 3029ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko custom.set_now(custom.ImplGetTimeNow() + custom.GetTimeUntilRelease()); 3039ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko custom.InformOfRequest(false); 3049ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko ASSERT_TRUE(custom.ShouldRejectRequest()); 305177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko } 306177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 307177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko // Max delay should still be respected. 308177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko EXPECT_EQ(20000, custom.GetTimeUntilRelease().InMilliseconds()); 309177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko} 310177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko 311177ddccf5dbb585aa8bab8482fa062d3a8858bc7Alex Vakulenko} // namespace 312