| // Copyright 2021 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "services/network/websocket_interceptor.h" |
| #include <memory> |
| |
| #include "base/logging.h" |
| #include "base/test/task_environment.h" |
| #include "services/network/throttling/network_conditions.h" |
| #include "services/network/throttling/throttling_controller.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace network { |
| namespace { |
| |
| uint32_t kNetLogSourceId = 123; |
| absl::optional<base::UnguessableToken> kThrottlingProfileId = |
| base::UnguessableToken::Create(); |
| |
| class MockCallback { |
| public: |
| MOCK_METHOD(void, Callback, ()); |
| }; |
| |
| class WebSocketInterceptorTest : public ::testing::Test { |
| protected: |
| WebSocketInterceptorTest() { |
| interceptor_ = std::make_unique<WebSocketInterceptor>(kNetLogSourceId, |
| kThrottlingProfileId); |
| } |
| |
| base::OnceClosure MakeCallback() { |
| return base::BindOnce(&MockCallback::Callback, |
| base::Unretained(&mock_callback_)); |
| } |
| |
| MockCallback mock_callback_; |
| base::test::SingleThreadTaskEnvironment task_environment_{ |
| base::test::SingleThreadTaskEnvironment::TimeSource::MOCK_TIME}; |
| std::unique_ptr<WebSocketInterceptor> interceptor_; |
| }; |
| |
| TEST_F(WebSocketInterceptorTest, DoesNotInterferWhenNoEmualatedConditions) { |
| EXPECT_CALL(mock_callback_, Callback()).Times(0); |
| ThrottlingController::SetConditions(*kThrottlingProfileId, nullptr); |
| EXPECT_EQ(WebSocketInterceptor::kContinue, |
| interceptor_->Intercept(WebSocketInterceptor::kOutgoing, 42, |
| MakeCallback())); |
| EXPECT_EQ(WebSocketInterceptor::kContinue, |
| interceptor_->Intercept(WebSocketInterceptor::kOutgoing, 42, |
| MakeCallback())); |
| } |
| |
| TEST_F(WebSocketInterceptorTest, ShouldWaitWhenOffline) { |
| EXPECT_CALL(mock_callback_, Callback()).Times(0); |
| ThrottlingController::SetConditions( |
| *kThrottlingProfileId, |
| std::make_unique<NetworkConditions>(/*offline=*/true)); |
| EXPECT_EQ(WebSocketInterceptor::kShouldWait, |
| interceptor_->Intercept(WebSocketInterceptor::kOutgoing, 42, |
| MakeCallback())); |
| } |
| |
| TEST_F(WebSocketInterceptorTest, ShouldWaitWhenSlow) { |
| ThrottlingController::SetConditions( |
| *kThrottlingProfileId, |
| std::make_unique<NetworkConditions>(/*offline=*/false, /*latency=*/0, |
| /*download=*/0, |
| /*upload=*/1)); |
| EXPECT_EQ(WebSocketInterceptor::kShouldWait, |
| interceptor_->Intercept(WebSocketInterceptor::kOutgoing, 42, |
| MakeCallback())); |
| EXPECT_CALL(mock_callback_, Callback()).Times(1); |
| |
| task_environment_.FastForwardUntilNoTasksRemain(); |
| } |
| |
| TEST_F(WebSocketInterceptorTest, SubsequentInterceptWhenSlow) { |
| ThrottlingController::SetConditions( |
| *kThrottlingProfileId, |
| std::make_unique<NetworkConditions>(/*offline=*/false, /*latency=*/0, |
| /*download=*/0, |
| /*upload=*/1)); |
| EXPECT_EQ(WebSocketInterceptor::kShouldWait, |
| interceptor_->Intercept(WebSocketInterceptor::kOutgoing, 42, |
| MakeCallback())); |
| |
| EXPECT_CALL(mock_callback_, Callback()).Times(1); |
| task_environment_.FastForwardUntilNoTasksRemain(); |
| |
| EXPECT_EQ(WebSocketInterceptor::kShouldWait, |
| interceptor_->Intercept(WebSocketInterceptor::kOutgoing, 42, |
| MakeCallback())); |
| } |
| |
| TEST_F(WebSocketInterceptorTest, OfflineCallbackInvokedWhenBackOnline) { |
| ThrottlingController::SetConditions( |
| *kThrottlingProfileId, |
| std::make_unique<NetworkConditions>(/*offline=*/true)); |
| EXPECT_CALL(mock_callback_, Callback()).Times(0); |
| EXPECT_EQ(WebSocketInterceptor::kShouldWait, |
| interceptor_->Intercept(WebSocketInterceptor::kOutgoing, 42, |
| MakeCallback())); |
| |
| EXPECT_CALL(mock_callback_, Callback()).Times(1); |
| ThrottlingController::SetConditions(*kThrottlingProfileId, nullptr); |
| interceptor_->Intercept(WebSocketInterceptor::kOutgoing, 42, MakeCallback()); |
| } |
| |
| TEST_F(WebSocketInterceptorTest, SlowAfterOffline) { |
| ThrottlingController::SetConditions( |
| *kThrottlingProfileId, |
| std::make_unique<NetworkConditions>(/*offline=*/true)); |
| EXPECT_CALL(mock_callback_, Callback()).Times(0); |
| EXPECT_EQ(WebSocketInterceptor::kShouldWait, |
| interceptor_->Intercept(WebSocketInterceptor::kOutgoing, 42, |
| MakeCallback())); |
| |
| EXPECT_CALL(mock_callback_, Callback()).Times(1); |
| ThrottlingController::SetConditions( |
| *kThrottlingProfileId, |
| std::make_unique<NetworkConditions>(/*offline=*/false, /*latency=*/0, |
| /*download=*/0, |
| /*upload=*/1)); |
| task_environment_.FastForwardUntilNoTasksRemain(); |
| interceptor_->Intercept(WebSocketInterceptor::kOutgoing, 43, MakeCallback()); |
| EXPECT_CALL(mock_callback_, Callback()).Times(1); |
| task_environment_.FastForwardUntilNoTasksRemain(); |
| } |
| |
| TEST_F(WebSocketInterceptorTest, UsesRightDirection) { |
| ThrottlingController::SetConditions( |
| *kThrottlingProfileId, |
| std::make_unique<NetworkConditions>(/*offline=*/false, /*latency=*/0, |
| /*download=*/1, |
| /*upload=*/0)); |
| interceptor_->Intercept(WebSocketInterceptor::kIncoming, 42, MakeCallback()); |
| EXPECT_CALL(mock_callback_, Callback()).Times(1); |
| task_environment_.FastForwardUntilNoTasksRemain(); |
| |
| interceptor_->Intercept(WebSocketInterceptor::kOutgoing, 42, MakeCallback()); |
| EXPECT_CALL(mock_callback_, Callback()).Times(0); |
| task_environment_.FastForwardUntilNoTasksRemain(); |
| } |
| |
| } // namespace |
| } // namespace network |