Chromium Code Reviews| 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/broken_alternative_services.h" | |
| 6 | |
| 7 #include <algorithm> | |
| 8 #include <vector> | |
| 9 | |
| 10 #include "base/test/test_mock_time_task_runner.h" | |
| 11 #include "base/time/tick_clock.h" | |
| 12 #include "testing/gtest/include/gtest/gtest.h" | |
| 13 | |
| 14 namespace net { | |
| 15 | |
| 16 namespace { | |
| 17 | |
| 18 const base::TimeDelta BROKEN_ALT_SVC_EXPIRE_DELAYS[10] = { | |
| 19 base::TimeDelta::FromMinutes(5), base::TimeDelta::FromMinutes(10), | |
| 20 base::TimeDelta::FromMinutes(20), base::TimeDelta::FromMinutes(40), | |
| 21 base::TimeDelta::FromMinutes(80), base::TimeDelta::FromMinutes(160), | |
| 22 base::TimeDelta::FromMinutes(320), base::TimeDelta::FromMinutes(640), | |
| 23 base::TimeDelta::FromMinutes(1280), base::TimeDelta::FromMinutes(2560)}; | |
| 24 | |
| 25 class BrokenAlternativeServicesTest | |
| 26 : public BrokenAlternativeServices::Delegate, | |
| 27 public ::testing::Test { | |
| 28 public: | |
| 29 BrokenAlternativeServicesTest() | |
| 30 : test_task_runner_(new base::TestMockTimeTaskRunner()), | |
| 31 test_task_runner_context_(test_task_runner_), | |
| 32 broken_services_clock_(test_task_runner_->GetMockTickClock()), | |
| 33 broken_services_(this, broken_services_clock_.get()) {} | |
| 34 | |
| 35 // BrokenAlternativeServices::Delegate implementation | |
| 36 void OnExpireBrokenAlternativeService( | |
| 37 const AlternativeService& expired_alternative_service) override { | |
| 38 expired_alt_svcs_.push_back(expired_alternative_service); | |
| 39 } | |
| 40 | |
| 41 // All tests will run inside the scope of |test_task_runner_context_|, which | |
| 42 // means any task posted to the main message loop will run on | |
| 43 // |test_task_runner_|. | |
|
Ryan Hamilton
2017/05/30 21:32:28
nice comment!
wangyix1
2017/05/30 23:57:49
Acknowledged.
| |
| 44 scoped_refptr<base::TestMockTimeTaskRunner> test_task_runner_; | |
| 45 base::TestMockTimeTaskRunner::ScopedContext test_task_runner_context_; | |
| 46 | |
| 47 std::unique_ptr<base::TickClock> broken_services_clock_; | |
| 48 BrokenAlternativeServices broken_services_; | |
| 49 | |
| 50 std::vector<AlternativeService> expired_alt_svcs_; | |
| 51 }; | |
| 52 | |
| 53 TEST_F(BrokenAlternativeServicesTest, MarkBroken) { | |
| 54 const AlternativeService alternative_service1(kProtoHTTP2, "foo", 443); | |
| 55 const AlternativeService alternative_service2(kProtoHTTP2, "foo", 1234); | |
| 56 | |
| 57 EXPECT_FALSE( | |
| 58 broken_services_.IsAlternativeServiceBroken(alternative_service1)); | |
| 59 EXPECT_FALSE( | |
| 60 broken_services_.IsAlternativeServiceBroken(alternative_service2)); | |
| 61 | |
| 62 broken_services_.MarkAlternativeServiceBroken(alternative_service1); | |
| 63 | |
| 64 EXPECT_TRUE( | |
| 65 broken_services_.IsAlternativeServiceBroken(alternative_service1)); | |
| 66 EXPECT_FALSE( | |
| 67 broken_services_.IsAlternativeServiceBroken(alternative_service2)); | |
| 68 | |
| 69 broken_services_.MarkAlternativeServiceBroken(alternative_service2); | |
| 70 | |
| 71 EXPECT_TRUE( | |
| 72 broken_services_.IsAlternativeServiceBroken(alternative_service1)); | |
| 73 EXPECT_TRUE( | |
| 74 broken_services_.IsAlternativeServiceBroken(alternative_service2)); | |
| 75 | |
| 76 broken_services_.ConfirmAlternativeService(alternative_service1); | |
| 77 | |
| 78 EXPECT_FALSE( | |
| 79 broken_services_.IsAlternativeServiceBroken(alternative_service1)); | |
| 80 EXPECT_TRUE( | |
| 81 broken_services_.IsAlternativeServiceBroken(alternative_service2)); | |
| 82 | |
| 83 broken_services_.ConfirmAlternativeService(alternative_service2); | |
| 84 | |
| 85 EXPECT_FALSE( | |
| 86 broken_services_.IsAlternativeServiceBroken(alternative_service1)); | |
| 87 EXPECT_FALSE( | |
| 88 broken_services_.IsAlternativeServiceBroken(alternative_service2)); | |
| 89 | |
| 90 EXPECT_EQ(0u, expired_alt_svcs_.size()); | |
| 91 } | |
| 92 | |
| 93 TEST_F(BrokenAlternativeServicesTest, MarkRecentlyBroken) { | |
| 94 const AlternativeService alternative_service(kProtoHTTP2, "foo", 443); | |
| 95 | |
| 96 EXPECT_FALSE( | |
| 97 broken_services_.IsAlternativeServiceBroken(alternative_service)); | |
| 98 EXPECT_FALSE(broken_services_.WasAlternativeServiceRecentlyBroken( | |
| 99 alternative_service)); | |
| 100 | |
| 101 broken_services_.MarkAlternativeServiceRecentlyBroken(alternative_service); | |
| 102 EXPECT_FALSE( | |
| 103 broken_services_.IsAlternativeServiceBroken(alternative_service)); | |
| 104 EXPECT_TRUE(broken_services_.WasAlternativeServiceRecentlyBroken( | |
| 105 alternative_service)); | |
| 106 | |
| 107 broken_services_.ConfirmAlternativeService(alternative_service); | |
| 108 EXPECT_FALSE( | |
| 109 broken_services_.IsAlternativeServiceBroken(alternative_service)); | |
| 110 EXPECT_FALSE(broken_services_.WasAlternativeServiceRecentlyBroken( | |
| 111 alternative_service)); | |
| 112 } | |
| 113 | |
| 114 TEST_F(BrokenAlternativeServicesTest, ExpireBrokenAlternateProtocolMappings) { | |
| 115 AlternativeService alternative_service(kProtoQUIC, "foo", 443); | |
| 116 | |
| 117 broken_services_.MarkAlternativeServiceBroken(alternative_service); | |
| 118 | |
| 119 // |broken_services_| should have posted task to expire the brokenness of | |
| 120 // |alternative_service|. | |
| 121 EXPECT_EQ(1u, test_task_runner_->GetPendingTaskCount()); | |
| 122 | |
| 123 // Advance time until one time quantum before |alternative_service1|'s | |
| 124 // brokenness expires | |
| 125 test_task_runner_->FastForwardBy(base::TimeDelta::FromMinutes(5) - | |
| 126 base::TimeDelta::FromInternalValue(1)); | |
| 127 | |
| 128 // Ensure |alternative_service| is still marked broken. | |
| 129 EXPECT_TRUE(broken_services_.IsAlternativeServiceBroken(alternative_service)); | |
| 130 EXPECT_EQ(0u, expired_alt_svcs_.size()); | |
| 131 EXPECT_EQ(1u, test_task_runner_->GetPendingTaskCount()); | |
| 132 | |
| 133 // Advance time by one time quantum | |
| 134 test_task_runner_->FastForwardBy(base::TimeDelta::FromInternalValue(1)); | |
| 135 | |
| 136 // Ensure |alternative_service| brokenness has expired but is still | |
| 137 // considered recently broken | |
| 138 EXPECT_FALSE( | |
| 139 broken_services_.IsAlternativeServiceBroken(alternative_service)); | |
| 140 EXPECT_FALSE(test_task_runner_->HasPendingTask()); | |
| 141 EXPECT_EQ(1u, expired_alt_svcs_.size()); | |
| 142 EXPECT_EQ(alternative_service, expired_alt_svcs_[0]); | |
| 143 EXPECT_TRUE(broken_services_.WasAlternativeServiceRecentlyBroken( | |
| 144 alternative_service)); | |
| 145 } | |
| 146 | |
| 147 TEST_F(BrokenAlternativeServicesTest, ExponentialBackoff) { | |
| 148 // Tests the exponential backoff of the computed expiration delay when an | |
| 149 // alt svc is marked broken. After being marked broken 10 times, the max | |
| 150 // expiration delay will have been reached and exponential backoff will no | |
| 151 // longer apply. | |
| 152 | |
| 153 AlternativeService alternative_service(kProtoQUIC, "foo", 443); | |
| 154 | |
| 155 for (int i = 0; i < 11; ++i) { | |
| 156 broken_services_.MarkAlternativeServiceBroken(alternative_service); | |
| 157 | |
| 158 // Advance time until one time quantum before |alternative_service1|'s | |
| 159 // brokenness expires | |
| 160 test_task_runner_->FastForwardBy( | |
| 161 BROKEN_ALT_SVC_EXPIRE_DELAYS[std::min(i, 9)] - | |
| 162 base::TimeDelta::FromInternalValue(1)); | |
| 163 | |
| 164 EXPECT_TRUE( | |
| 165 broken_services_.IsAlternativeServiceBroken(alternative_service)); | |
| 166 | |
| 167 // Advance time by one time quantum. |alternative_service| should no longer | |
| 168 // be broken. | |
| 169 test_task_runner_->FastForwardBy(base::TimeDelta::FromInternalValue(1)); | |
| 170 | |
| 171 EXPECT_FALSE( | |
| 172 broken_services_.IsAlternativeServiceBroken(alternative_service)); | |
| 173 } | |
| 174 } | |
| 175 | |
| 176 TEST_F(BrokenAlternativeServicesTest, RemoveExpiredBrokenAltSvc) { | |
| 177 // This test will mark broken an alternative service A that has already been | |
| 178 // marked broken many times, then immediately mark another alternative service | |
| 179 // B as broken for the first time. Because A's been marked broken many times | |
| 180 // already, its brokenness will be scheduled to expire much further in the | |
| 181 // future than B, even though it was marked broken before B. This test makes | |
| 182 // sure that even though A was marked broken before B, B's brokenness should | |
| 183 // expire before A. | |
| 184 | |
| 185 AlternativeService alternative_service1(kProtoQUIC, "foo", 443); | |
| 186 AlternativeService alternative_service2(kProtoQUIC, "bar", 443); | |
| 187 | |
| 188 // Repeately mark |alternative_service1| broken and let brokenness expire. | |
| 189 // Do this a few times. | |
| 190 for (int i = 0; i < 3; ++i) { | |
| 191 broken_services_.MarkAlternativeServiceBroken(alternative_service1); | |
| 192 | |
| 193 // |broken_services_| should have posted task to expire the brokenness of | |
| 194 // |alternative_service|. | |
| 195 EXPECT_EQ(1u, test_task_runner_->GetPendingTaskCount()); | |
| 196 | |
| 197 // Advance time by just enough so that |alternative_service|'s brokenness | |
| 198 // expires. | |
| 199 test_task_runner_->FastForwardBy(BROKEN_ALT_SVC_EXPIRE_DELAYS[i]); | |
| 200 | |
| 201 // Ensure |broken_services_| notifies the delegate of expired broken alt | |
| 202 // svcs. | |
| 203 EXPECT_EQ(i + 1, (int)expired_alt_svcs_.size()); | |
| 204 EXPECT_EQ(alternative_service1, expired_alt_svcs_[i]); | |
| 205 } | |
| 206 expired_alt_svcs_.clear(); | |
| 207 | |
| 208 // Mark |alternative_service1| broken (will be given longer expiration delay), | |
| 209 // then mark |alternative_service2| broken (will be given shorter expiration | |
| 210 // delay). | |
| 211 broken_services_.MarkAlternativeServiceBroken(alternative_service1); | |
| 212 broken_services_.MarkAlternativeServiceBroken(alternative_service2); | |
| 213 | |
| 214 EXPECT_TRUE( | |
| 215 broken_services_.IsAlternativeServiceBroken(alternative_service1)); | |
| 216 EXPECT_TRUE( | |
| 217 broken_services_.IsAlternativeServiceBroken(alternative_service2)); | |
| 218 | |
| 219 // Advance time until one time quantum before |alternative_service2|'s | |
| 220 // brokenness expires. | |
| 221 test_task_runner_->FastForwardBy(BROKEN_ALT_SVC_EXPIRE_DELAYS[0] - | |
| 222 base::TimeDelta::FromInternalValue(1)); | |
| 223 | |
| 224 EXPECT_TRUE( | |
| 225 broken_services_.IsAlternativeServiceBroken(alternative_service1)); | |
| 226 EXPECT_TRUE( | |
| 227 broken_services_.IsAlternativeServiceBroken(alternative_service2)); | |
| 228 EXPECT_EQ(0u, expired_alt_svcs_.size()); | |
| 229 | |
| 230 // Advance time by one time quantum. |alternative_service2| should no longer | |
| 231 // be broken. | |
| 232 test_task_runner_->FastForwardBy(base::TimeDelta::FromInternalValue(1)); | |
| 233 | |
| 234 EXPECT_TRUE( | |
| 235 broken_services_.IsAlternativeServiceBroken(alternative_service1)); | |
| 236 EXPECT_FALSE( | |
| 237 broken_services_.IsAlternativeServiceBroken(alternative_service2)); | |
| 238 EXPECT_EQ(1u, expired_alt_svcs_.size()); | |
| 239 EXPECT_EQ(alternative_service2, expired_alt_svcs_[0]); | |
| 240 | |
| 241 // Advance time until one time quantum before |alternative_service1|'s | |
| 242 // brokenness expires | |
| 243 test_task_runner_->FastForwardBy(BROKEN_ALT_SVC_EXPIRE_DELAYS[3] - | |
| 244 BROKEN_ALT_SVC_EXPIRE_DELAYS[0] - | |
| 245 base::TimeDelta::FromInternalValue(1)); | |
| 246 | |
| 247 EXPECT_TRUE( | |
| 248 broken_services_.IsAlternativeServiceBroken(alternative_service1)); | |
| 249 EXPECT_FALSE( | |
| 250 broken_services_.IsAlternativeServiceBroken(alternative_service2)); | |
| 251 EXPECT_EQ(1u, expired_alt_svcs_.size()); | |
| 252 EXPECT_EQ(alternative_service2, expired_alt_svcs_[0]); | |
| 253 | |
| 254 // Advance time by one time quantum. |alternative_service1| should no longer | |
| 255 // be broken. | |
| 256 test_task_runner_->FastForwardBy(base::TimeDelta::FromInternalValue(1)); | |
| 257 | |
| 258 EXPECT_FALSE( | |
| 259 broken_services_.IsAlternativeServiceBroken(alternative_service1)); | |
| 260 EXPECT_FALSE( | |
| 261 broken_services_.IsAlternativeServiceBroken(alternative_service2)); | |
| 262 EXPECT_EQ(2u, expired_alt_svcs_.size()); | |
| 263 EXPECT_EQ(alternative_service2, expired_alt_svcs_[0]); | |
| 264 EXPECT_EQ(alternative_service1, expired_alt_svcs_[1]); | |
| 265 } | |
| 266 | |
| 267 } // namespace | |
| 268 | |
| 269 } // namespace net | |
| OLD | NEW |