123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353 |
- // Copyright 2018 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 "services/network/websocket_throttler.h"
- #include <vector>
- #include "base/test/task_environment.h"
- #include "services/network/public/mojom/network_context.mojom-forward.h"
- #include "testing/gtest/include/gtest/gtest.h"
- #include "third_party/abseil-cpp/absl/types/optional.h"
- namespace network {
- namespace {
- class WebSocketThrottlerTest : public ::testing::Test {
- private:
- base::test::SingleThreadTaskEnvironment task_environment_;
- };
- TEST(WebSocketPerProcessThrottlerTest, InitialState) {
- WebSocketPerProcessThrottler throttler;
- EXPECT_FALSE(throttler.HasTooManyPendingConnections());
- EXPECT_EQ(0, throttler.num_pending_connections());
- EXPECT_EQ(0, throttler.num_current_succeeded_connections());
- EXPECT_EQ(0, throttler.num_previous_succeeded_connections());
- EXPECT_EQ(0, throttler.num_current_failed_connections());
- EXPECT_EQ(0, throttler.num_previous_failed_connections());
- EXPECT_EQ(base::TimeDelta(), throttler.CalculateDelay());
- }
- TEST(WebSocketPerProcessThrottlerTest, Pending) {
- WebSocketPerProcessThrottler throttler;
- auto tracker = throttler.IssuePendingConnectionTracker();
- EXPECT_FALSE(throttler.HasTooManyPendingConnections());
- EXPECT_EQ(1, throttler.num_pending_connections());
- EXPECT_EQ(0, throttler.num_current_succeeded_connections());
- EXPECT_EQ(0, throttler.num_previous_succeeded_connections());
- EXPECT_EQ(0, throttler.num_current_failed_connections());
- EXPECT_EQ(0, throttler.num_previous_failed_connections());
- EXPECT_EQ(base::TimeDelta(), throttler.CalculateDelay());
- }
- TEST(WebSocketPerProcessThrottlerTest, Complete) {
- WebSocketPerProcessThrottler throttler;
- {
- auto tracker = throttler.IssuePendingConnectionTracker();
- EXPECT_FALSE(throttler.HasTooManyPendingConnections());
- EXPECT_EQ(1, throttler.num_pending_connections());
- EXPECT_EQ(0, throttler.num_current_succeeded_connections());
- EXPECT_EQ(0, throttler.num_previous_succeeded_connections());
- EXPECT_EQ(0, throttler.num_current_failed_connections());
- EXPECT_EQ(0, throttler.num_previous_failed_connections());
- EXPECT_EQ(base::TimeDelta(), throttler.CalculateDelay());
- tracker.OnCompleteHandshake();
- EXPECT_FALSE(throttler.HasTooManyPendingConnections());
- EXPECT_EQ(0, throttler.num_pending_connections());
- EXPECT_EQ(1, throttler.num_current_succeeded_connections());
- EXPECT_EQ(0, throttler.num_previous_succeeded_connections());
- EXPECT_EQ(0, throttler.num_current_failed_connections());
- EXPECT_EQ(0, throttler.num_previous_failed_connections());
- EXPECT_EQ(base::TimeDelta(), throttler.CalculateDelay());
- // Destruct |tracker|.
- }
- EXPECT_FALSE(throttler.HasTooManyPendingConnections());
- EXPECT_EQ(0, throttler.num_pending_connections());
- EXPECT_EQ(1, throttler.num_current_succeeded_connections());
- EXPECT_EQ(0, throttler.num_previous_succeeded_connections());
- EXPECT_EQ(0, throttler.num_current_failed_connections());
- EXPECT_EQ(0, throttler.num_previous_failed_connections());
- EXPECT_EQ(base::TimeDelta(), throttler.CalculateDelay());
- }
- TEST(WebSocketPerProcessThrottlerTest, Failed) {
- WebSocketPerProcessThrottler throttler;
- {
- auto tracker = throttler.IssuePendingConnectionTracker();
- EXPECT_FALSE(throttler.HasTooManyPendingConnections());
- EXPECT_EQ(1, throttler.num_pending_connections());
- EXPECT_EQ(0, throttler.num_current_succeeded_connections());
- EXPECT_EQ(0, throttler.num_previous_succeeded_connections());
- EXPECT_EQ(0, throttler.num_current_failed_connections());
- EXPECT_EQ(0, throttler.num_previous_failed_connections());
- EXPECT_EQ(base::TimeDelta(), throttler.CalculateDelay());
- // Destruct |tracker|.
- }
- EXPECT_FALSE(throttler.HasTooManyPendingConnections());
- EXPECT_EQ(0, throttler.num_pending_connections());
- EXPECT_EQ(0, throttler.num_current_succeeded_connections());
- EXPECT_EQ(0, throttler.num_previous_succeeded_connections());
- EXPECT_EQ(1, throttler.num_current_failed_connections());
- EXPECT_EQ(0, throttler.num_previous_failed_connections());
- EXPECT_EQ(base::TimeDelta(), throttler.CalculateDelay());
- }
- TEST(WebSocketPerProcessThrottlerTest, TooManyPendingConnections) {
- constexpr int limit = 255;
- WebSocketPerProcessThrottler throttler;
- std::vector<WebSocketPerProcessThrottler::PendingConnection> trackers;
- for (int i = 0; i < limit - 1; ++i) {
- ASSERT_FALSE(throttler.HasTooManyPendingConnections());
- trackers.push_back(throttler.IssuePendingConnectionTracker());
- }
- ASSERT_FALSE(throttler.HasTooManyPendingConnections());
- trackers.push_back(throttler.IssuePendingConnectionTracker());
- EXPECT_TRUE(throttler.HasTooManyPendingConnections());
- }
- TEST(WebSocketPerProcessThrottlerTest, CompletedConnectionsDontCount) {
- constexpr int limit = 255;
- WebSocketPerProcessThrottler throttler;
- for (int i = 0; i < limit * 3; ++i) {
- ASSERT_FALSE(throttler.HasTooManyPendingConnections());
- auto tracker = throttler.IssuePendingConnectionTracker();
- tracker.OnCompleteHandshake();
- }
- EXPECT_FALSE(throttler.HasTooManyPendingConnections());
- }
- TEST(WebSocketPerProcessThrottlerTest, FailedConnectionsDontCount) {
- constexpr int limit = 255;
- WebSocketPerProcessThrottler throttler;
- for (int i = 0; i < limit * 3; ++i) {
- ASSERT_FALSE(throttler.HasTooManyPendingConnections());
- auto tracker = throttler.IssuePendingConnectionTracker();
- }
- EXPECT_FALSE(throttler.HasTooManyPendingConnections());
- }
- TEST(WebSocketPerProcessThrottlerTest, Roll) {
- WebSocketPerProcessThrottler throttler;
- for (int i = 0; i < 2; ++i)
- throttler.IssuePendingConnectionTracker().OnCompleteHandshake();
- for (int i = 0; i < 3; ++i)
- throttler.IssuePendingConnectionTracker();
- EXPECT_EQ(0, throttler.num_pending_connections());
- EXPECT_EQ(2, throttler.num_current_succeeded_connections());
- EXPECT_EQ(0, throttler.num_previous_succeeded_connections());
- EXPECT_EQ(3, throttler.num_current_failed_connections());
- EXPECT_EQ(0, throttler.num_previous_failed_connections());
- throttler.Roll();
- EXPECT_EQ(0, throttler.num_pending_connections());
- EXPECT_EQ(0, throttler.num_current_succeeded_connections());
- EXPECT_EQ(2, throttler.num_previous_succeeded_connections());
- EXPECT_EQ(0, throttler.num_current_failed_connections());
- EXPECT_EQ(3, throttler.num_previous_failed_connections());
- throttler.Roll();
- EXPECT_EQ(0, throttler.num_pending_connections());
- EXPECT_EQ(0, throttler.num_current_succeeded_connections());
- EXPECT_EQ(0, throttler.num_previous_succeeded_connections());
- EXPECT_EQ(0, throttler.num_current_failed_connections());
- EXPECT_EQ(0, throttler.num_previous_failed_connections());
- }
- TEST(WebSocketPerProcessThrottlerTest, CalculateDelay_3Pending) {
- WebSocketPerProcessThrottler throttler;
- std::vector<WebSocketPerProcessThrottler::PendingConnection> trackers;
- for (int i = 0; i < 3; ++i)
- trackers.push_back(throttler.IssuePendingConnectionTracker());
- EXPECT_EQ(3, throttler.num_pending_connections());
- EXPECT_EQ(0, throttler.num_current_succeeded_connections());
- EXPECT_EQ(0, throttler.num_previous_succeeded_connections());
- EXPECT_EQ(0, throttler.num_current_failed_connections());
- EXPECT_EQ(0, throttler.num_previous_failed_connections());
- EXPECT_EQ(base::TimeDelta(), throttler.CalculateDelay());
- }
- TEST(WebSocketPerProcessThrottlerTest, CalculateDelay_7Pending) {
- WebSocketPerProcessThrottler throttler;
- std::vector<WebSocketPerProcessThrottler::PendingConnection> trackers;
- for (int i = 0; i < 7; ++i)
- trackers.push_back(throttler.IssuePendingConnectionTracker());
- EXPECT_EQ(7, throttler.num_pending_connections());
- EXPECT_EQ(0, throttler.num_current_succeeded_connections());
- EXPECT_EQ(0, throttler.num_previous_succeeded_connections());
- EXPECT_EQ(0, throttler.num_current_failed_connections());
- EXPECT_EQ(0, throttler.num_previous_failed_connections());
- EXPECT_LT(base::TimeDelta(), throttler.CalculateDelay());
- }
- TEST(WebSocketPerProcessThrottlerTest, CalculateDelay_16Pending) {
- WebSocketPerProcessThrottler throttler;
- std::vector<WebSocketPerProcessThrottler::PendingConnection> trackers;
- for (int i = 0; i < 16; ++i)
- trackers.push_back(throttler.IssuePendingConnectionTracker());
- EXPECT_EQ(16, throttler.num_pending_connections());
- EXPECT_EQ(0, throttler.num_current_succeeded_connections());
- EXPECT_EQ(0, throttler.num_previous_succeeded_connections());
- EXPECT_EQ(0, throttler.num_current_failed_connections());
- EXPECT_EQ(0, throttler.num_previous_failed_connections());
- EXPECT_LE(base::Milliseconds(1000), throttler.CalculateDelay());
- EXPECT_LE(throttler.CalculateDelay(), base::Milliseconds(5000));
- }
- TEST(WebSocketPerProcessThrottlerTest, CalculateDelay_3Failure) {
- WebSocketPerProcessThrottler throttler;
- for (int i = 0; i < 3; ++i)
- throttler.IssuePendingConnectionTracker();
- EXPECT_EQ(0, throttler.num_pending_connections());
- EXPECT_EQ(0, throttler.num_current_succeeded_connections());
- EXPECT_EQ(0, throttler.num_previous_succeeded_connections());
- EXPECT_EQ(3, throttler.num_current_failed_connections());
- EXPECT_EQ(0, throttler.num_previous_failed_connections());
- EXPECT_EQ(base::TimeDelta(), throttler.CalculateDelay());
- }
- TEST(WebSocketPerProcessThrottlerTest, CalculateDelay_7Failure) {
- WebSocketPerProcessThrottler throttler;
- for (int i = 0; i < 7; ++i)
- throttler.IssuePendingConnectionTracker();
- EXPECT_EQ(0, throttler.num_pending_connections());
- EXPECT_EQ(0, throttler.num_current_succeeded_connections());
- EXPECT_EQ(0, throttler.num_previous_succeeded_connections());
- EXPECT_EQ(7, throttler.num_current_failed_connections());
- EXPECT_EQ(0, throttler.num_previous_failed_connections());
- EXPECT_LT(base::TimeDelta(), throttler.CalculateDelay());
- }
- TEST(WebSocketPerProcessThrottlerTest, CalculateDelay_16Failure) {
- WebSocketPerProcessThrottler throttler;
- for (int i = 0; i < 16; ++i)
- throttler.IssuePendingConnectionTracker();
- EXPECT_EQ(0, throttler.num_pending_connections());
- EXPECT_EQ(0, throttler.num_current_succeeded_connections());
- EXPECT_EQ(0, throttler.num_previous_succeeded_connections());
- EXPECT_EQ(16, throttler.num_current_failed_connections());
- EXPECT_EQ(0, throttler.num_previous_failed_connections());
- EXPECT_LE(base::Milliseconds(1000), throttler.CalculateDelay());
- EXPECT_LE(throttler.CalculateDelay(), base::Milliseconds(5000));
- }
- TEST(WebSocketPerProcessThrottlerTest, MoveTracker) {
- WebSocketPerProcessThrottler throttler;
- absl::optional<WebSocketThrottler::PendingConnection> tracker_holder;
- {
- WebSocketThrottler::PendingConnection tracker =
- throttler.IssuePendingConnectionTracker();
- EXPECT_EQ(1, throttler.num_pending_connections());
- EXPECT_EQ(0, throttler.num_current_succeeded_connections());
- EXPECT_EQ(0, throttler.num_previous_succeeded_connections());
- EXPECT_EQ(0, throttler.num_current_failed_connections());
- EXPECT_EQ(0, throttler.num_previous_failed_connections());
- WebSocketThrottler::PendingConnection tracker2 = std::move(tracker);
- WebSocketThrottler::PendingConnection tracker3 = std::move(tracker2);
- EXPECT_EQ(1, throttler.num_pending_connections());
- EXPECT_EQ(0, throttler.num_current_succeeded_connections());
- EXPECT_EQ(0, throttler.num_previous_succeeded_connections());
- EXPECT_EQ(0, throttler.num_current_failed_connections());
- EXPECT_EQ(0, throttler.num_previous_failed_connections());
- tracker_holder.emplace(std::move(tracker3));
- EXPECT_EQ(1, throttler.num_pending_connections());
- EXPECT_EQ(0, throttler.num_current_succeeded_connections());
- EXPECT_EQ(0, throttler.num_previous_succeeded_connections());
- EXPECT_EQ(0, throttler.num_current_failed_connections());
- EXPECT_EQ(0, throttler.num_previous_failed_connections());
- }
- EXPECT_EQ(1, throttler.num_pending_connections());
- EXPECT_EQ(0, throttler.num_current_succeeded_connections());
- EXPECT_EQ(0, throttler.num_previous_succeeded_connections());
- EXPECT_EQ(0, throttler.num_current_failed_connections());
- EXPECT_EQ(0, throttler.num_previous_failed_connections());
- tracker_holder = absl::nullopt;
- EXPECT_EQ(0, throttler.num_pending_connections());
- EXPECT_EQ(0, throttler.num_current_succeeded_connections());
- EXPECT_EQ(0, throttler.num_previous_succeeded_connections());
- EXPECT_EQ(1, throttler.num_current_failed_connections());
- EXPECT_EQ(0, throttler.num_previous_failed_connections());
- }
- TEST_F(WebSocketThrottlerTest, InitialState) {
- WebSocketThrottler throttler;
- EXPECT_EQ(0u, throttler.GetSizeForTesting());
- }
- TEST_F(WebSocketThrottlerTest, TooManyPendingConnections) {
- constexpr int process1 = 1;
- constexpr int process2 = 2;
- constexpr int limit = 255;
- WebSocketThrottler throttler;
- std::vector<WebSocketThrottler::PendingConnection> trackers;
- for (int i = 0; i < limit - 1; ++i) {
- ASSERT_FALSE(throttler.HasTooManyPendingConnections(process1));
- ASSERT_FALSE(throttler.HasTooManyPendingConnections(process2));
- trackers.push_back(
- std::move(throttler.IssuePendingConnectionTracker(process1).value()));
- trackers.push_back(
- std::move(throttler.IssuePendingConnectionTracker(process2).value()));
- }
- EXPECT_EQ(2u, throttler.GetSizeForTesting());
- ASSERT_FALSE(throttler.HasTooManyPendingConnections(process1));
- ASSERT_FALSE(throttler.HasTooManyPendingConnections(process2));
- trackers.push_back(
- std::move(throttler.IssuePendingConnectionTracker(process1).value()));
- ASSERT_TRUE(throttler.HasTooManyPendingConnections(process1));
- ASSERT_FALSE(throttler.HasTooManyPendingConnections(process2));
- trackers.push_back(
- std::move(throttler.IssuePendingConnectionTracker(process2).value()));
- ASSERT_TRUE(throttler.HasTooManyPendingConnections(process1));
- ASSERT_TRUE(throttler.HasTooManyPendingConnections(process2));
- }
- TEST_F(WebSocketThrottlerTest, BrowserProcessNotThrottled) {
- WebSocketThrottler throttler;
- ASSERT_FALSE(
- throttler.HasTooManyPendingConnections(mojom::kBrowserProcessId));
- ASSERT_FALSE(throttler.IssuePendingConnectionTracker(mojom::kBrowserProcessId)
- .has_value());
- }
- } // namespace
- } // namespace network
|