Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(490)

Unified Diff: net/http/broken_alternative_services_unittest.cc

Issue 2898983006: Fix and refactor HttpServerPropertiesImpl's alternative services brokenness expiration behavior (Closed)
Patch Set: Fixed cherie's comments from ps9; added BrokenAlternativeServicesTest.ScheduleExpireTaskAfterExpire Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/http/broken_alternative_services.cc ('k') | net/http/http_server_properties_impl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..0c58582648d9c561851fef7229c7a9098f3015cd
--- /dev/null
+++ b/net/http/broken_alternative_services_unittest.cc
@@ -0,0 +1,366 @@
+// 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.
+ 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]);
+}
+
+TEST_F(BrokenAlternativeServicesTest, ScheduleExpireTaskAfterExpire) {
+ // This test will check that when a broken alt svc expires, an expiration task
+ // is scheduled for the next broken alt svc in the expiration queue.
+
+ AlternativeService alternative_service1(kProtoQUIC, "foo", 443);
+ AlternativeService alternative_service2(kProtoQUIC, "bar", 443);
+
+ // Mark |alternative_service1| broken and let brokenness expire. This will
+ // increase its expiration delay the next time it's marked broken.
+ broken_services_.MarkAlternativeServiceBroken(alternative_service1);
+ test_task_runner_->FastForwardBy(base::TimeDelta::FromMinutes(5));
+ EXPECT_FALSE(
+ broken_services_.IsAlternativeServiceBroken(alternative_service1));
+ EXPECT_FALSE(test_task_runner_->HasPendingTask());
+
+ // Mark |alternative_service1| and |alternative_service2| broken and
+ // let |alternative_service2|'s brokenness expire.
+ broken_services_.MarkAlternativeServiceBroken(alternative_service1);
+ broken_services_.MarkAlternativeServiceBroken(alternative_service2);
+
+ test_task_runner_->FastForwardBy(base::TimeDelta::FromMinutes(5));
+ EXPECT_FALSE(
+ broken_services_.IsAlternativeServiceBroken(alternative_service2));
+ EXPECT_TRUE(
+ broken_services_.IsAlternativeServiceBroken(alternative_service1));
+
+ // Make sure an expiration task has been scheduled for expiring the brokenness
+ // of |alternative_service1|.
+ EXPECT_TRUE(test_task_runner_->HasPendingTask());
+}
+
+} // namespace
+
+} // namespace net
« no previous file with comments | « net/http/broken_alternative_services.cc ('k') | net/http/http_server_properties_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698