blob: 43cb48091527e05b4acc4e4e3fd0c22d748ee50a [file] [log] [blame]
// 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