Chromium Code Reviews| Index: net/http/broken_alternative_services_unittest.cc | 
| diff --git a/net/http/broken_alternative_services_unittest.cc b/net/http/broken_alternative_services_unittest.cc | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..d605872a02673208aaa6a0e4bdf722ce40138850 | 
| --- /dev/null | 
| +++ b/net/http/broken_alternative_services_unittest.cc | 
| @@ -0,0 +1,335 @@ | 
| +// Copyright (c) 2017 The Chromium Authors. All rights reserved. | 
| +// Use of this source code is governed by a BSD-style license that can be | 
| +// found in the LICENSE file. | 
| + | 
| +#include "net/http/broken_alternative_services.h" | 
| + | 
| +#include <algorithm> | 
| +#include <vector> | 
| + | 
| +#include "base/test/test_mock_time_task_runner.h" | 
| +#include "base/time/tick_clock.h" | 
| +#include "testing/gtest/include/gtest/gtest.h" | 
| + | 
| +namespace net { | 
| + | 
| +namespace { | 
| + | 
| +class BrokenAlternativeServicesTest | 
| + : public BrokenAlternativeServices::Delegate, | 
| + public ::testing::Test { | 
| + public: | 
| + BrokenAlternativeServicesTest() | 
| + : test_task_runner_(new base::TestMockTimeTaskRunner()), | 
| + test_task_runner_context_(test_task_runner_), | 
| + broken_services_clock_(test_task_runner_->GetMockTickClock()), | 
| + broken_services_(this, broken_services_clock_.get()) {} | 
| + | 
| + // BrokenAlternativeServices::Delegate implementation | 
| + void OnExpireBrokenAlternativeService( | 
| + const AlternativeService& expired_alternative_service) override { | 
| + expired_alt_svcs_.push_back(expired_alternative_service); | 
| + } | 
| + | 
| + // All tests will run inside the scope of |test_task_runner_context_|, which | 
| + // means any task posted to the main message loop will run on | 
| + // |test_task_runner_|. | 
| + scoped_refptr<base::TestMockTimeTaskRunner> test_task_runner_; | 
| + base::TestMockTimeTaskRunner::ScopedContext test_task_runner_context_; | 
| + | 
| + std::unique_ptr<base::TickClock> broken_services_clock_; | 
| + BrokenAlternativeServices broken_services_; | 
| + | 
| + std::vector<AlternativeService> expired_alt_svcs_; | 
| +}; | 
| + | 
| +TEST_F(BrokenAlternativeServicesTest, MarkBroken) { | 
| + const AlternativeService alternative_service1(kProtoHTTP2, "foo", 443); | 
| + const AlternativeService alternative_service2(kProtoHTTP2, "foo", 1234); | 
| + | 
| + EXPECT_FALSE( | 
| + broken_services_.IsAlternativeServiceBroken(alternative_service1)); | 
| + EXPECT_FALSE( | 
| + broken_services_.IsAlternativeServiceBroken(alternative_service2)); | 
| + | 
| + broken_services_.MarkAlternativeServiceBroken(alternative_service1); | 
| + | 
| + EXPECT_TRUE( | 
| + broken_services_.IsAlternativeServiceBroken(alternative_service1)); | 
| + EXPECT_FALSE( | 
| + broken_services_.IsAlternativeServiceBroken(alternative_service2)); | 
| + | 
| + broken_services_.MarkAlternativeServiceBroken(alternative_service2); | 
| + | 
| + EXPECT_TRUE( | 
| + broken_services_.IsAlternativeServiceBroken(alternative_service1)); | 
| + EXPECT_TRUE( | 
| + broken_services_.IsAlternativeServiceBroken(alternative_service2)); | 
| + | 
| + broken_services_.ConfirmAlternativeService(alternative_service1); | 
| + | 
| + EXPECT_FALSE( | 
| + broken_services_.IsAlternativeServiceBroken(alternative_service1)); | 
| + EXPECT_TRUE( | 
| + broken_services_.IsAlternativeServiceBroken(alternative_service2)); | 
| + | 
| + broken_services_.ConfirmAlternativeService(alternative_service2); | 
| + | 
| + EXPECT_FALSE( | 
| + broken_services_.IsAlternativeServiceBroken(alternative_service1)); | 
| + EXPECT_FALSE( | 
| + broken_services_.IsAlternativeServiceBroken(alternative_service2)); | 
| + | 
| + EXPECT_EQ(0u, expired_alt_svcs_.size()); | 
| +} | 
| + | 
| +TEST_F(BrokenAlternativeServicesTest, MarkRecentlyBroken) { | 
| + const AlternativeService alternative_service(kProtoHTTP2, "foo", 443); | 
| + | 
| + EXPECT_FALSE( | 
| + broken_services_.IsAlternativeServiceBroken(alternative_service)); | 
| + EXPECT_FALSE(broken_services_.WasAlternativeServiceRecentlyBroken( | 
| + alternative_service)); | 
| + | 
| + broken_services_.MarkAlternativeServiceRecentlyBroken(alternative_service); | 
| + EXPECT_FALSE( | 
| + broken_services_.IsAlternativeServiceBroken(alternative_service)); | 
| + EXPECT_TRUE(broken_services_.WasAlternativeServiceRecentlyBroken( | 
| + alternative_service)); | 
| + | 
| + broken_services_.ConfirmAlternativeService(alternative_service); | 
| + EXPECT_FALSE( | 
| + broken_services_.IsAlternativeServiceBroken(alternative_service)); | 
| + EXPECT_FALSE(broken_services_.WasAlternativeServiceRecentlyBroken( | 
| + alternative_service)); | 
| +} | 
| + | 
| +TEST_F(BrokenAlternativeServicesTest, ExpireBrokenAlternateProtocolMappings) { | 
| + AlternativeService alternative_service(kProtoQUIC, "foo", 443); | 
| + | 
| + broken_services_.MarkAlternativeServiceBroken(alternative_service); | 
| + | 
| + // |broken_services_| should have posted task to expire the brokenness of | 
| + // |alternative_service|. | 
| + EXPECT_EQ(1u, test_task_runner_->GetPendingTaskCount()); | 
| + | 
| + // Advance time until one time quantum before |alternative_service1|'s | 
| + // brokenness expires | 
| + test_task_runner_->FastForwardBy(base::TimeDelta::FromMinutes(5) - | 
| + base::TimeDelta::FromInternalValue(1)); | 
| + | 
| + // Ensure |alternative_service| is still marked broken. | 
| + EXPECT_TRUE(broken_services_.IsAlternativeServiceBroken(alternative_service)); | 
| + EXPECT_EQ(0u, expired_alt_svcs_.size()); | 
| + EXPECT_EQ(1u, test_task_runner_->GetPendingTaskCount()); | 
| + | 
| + // Advance time by one time quantum | 
| 
 
Zhongyi Shi
2017/05/31 18:54:15
nit: quantum.
 
wangyix1
2017/06/01 20:05:48
Done.
 
 | 
| + test_task_runner_->FastForwardBy(base::TimeDelta::FromInternalValue(1)); | 
| + | 
| + // Ensure |alternative_service| brokenness has expired but is still | 
| + // considered recently broken | 
| + EXPECT_FALSE( | 
| + broken_services_.IsAlternativeServiceBroken(alternative_service)); | 
| + EXPECT_FALSE(test_task_runner_->HasPendingTask()); | 
| + EXPECT_EQ(1u, expired_alt_svcs_.size()); | 
| + EXPECT_EQ(alternative_service, expired_alt_svcs_[0]); | 
| + EXPECT_TRUE(broken_services_.WasAlternativeServiceRecentlyBroken( | 
| + alternative_service)); | 
| +} | 
| + | 
| +TEST_F(BrokenAlternativeServicesTest, ExponentialBackoff) { | 
| + // Tests the exponential backoff of the computed expiration delay when an | 
| + // alt svc is marked broken. After being marked broken 10 times, the max | 
| + // expiration delay will have been reached and exponential backoff will no | 
| + // longer apply. | 
| + | 
| + AlternativeService alternative_service(kProtoQUIC, "foo", 443); | 
| + | 
| + broken_services_.MarkAlternativeServiceBroken(alternative_service); | 
| + test_task_runner_->FastForwardBy(base::TimeDelta::FromMinutes(5) - | 
| + base::TimeDelta::FromInternalValue(1)); | 
| + EXPECT_TRUE(broken_services_.IsAlternativeServiceBroken(alternative_service)); | 
| + test_task_runner_->FastForwardBy(base::TimeDelta::FromInternalValue(1)); | 
| + EXPECT_FALSE( | 
| + broken_services_.IsAlternativeServiceBroken(alternative_service)); | 
| + | 
| + broken_services_.MarkAlternativeServiceBroken(alternative_service); | 
| + test_task_runner_->FastForwardBy(base::TimeDelta::FromMinutes(10) - | 
| + base::TimeDelta::FromInternalValue(1)); | 
| + EXPECT_TRUE(broken_services_.IsAlternativeServiceBroken(alternative_service)); | 
| + test_task_runner_->FastForwardBy(base::TimeDelta::FromInternalValue(1)); | 
| + EXPECT_FALSE( | 
| + broken_services_.IsAlternativeServiceBroken(alternative_service)); | 
| + | 
| + broken_services_.MarkAlternativeServiceBroken(alternative_service); | 
| + test_task_runner_->FastForwardBy(base::TimeDelta::FromMinutes(20) - | 
| + base::TimeDelta::FromInternalValue(1)); | 
| + EXPECT_TRUE(broken_services_.IsAlternativeServiceBroken(alternative_service)); | 
| + test_task_runner_->FastForwardBy(base::TimeDelta::FromInternalValue(1)); | 
| + EXPECT_FALSE( | 
| + broken_services_.IsAlternativeServiceBroken(alternative_service)); | 
| + | 
| + broken_services_.MarkAlternativeServiceBroken(alternative_service); | 
| + test_task_runner_->FastForwardBy(base::TimeDelta::FromMinutes(40) - | 
| + base::TimeDelta::FromInternalValue(1)); | 
| + EXPECT_TRUE(broken_services_.IsAlternativeServiceBroken(alternative_service)); | 
| + test_task_runner_->FastForwardBy(base::TimeDelta::FromInternalValue(1)); | 
| + EXPECT_FALSE( | 
| + broken_services_.IsAlternativeServiceBroken(alternative_service)); | 
| + | 
| + broken_services_.MarkAlternativeServiceBroken(alternative_service); | 
| + test_task_runner_->FastForwardBy(base::TimeDelta::FromMinutes(80) - | 
| + base::TimeDelta::FromInternalValue(1)); | 
| + EXPECT_TRUE(broken_services_.IsAlternativeServiceBroken(alternative_service)); | 
| + test_task_runner_->FastForwardBy(base::TimeDelta::FromInternalValue(1)); | 
| + EXPECT_FALSE( | 
| + broken_services_.IsAlternativeServiceBroken(alternative_service)); | 
| + | 
| + broken_services_.MarkAlternativeServiceBroken(alternative_service); | 
| + test_task_runner_->FastForwardBy(base::TimeDelta::FromMinutes(160) - | 
| + base::TimeDelta::FromInternalValue(1)); | 
| + EXPECT_TRUE(broken_services_.IsAlternativeServiceBroken(alternative_service)); | 
| + test_task_runner_->FastForwardBy(base::TimeDelta::FromInternalValue(1)); | 
| + EXPECT_FALSE( | 
| + broken_services_.IsAlternativeServiceBroken(alternative_service)); | 
| + | 
| + broken_services_.MarkAlternativeServiceBroken(alternative_service); | 
| + test_task_runner_->FastForwardBy(base::TimeDelta::FromMinutes(320) - | 
| + base::TimeDelta::FromInternalValue(1)); | 
| + EXPECT_TRUE(broken_services_.IsAlternativeServiceBroken(alternative_service)); | 
| + test_task_runner_->FastForwardBy(base::TimeDelta::FromInternalValue(1)); | 
| + EXPECT_FALSE( | 
| + broken_services_.IsAlternativeServiceBroken(alternative_service)); | 
| + | 
| + broken_services_.MarkAlternativeServiceBroken(alternative_service); | 
| + test_task_runner_->FastForwardBy(base::TimeDelta::FromMinutes(640) - | 
| + base::TimeDelta::FromInternalValue(1)); | 
| + EXPECT_TRUE(broken_services_.IsAlternativeServiceBroken(alternative_service)); | 
| + test_task_runner_->FastForwardBy(base::TimeDelta::FromInternalValue(1)); | 
| + EXPECT_FALSE( | 
| + broken_services_.IsAlternativeServiceBroken(alternative_service)); | 
| + | 
| + broken_services_.MarkAlternativeServiceBroken(alternative_service); | 
| + test_task_runner_->FastForwardBy(base::TimeDelta::FromMinutes(1280) - | 
| + base::TimeDelta::FromInternalValue(1)); | 
| + EXPECT_TRUE(broken_services_.IsAlternativeServiceBroken(alternative_service)); | 
| + test_task_runner_->FastForwardBy(base::TimeDelta::FromInternalValue(1)); | 
| + EXPECT_FALSE( | 
| + broken_services_.IsAlternativeServiceBroken(alternative_service)); | 
| + | 
| + broken_services_.MarkAlternativeServiceBroken(alternative_service); | 
| + test_task_runner_->FastForwardBy(base::TimeDelta::FromMinutes(2560) - | 
| + base::TimeDelta::FromInternalValue(1)); | 
| + EXPECT_TRUE(broken_services_.IsAlternativeServiceBroken(alternative_service)); | 
| + test_task_runner_->FastForwardBy(base::TimeDelta::FromInternalValue(1)); | 
| + EXPECT_FALSE( | 
| + broken_services_.IsAlternativeServiceBroken(alternative_service)); | 
| + | 
| + // Max expiration delay has been reached; subsequent expiration delays from | 
| + // this point forward should not increase further. | 
| + broken_services_.MarkAlternativeServiceBroken(alternative_service); | 
| + test_task_runner_->FastForwardBy(base::TimeDelta::FromMinutes(2560) - | 
| + base::TimeDelta::FromInternalValue(1)); | 
| + EXPECT_TRUE(broken_services_.IsAlternativeServiceBroken(alternative_service)); | 
| + test_task_runner_->FastForwardBy(base::TimeDelta::FromInternalValue(1)); | 
| + EXPECT_FALSE( | 
| + broken_services_.IsAlternativeServiceBroken(alternative_service)); | 
| +} | 
| + | 
| +TEST_F(BrokenAlternativeServicesTest, RemoveExpiredBrokenAltSvc) { | 
| + // This test will mark broken an alternative service A that has already been | 
| + // marked broken many times, then immediately mark another alternative service | 
| + // B as broken for the first time. Because A's been marked broken many times | 
| + // already, its brokenness will be scheduled to expire much further in the | 
| + // future than B, even though it was marked broken before B. This test makes | 
| + // sure that even though A was marked broken before B, B's brokenness should | 
| + // expire before A. | 
| + | 
| + AlternativeService alternative_service1(kProtoQUIC, "foo", 443); | 
| + AlternativeService alternative_service2(kProtoQUIC, "bar", 443); | 
| + | 
| + // Repeately mark |alternative_service1| broken and let brokenness expire. | 
| + // Do this a few times. | 
| + | 
| + broken_services_.MarkAlternativeServiceBroken(alternative_service1); | 
| + EXPECT_EQ(1u, test_task_runner_->GetPendingTaskCount()); | 
| + test_task_runner_->FastForwardBy(base::TimeDelta::FromMinutes(5)); | 
| + EXPECT_EQ(1u, expired_alt_svcs_.size()); | 
| + EXPECT_EQ(alternative_service1, expired_alt_svcs_.back()); | 
| + | 
| + broken_services_.MarkAlternativeServiceBroken(alternative_service1); | 
| + EXPECT_EQ(1u, test_task_runner_->GetPendingTaskCount()); | 
| + test_task_runner_->FastForwardBy(base::TimeDelta::FromMinutes(10)); | 
| + EXPECT_EQ(2u, expired_alt_svcs_.size()); | 
| + EXPECT_EQ(alternative_service1, expired_alt_svcs_.back()); | 
| + | 
| + broken_services_.MarkAlternativeServiceBroken(alternative_service1); | 
| + EXPECT_EQ(1u, test_task_runner_->GetPendingTaskCount()); | 
| + test_task_runner_->FastForwardBy(base::TimeDelta::FromMinutes(20)); | 
| + EXPECT_EQ(3u, expired_alt_svcs_.size()); | 
| + EXPECT_EQ(alternative_service1, expired_alt_svcs_.back()); | 
| + | 
| + expired_alt_svcs_.clear(); | 
| + | 
| + // Mark |alternative_service1| broken (will be given longer expiration delay), | 
| + // then mark |alternative_service2| broken (will be given shorter expiration | 
| + // delay). | 
| + broken_services_.MarkAlternativeServiceBroken(alternative_service1); | 
| + broken_services_.MarkAlternativeServiceBroken(alternative_service2); | 
| + | 
| + EXPECT_TRUE( | 
| + broken_services_.IsAlternativeServiceBroken(alternative_service1)); | 
| + EXPECT_TRUE( | 
| + broken_services_.IsAlternativeServiceBroken(alternative_service2)); | 
| + | 
| + // Advance time until one time quantum before |alternative_service2|'s | 
| + // brokenness expires. | 
| + test_task_runner_->FastForwardBy(base::TimeDelta::FromMinutes(5) - | 
| + base::TimeDelta::FromInternalValue(1)); | 
| + | 
| + EXPECT_TRUE( | 
| + broken_services_.IsAlternativeServiceBroken(alternative_service1)); | 
| + EXPECT_TRUE( | 
| + broken_services_.IsAlternativeServiceBroken(alternative_service2)); | 
| + EXPECT_EQ(0u, expired_alt_svcs_.size()); | 
| + | 
| + // Advance time by one time quantum. |alternative_service2| should no longer | 
| + // be broken. | 
| + test_task_runner_->FastForwardBy(base::TimeDelta::FromInternalValue(1)); | 
| + | 
| + EXPECT_TRUE( | 
| + broken_services_.IsAlternativeServiceBroken(alternative_service1)); | 
| + EXPECT_FALSE( | 
| + broken_services_.IsAlternativeServiceBroken(alternative_service2)); | 
| + EXPECT_EQ(1u, expired_alt_svcs_.size()); | 
| + EXPECT_EQ(alternative_service2, expired_alt_svcs_[0]); | 
| + | 
| + // Advance time until one time quantum before |alternative_service1|'s | 
| + // brokenness expires | 
| + test_task_runner_->FastForwardBy(base::TimeDelta::FromMinutes(40) - | 
| + base::TimeDelta::FromMinutes(5) - | 
| + base::TimeDelta::FromInternalValue(1)); | 
| + | 
| + EXPECT_TRUE( | 
| + broken_services_.IsAlternativeServiceBroken(alternative_service1)); | 
| + EXPECT_FALSE( | 
| + broken_services_.IsAlternativeServiceBroken(alternative_service2)); | 
| + EXPECT_EQ(1u, expired_alt_svcs_.size()); | 
| + EXPECT_EQ(alternative_service2, expired_alt_svcs_[0]); | 
| + | 
| + // Advance time by one time quantum. |alternative_service1| should no longer | 
| + // be broken. | 
| + test_task_runner_->FastForwardBy(base::TimeDelta::FromInternalValue(1)); | 
| + | 
| + EXPECT_FALSE( | 
| + broken_services_.IsAlternativeServiceBroken(alternative_service1)); | 
| + EXPECT_FALSE( | 
| + broken_services_.IsAlternativeServiceBroken(alternative_service2)); | 
| + EXPECT_EQ(2u, expired_alt_svcs_.size()); | 
| + EXPECT_EQ(alternative_service2, expired_alt_svcs_[0]); | 
| + EXPECT_EQ(alternative_service1, expired_alt_svcs_[1]); | 
| +} | 
| + | 
| 
 
Zhongyi Shi
2017/05/31 18:54:14
Most of the tests currently schedule expiring task
 
wangyix1
2017/06/01 20:05:49
Done.
 
 | 
| +} // namespace | 
| + | 
| +} // namespace net |