| OLD | NEW |
| (Empty) | |
| 1 // Copyright (c) 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "net/http/http_broken_alternative_services_manager.h" |
| 6 |
| 7 #include <vector> |
| 8 |
| 9 #include "base/test/test_mock_time_task_runner.h" |
| 10 #include "base/time/time.h" |
| 11 #include "testing/gtest/include/gtest/gtest.h" |
| 12 |
| 13 namespace net { |
| 14 |
| 15 namespace { |
| 16 |
| 17 class TestClock : public HttpBrokenAlternativeServicesManager::Clock { |
| 18 public: |
| 19 TestClock() : now_(base::TimeTicks::Now()) {} |
| 20 ~TestClock() override {} |
| 21 |
| 22 base::TimeTicks Now() const override { return now_; } |
| 23 |
| 24 void Set(base::TimeTicks now) { now_ = now; } |
| 25 void Advance(base::TimeDelta delta) { now_ += delta; } |
| 26 |
| 27 private: |
| 28 base::TimeTicks now_; |
| 29 }; |
| 30 |
| 31 class HttpBrokenAlternativeServicesManagerTest |
| 32 : public HttpBrokenAlternativeServicesManager::Delegate, |
| 33 public ::testing::Test { |
| 34 public: |
| 35 HttpBrokenAlternativeServicesManagerTest() |
| 36 : manager_(this, &test_clock_), |
| 37 test_task_runner_(new base::TestMockTimeTaskRunner()) {} |
| 38 |
| 39 // HttpBrokenAlternativeServicesManager::Delegate implementation |
| 40 void OnExpireBrokenAlternativeService( |
| 41 const AlternativeService& expired_alternative_service) override { |
| 42 expired_alt_svcs.push_back(expired_alternative_service); |
| 43 } |
| 44 |
| 45 ::testing::AssertionResult MarkAlternativeServiceBrokenAndLetExpireNTimes( |
| 46 const AlternativeService& alternative_service, |
| 47 int num_times) { |
| 48 for (int i = 0; i < num_times; ++i) { |
| 49 { |
| 50 base::TestMockTimeTaskRunner::ScopedContext scoped_context( |
| 51 test_task_runner_); |
| 52 manager_.MarkAlternativeServiceBroken(alternative_service); |
| 53 } |
| 54 if (!manager_.IsAlternativeServiceBroken(alternative_service)) { |
| 55 return ::testing::AssertionFailure() << "Alt svc not showing as broken " |
| 56 << "after being marked broken."; |
| 57 } |
| 58 |
| 59 // |manager_| should have posted task to expire the brokenness of |
| 60 // |alternative_service|. |
| 61 int pending_task_count = test_task_runner_->GetPendingTaskCount(); |
| 62 if (pending_task_count != 1u) { |
| 63 return ::testing::AssertionFailure() |
| 64 << "Test task runner has " << pending_task_count |
| 65 << " pending tasks instead of 1 after marking " |
| 66 << "alternative service broken."; |
| 67 } |
| 68 |
| 69 // Advance time by just enough so that |alternative_service|'s brokenness |
| 70 // expires. |
| 71 base::TimeDelta delta = HttpBrokenAlternativeServicesManager:: |
| 72 ComputeBrokenAltSvcExpirationDelayForTest(i); |
| 73 test_clock_.Advance(delta); |
| 74 test_task_runner_->FastForwardBy(delta); |
| 75 |
| 76 // Ensure |alternative_service| brokenness has expired |
| 77 if (manager_.IsAlternativeServiceBroken(alternative_service)) { |
| 78 return ::testing::AssertionFailure() << "Alt svc showing as broken " |
| 79 << " after being confirmed."; |
| 80 } |
| 81 } |
| 82 return ::testing::AssertionSuccess(); |
| 83 } |
| 84 |
| 85 TestClock test_clock_; |
| 86 std::vector<AlternativeService> expired_alt_svcs; |
| 87 HttpBrokenAlternativeServicesManager manager_; |
| 88 |
| 89 scoped_refptr<base::TestMockTimeTaskRunner> test_task_runner_; |
| 90 }; |
| 91 |
| 92 TEST_F(HttpBrokenAlternativeServicesManagerTest, MarkBroken) { |
| 93 const AlternativeService alternative_service1(kProtoHTTP2, "foo", 443); |
| 94 const AlternativeService alternative_service2(kProtoHTTP2, "foo", 1234); |
| 95 |
| 96 EXPECT_FALSE(manager_.IsAlternativeServiceBroken(alternative_service1)); |
| 97 EXPECT_FALSE(manager_.IsAlternativeServiceBroken(alternative_service2)); |
| 98 |
| 99 manager_.MarkAlternativeServiceBroken(alternative_service1); |
| 100 |
| 101 EXPECT_TRUE(manager_.IsAlternativeServiceBroken(alternative_service1)); |
| 102 EXPECT_FALSE(manager_.IsAlternativeServiceBroken(alternative_service2)); |
| 103 |
| 104 manager_.MarkAlternativeServiceBroken(alternative_service2); |
| 105 |
| 106 EXPECT_TRUE(manager_.IsAlternativeServiceBroken(alternative_service1)); |
| 107 EXPECT_TRUE(manager_.IsAlternativeServiceBroken(alternative_service2)); |
| 108 |
| 109 manager_.ConfirmAlternativeService(alternative_service1); |
| 110 |
| 111 EXPECT_FALSE(manager_.IsAlternativeServiceBroken(alternative_service1)); |
| 112 EXPECT_TRUE(manager_.IsAlternativeServiceBroken(alternative_service2)); |
| 113 |
| 114 manager_.ConfirmAlternativeService(alternative_service2); |
| 115 |
| 116 EXPECT_FALSE(manager_.IsAlternativeServiceBroken(alternative_service1)); |
| 117 EXPECT_FALSE(manager_.IsAlternativeServiceBroken(alternative_service2)); |
| 118 } |
| 119 |
| 120 TEST_F(HttpBrokenAlternativeServicesManagerTest, MarkRecentlyBroken) { |
| 121 const AlternativeService alternative_service(kProtoHTTP2, "foo", 443); |
| 122 |
| 123 EXPECT_FALSE(manager_.IsAlternativeServiceBroken(alternative_service)); |
| 124 EXPECT_FALSE( |
| 125 manager_.WasAlternativeServiceRecentlyBroken(alternative_service)); |
| 126 |
| 127 manager_.MarkAlternativeServiceRecentlyBroken(alternative_service); |
| 128 EXPECT_FALSE(manager_.IsAlternativeServiceBroken(alternative_service)); |
| 129 EXPECT_TRUE( |
| 130 manager_.WasAlternativeServiceRecentlyBroken(alternative_service)); |
| 131 |
| 132 manager_.ConfirmAlternativeService(alternative_service); |
| 133 EXPECT_FALSE(manager_.IsAlternativeServiceBroken(alternative_service)); |
| 134 EXPECT_FALSE( |
| 135 manager_.WasAlternativeServiceRecentlyBroken(alternative_service)); |
| 136 } |
| 137 |
| 138 TEST_F(HttpBrokenAlternativeServicesManagerTest, |
| 139 ExpireBrokenAlternateProtoclMappings) { |
| 140 AlternativeService alternative_service(kProtoQUIC, "foo", 443); |
| 141 |
| 142 EXPECT_FALSE(manager_.IsAlternativeServiceBroken(alternative_service)); |
| 143 EXPECT_FALSE( |
| 144 manager_.WasAlternativeServiceRecentlyBroken(alternative_service)); |
| 145 |
| 146 EXPECT_TRUE( |
| 147 MarkAlternativeServiceBrokenAndLetExpireNTimes(alternative_service, 1)); |
| 148 } |
| 149 |
| 150 TEST_F(HttpBrokenAlternativeServicesManagerTest, RemoveExpiredBrokenAltSvc) { |
| 151 // This test will mark broken an alternative service A that has already been |
| 152 // marked broken many times, then immediately mark another alternative service |
| 153 // B as broken for the first time. Because A's been marked broken many times |
| 154 // already, its brokenness will be scheduled to expire much further in the |
| 155 // future than B, even though it was marked broken before B. This test makes |
| 156 // sure that even though A was marked broken before B, B's brokenness should |
| 157 // expire before A. |
| 158 |
| 159 // This test only makes sense if HttpServerPropertiesImpl's expiration delay |
| 160 // for a broken AlternativeService is an increasing function of how many times |
| 161 // that AlternativeService has been marked broken already. |
| 162 DCHECK(HttpBrokenAlternativeServicesManager:: |
| 163 ComputeBrokenAltSvcExpirationDelayForTest(3) > |
| 164 HttpBrokenAlternativeServicesManager:: |
| 165 ComputeBrokenAltSvcExpirationDelayForTest(0)); |
| 166 |
| 167 AlternativeService alternative_service1(kProtoQUIC, "foo", 443); |
| 168 AlternativeService alternative_service2(kProtoQUIC, "bar", 443); |
| 169 |
| 170 EXPECT_TRUE( |
| 171 MarkAlternativeServiceBrokenAndLetExpireNTimes(alternative_service1, 3)); |
| 172 |
| 173 { |
| 174 base::TestMockTimeTaskRunner::ScopedContext scoped_context( |
| 175 test_task_runner_); |
| 176 |
| 177 manager_.MarkAlternativeServiceBroken(alternative_service1); |
| 178 manager_.MarkAlternativeServiceBroken(alternative_service2); |
| 179 } |
| 180 EXPECT_TRUE(manager_.IsAlternativeServiceBroken(alternative_service1)); |
| 181 EXPECT_TRUE(manager_.IsAlternativeServiceBroken(alternative_service2)); |
| 182 |
| 183 // Advance time until one time quantum before |alternative_service2|'s |
| 184 // brokenness expires. |
| 185 base::TimeDelta delta = HttpBrokenAlternativeServicesManager:: |
| 186 ComputeBrokenAltSvcExpirationDelayForTest(0) - |
| 187 base::TimeDelta::FromInternalValue(1); |
| 188 test_clock_.Advance(delta); |
| 189 test_task_runner_->FastForwardBy(delta); |
| 190 |
| 191 EXPECT_TRUE(manager_.IsAlternativeServiceBroken(alternative_service1)); |
| 192 EXPECT_TRUE(manager_.IsAlternativeServiceBroken(alternative_service2)); |
| 193 |
| 194 // Advance time by one time quantum. |alternative_service2| should no longer |
| 195 // be broken. |
| 196 delta = base::TimeDelta::FromInternalValue(1); |
| 197 test_clock_.Advance(delta); |
| 198 test_task_runner_->FastForwardBy(delta); |
| 199 |
| 200 EXPECT_TRUE(manager_.IsAlternativeServiceBroken(alternative_service1)); |
| 201 EXPECT_FALSE(manager_.IsAlternativeServiceBroken(alternative_service2)); |
| 202 |
| 203 // Advance time until one time quantum before |alternative_service1|'s |
| 204 // brokenness expires |
| 205 delta = HttpBrokenAlternativeServicesManager:: |
| 206 ComputeBrokenAltSvcExpirationDelayForTest(3) - |
| 207 HttpBrokenAlternativeServicesManager:: |
| 208 ComputeBrokenAltSvcExpirationDelayForTest(0) - |
| 209 base::TimeDelta::FromInternalValue(1); |
| 210 test_clock_.Advance(delta); |
| 211 test_task_runner_->FastForwardBy(delta); |
| 212 |
| 213 EXPECT_TRUE(manager_.IsAlternativeServiceBroken(alternative_service1)); |
| 214 EXPECT_FALSE(manager_.IsAlternativeServiceBroken(alternative_service2)); |
| 215 |
| 216 // Advance time by one time quantum. |alternative_service1| should no longer |
| 217 // be broken. |
| 218 delta = base::TimeDelta::FromInternalValue(1); |
| 219 test_clock_.Advance(delta); |
| 220 test_task_runner_->FastForwardBy(delta); |
| 221 |
| 222 EXPECT_FALSE(manager_.IsAlternativeServiceBroken(alternative_service1)); |
| 223 EXPECT_FALSE(manager_.IsAlternativeServiceBroken(alternative_service2)); |
| 224 } |
| 225 |
| 226 } // namespace |
| 227 |
| 228 } // namespace net |
| OLD | NEW |