blob: cead9b45eb3ea4c75c26f28807ceff30dc905347 [file] [log] [blame]
Avi Drissman64595482022-09-14 20:52:291// Copyright 2018 The Chromium Authors
Matt Menke977e61b2019-01-10 19:36:022// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "net/socket/connect_job.h"
6
Avi Drissman41c4a412023-01-11 22:45:377#include "base/functional/bind.h"
8#include "base/functional/callback.h"
Matt Menke977e61b2019-01-10 19:36:029#include "base/run_loop.h"
Gabriel Charettec7108742019-08-23 03:31:4010#include "base/test/task_environment.h"
Matt Menke977e61b2019-01-10 19:36:0211#include "net/base/address_list.h"
12#include "net/base/net_errors.h"
13#include "net/base/request_priority.h"
dalykedd30d982019-12-16 15:31:1014#include "net/dns/public/resolve_error_info.h"
Matt Menke977e61b2019-01-10 19:36:0215#include "net/log/test_net_log.h"
16#include "net/log/test_net_log_util.h"
Matt Menke3abc57c2019-01-10 21:48:4217#include "net/socket/connect_job_test_util.h"
Matt Menke977e61b2019-01-10 19:36:0218#include "net/socket/socket_tag.h"
19#include "net/socket/socket_test_util.h"
20#include "net/test/gtest_util.h"
21#include "testing/gtest/include/gtest/gtest.h"
22
23namespace net {
24namespace {
25
Matt Menke977e61b2019-01-10 19:36:0226class TestConnectJob : public ConnectJob {
27 public:
28 enum class JobType {
29 kSyncSuccess,
30 kAsyncSuccess,
31 kHung,
32 };
33
34 TestConnectJob(JobType job_type,
35 base::TimeDelta timeout_duration,
Matt Menkea6f99ad2019-03-08 02:26:4336 const CommonConnectJobParams* common_connect_job_params,
37 ConnectJob::Delegate* delegate)
Matt Menke1a6c92d2019-02-23 00:25:3838 : ConnectJob(DEFAULT_PRIORITY,
Matt Menkea6f99ad2019-03-08 02:26:4339 SocketTag(),
Matt Menke1a6c92d2019-02-23 00:25:3840 timeout_duration,
Matt Menkea6f99ad2019-03-08 02:26:4341 common_connect_job_params,
Matt Menke1a6c92d2019-02-23 00:25:3842 delegate,
43 nullptr /* net_log */,
44 NetLogSourceType::TRANSPORT_CONNECT_JOB,
45 NetLogEventType::TRANSPORT_CONNECT_JOB_CONNECT),
Tsuyoshi Horo2ec06e002022-06-09 01:38:5946 job_type_(job_type) {
Matt Menke977e61b2019-01-10 19:36:0247 switch (job_type_) {
48 case JobType::kSyncSuccess:
49 socket_data_provider_.set_connect_data(MockConnect(SYNCHRONOUS, OK));
50 return;
51 case JobType::kAsyncSuccess:
52 socket_data_provider_.set_connect_data(MockConnect(ASYNC, OK));
53 return;
54 case JobType::kHung:
55 socket_data_provider_.set_connect_data(
56 MockConnect(SYNCHRONOUS, ERR_IO_PENDING));
57 return;
58 }
59 }
60
Peter Boström407869b2021-10-07 04:42:4861 TestConnectJob(const TestConnectJob&) = delete;
62 TestConnectJob& operator=(const TestConnectJob&) = delete;
63
Matt Menke977e61b2019-01-10 19:36:0264 // From ConnectJob:
65 LoadState GetLoadState() const override { return LOAD_STATE_IDLE; }
Matt Menke141b87f22019-01-30 02:43:0366 bool HasEstablishedConnection() const override { return false; }
dalykedd30d982019-12-16 15:31:1067 ResolveErrorInfo GetResolveErrorInfo() const override {
68 return ResolveErrorInfo(net::OK);
69 }
Matt Menke977e61b2019-01-10 19:36:0270 int ConnectInternal() override {
Tsuyoshi Horoc39623a82022-07-11 01:27:5871 SetSocket(std::make_unique<MockTCPClientSocket>(
72 AddressList(), net_log().net_log(), &socket_data_provider_),
Anton Bikineev068d2912021-05-15 20:43:5273 absl::nullopt /* dns_aliases */);
Matt Menke977e61b2019-01-10 19:36:0274 return socket()->Connect(base::BindOnce(
75 &TestConnectJob::NotifyDelegateOfCompletion, base::Unretained(this)));
76 }
77 void ChangePriorityInternal(RequestPriority priority) override {
78 last_seen_priority_ = priority;
79 }
80
81 using ConnectJob::ResetTimer;
82
83 // The priority seen during the most recent call to ChangePriorityInternal().
84 RequestPriority last_seen_priority() const { return last_seen_priority_; }
85
Matt Menkea6f99ad2019-03-08 02:26:4386 protected:
Matt Menke977e61b2019-01-10 19:36:0287 const JobType job_type_;
88 StaticSocketDataProvider socket_data_provider_;
Tsuyoshi Horo2ec06e002022-06-09 01:38:5989 RequestPriority last_seen_priority_ = DEFAULT_PRIORITY;
Matt Menke977e61b2019-01-10 19:36:0290};
91
92class ConnectJobTest : public testing::Test {
93 public:
94 ConnectJobTest()
Gabriel Charette694c3c332019-08-19 14:53:0595 : task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME),
Matt Menkea6f99ad2019-03-08 02:26:4396 common_connect_job_params_(
97 nullptr /* client_socket_factory */,
98 nullptr /* host_resolver */,
Matt Menkeb88837e2019-03-20 11:50:4099 nullptr /* http_auth_cache */,
100 nullptr /* http_auth_handler_factory */,
101 nullptr /* spdy_session_pool */,
Matt Menkeb5fb42b2019-03-22 17:26:13102 nullptr /* quic_supported_versions */,
Matt Menkeb88837e2019-03-20 11:50:40103 nullptr /* quic_stream_factory */,
Matt Menkea6f99ad2019-03-08 02:26:43104 nullptr /* proxy_delegate */,
Matt Menked732ea42019-03-08 12:05:00105 nullptr /* http_user_agent_settings */,
David Benjamin24725be2019-07-24 20:57:18106 nullptr /* ssl_client_context */,
Matt Menkea6f99ad2019-03-08 02:26:43107 nullptr /* socket_performance_watcher_factory */,
108 nullptr /* network_quality_estimator */,
Matt Reichhoff36a1fd62021-10-12 22:52:20109 NetLog::Get(),
Matt Menkea6f99ad2019-03-08 02:26:43110 nullptr /* websocket_endpoint_lock_manager */) {}
Matt Menke977e61b2019-01-10 19:36:02111 ~ConnectJobTest() override = default;
112
113 protected:
Gabriel Charette694c3c332019-08-19 14:53:05114 base::test::TaskEnvironment task_environment_;
Matt Reichhoff36a1fd62021-10-12 22:52:20115 RecordingNetLogObserver net_log_observer_;
Matt Menkea6f99ad2019-03-08 02:26:43116 const CommonConnectJobParams common_connect_job_params_;
Matt Menke977e61b2019-01-10 19:36:02117 TestConnectJobDelegate delegate_;
118};
119
120// Even though a timeout is specified, it doesn't time out on a synchronous
121// completion.
122TEST_F(ConnectJobTest, NoTimeoutOnSyncCompletion) {
123 TestConnectJob job(TestConnectJob::JobType::kSyncSuccess,
Peter Kastinge5a38ed2021-10-02 03:06:35124 base::Microseconds(1), &common_connect_job_params_,
125 &delegate_);
Matt Menke977e61b2019-01-10 19:36:02126 EXPECT_THAT(job.Connect(), test::IsOk());
127}
128
129// Even though a timeout is specified, it doesn't time out on an asynchronous
130// completion.
131TEST_F(ConnectJobTest, NoTimeoutOnAsyncCompletion) {
Peter Kastinge5a38ed2021-10-02 03:06:35132 TestConnectJob job(TestConnectJob::JobType::kAsyncSuccess, base::Minutes(1),
Matt Menkea6f99ad2019-03-08 02:26:43133 &common_connect_job_params_, &delegate_);
Matt Menke977e61b2019-01-10 19:36:02134 ASSERT_THAT(job.Connect(), test::IsError(ERR_IO_PENDING));
135 EXPECT_THAT(delegate_.WaitForResult(), test::IsOk());
136}
137
138// Job shouldn't timeout when passed a TimeDelta of zero.
139TEST_F(ConnectJobTest, NoTimeoutWithNoTimeDelta) {
140 TestConnectJob job(TestConnectJob::JobType::kHung, base::TimeDelta(),
Matt Menkea6f99ad2019-03-08 02:26:43141 &common_connect_job_params_, &delegate_);
Matt Menke977e61b2019-01-10 19:36:02142 ASSERT_THAT(job.Connect(), test::IsError(ERR_IO_PENDING));
Gabriel Charette694c3c332019-08-19 14:53:05143 task_environment_.RunUntilIdle();
Matt Menke977e61b2019-01-10 19:36:02144 EXPECT_FALSE(delegate_.has_result());
145}
146
147// Make sure that ChangePriority() works, and new priority is visible to
148// subclasses during the SetPriorityInternal call.
149TEST_F(ConnectJobTest, SetPriority) {
150 TestConnectJob job(TestConnectJob::JobType::kAsyncSuccess,
Peter Kastinge5a38ed2021-10-02 03:06:35151 base::Microseconds(1), &common_connect_job_params_,
152 &delegate_);
Matt Menke977e61b2019-01-10 19:36:02153 ASSERT_THAT(job.Connect(), test::IsError(ERR_IO_PENDING));
154
155 job.ChangePriority(HIGHEST);
156 EXPECT_EQ(HIGHEST, job.priority());
157 EXPECT_EQ(HIGHEST, job.last_seen_priority());
158
159 job.ChangePriority(MEDIUM);
160 EXPECT_EQ(MEDIUM, job.priority());
161 EXPECT_EQ(MEDIUM, job.last_seen_priority());
162
163 EXPECT_THAT(delegate_.WaitForResult(), test::IsOk());
164}
165
166TEST_F(ConnectJobTest, TimedOut) {
Peter Kastinge5a38ed2021-10-02 03:06:35167 const base::TimeDelta kTimeout = base::Hours(1);
Matt Menke977e61b2019-01-10 19:36:02168
Matt Menkea6f99ad2019-03-08 02:26:43169 std::unique_ptr<TestConnectJob> job =
170 std::make_unique<TestConnectJob>(TestConnectJob::JobType::kHung, kTimeout,
171 &common_connect_job_params_, &delegate_);
Matt Menke977e61b2019-01-10 19:36:02172 ASSERT_THAT(job->Connect(), test::IsError(ERR_IO_PENDING));
173
174 // Nothing should happen before the specified time.
Peter Kastinge5a38ed2021-10-02 03:06:35175 task_environment_.FastForwardBy(kTimeout - base::Milliseconds(1));
Matt Menke977e61b2019-01-10 19:36:02176 base::RunLoop().RunUntilIdle();
177 EXPECT_FALSE(delegate_.has_result());
178
179 // At which point the job should time out.
Peter Kastinge5a38ed2021-10-02 03:06:35180 task_environment_.FastForwardBy(base::Milliseconds(1));
Matt Menke977e61b2019-01-10 19:36:02181 EXPECT_THAT(delegate_.WaitForResult(), test::IsError(ERR_TIMED_OUT));
182
183 // Have to delete the job for it to log the end event.
184 job.reset();
185
Matt Reichhoff36a1fd62021-10-12 22:52:20186 auto entries = net_log_observer_.GetEntries();
Matt Menke977e61b2019-01-10 19:36:02187
188 EXPECT_EQ(6u, entries.size());
Matt Menke1a6c92d2019-02-23 00:25:38189 EXPECT_TRUE(LogContainsBeginEvent(entries, 0, NetLogEventType::CONNECT_JOB));
Matt Menke977e61b2019-01-10 19:36:02190 EXPECT_TRUE(LogContainsBeginEvent(
Matt Menke1a6c92d2019-02-23 00:25:38191 entries, 1, NetLogEventType::TRANSPORT_CONNECT_JOB_CONNECT));
Matt Menke977e61b2019-01-10 19:36:02192 EXPECT_TRUE(LogContainsEvent(entries, 2,
193 NetLogEventType::CONNECT_JOB_SET_SOCKET,
194 NetLogEventPhase::NONE));
Matt Menke1a6c92d2019-02-23 00:25:38195 EXPECT_TRUE(LogContainsEvent(entries, 3,
196 NetLogEventType::CONNECT_JOB_TIMED_OUT,
197 NetLogEventPhase::NONE));
Matt Menke977e61b2019-01-10 19:36:02198 EXPECT_TRUE(LogContainsEndEvent(
Matt Menke1a6c92d2019-02-23 00:25:38199 entries, 4, NetLogEventType::TRANSPORT_CONNECT_JOB_CONNECT));
200 EXPECT_TRUE(LogContainsEndEvent(entries, 5, NetLogEventType::CONNECT_JOB));
Matt Menke977e61b2019-01-10 19:36:02201}
202
203TEST_F(ConnectJobTest, TimedOutWithRestartedTimer) {
Peter Kastinge5a38ed2021-10-02 03:06:35204 const base::TimeDelta kTimeout = base::Hours(1);
Matt Menke977e61b2019-01-10 19:36:02205
Matt Menkea6f99ad2019-03-08 02:26:43206 TestConnectJob job(TestConnectJob::JobType::kHung, kTimeout,
207 &common_connect_job_params_, &delegate_);
Matt Menke977e61b2019-01-10 19:36:02208 ASSERT_THAT(job.Connect(), test::IsError(ERR_IO_PENDING));
209
210 // Nothing should happen before the specified time.
Peter Kastinge5a38ed2021-10-02 03:06:35211 task_environment_.FastForwardBy(kTimeout - base::Milliseconds(1));
Matt Menke977e61b2019-01-10 19:36:02212 base::RunLoop().RunUntilIdle();
213 EXPECT_FALSE(delegate_.has_result());
214
215 // Make sure restarting the timer is respected.
216 job.ResetTimer(kTimeout);
Peter Kastinge5a38ed2021-10-02 03:06:35217 task_environment_.FastForwardBy(kTimeout - base::Milliseconds(1));
Matt Menke977e61b2019-01-10 19:36:02218 base::RunLoop().RunUntilIdle();
219 EXPECT_FALSE(delegate_.has_result());
220
Peter Kastinge5a38ed2021-10-02 03:06:35221 task_environment_.FastForwardBy(base::Milliseconds(1));
Matt Menke977e61b2019-01-10 19:36:02222 EXPECT_THAT(delegate_.WaitForResult(), test::IsError(ERR_TIMED_OUT));
223}
224
225} // namespace
226} // namespace net