blob: 175ea34ee0efb15d59a509c2eeb6fd11ffb34cb8 [file] [log] [blame]
Matt Menke977e61b2019-01-10 19:36:021// Copyright 2018 The Chromium Authors. All rights reserved.
2// 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
Sebastien Marchand6d0558fd2019-01-25 16:49:377#include "base/bind.h"
Matt Menke977e61b2019-01-10 19:36:028#include "base/callback.h"
9#include "base/logging.h"
10#include "base/macros.h"
11#include "base/run_loop.h"
12#include "base/test/scoped_task_environment.h"
13#include "net/base/address_list.h"
14#include "net/base/net_errors.h"
15#include "net/base/request_priority.h"
16#include "net/log/test_net_log.h"
17#include "net/log/test_net_log_util.h"
Matt Menke3abc57c2019-01-10 21:48:4218#include "net/socket/connect_job_test_util.h"
Matt Menke977e61b2019-01-10 19:36:0219#include "net/socket/socket_tag.h"
20#include "net/socket/socket_test_util.h"
21#include "net/test/gtest_util.h"
22#include "testing/gtest/include/gtest/gtest.h"
23
24namespace net {
25namespace {
26
Matt Menke977e61b2019-01-10 19:36:0227class TestConnectJob : public ConnectJob {
28 public:
29 enum class JobType {
30 kSyncSuccess,
31 kAsyncSuccess,
32 kHung,
33 };
34
35 TestConnectJob(JobType job_type,
36 base::TimeDelta timeout_duration,
Matt Menkea6f99ad2019-03-08 02:26:4337 const CommonConnectJobParams* common_connect_job_params,
38 ConnectJob::Delegate* delegate)
Matt Menke1a6c92d2019-02-23 00:25:3839 : ConnectJob(DEFAULT_PRIORITY,
Matt Menkea6f99ad2019-03-08 02:26:4340 SocketTag(),
Matt Menke1a6c92d2019-02-23 00:25:3841 timeout_duration,
Matt Menkea6f99ad2019-03-08 02:26:4342 common_connect_job_params,
Matt Menke1a6c92d2019-02-23 00:25:3843 delegate,
44 nullptr /* net_log */,
45 NetLogSourceType::TRANSPORT_CONNECT_JOB,
46 NetLogEventType::TRANSPORT_CONNECT_JOB_CONNECT),
Matt Menke977e61b2019-01-10 19:36:0247 job_type_(job_type),
48 last_seen_priority_(DEFAULT_PRIORITY) {
49 switch (job_type_) {
50 case JobType::kSyncSuccess:
51 socket_data_provider_.set_connect_data(MockConnect(SYNCHRONOUS, OK));
52 return;
53 case JobType::kAsyncSuccess:
54 socket_data_provider_.set_connect_data(MockConnect(ASYNC, OK));
55 return;
56 case JobType::kHung:
57 socket_data_provider_.set_connect_data(
58 MockConnect(SYNCHRONOUS, ERR_IO_PENDING));
59 return;
60 }
61 }
62
63 // From ConnectJob:
64 LoadState GetLoadState() const override { return LOAD_STATE_IDLE; }
Matt Menke141b87f22019-01-30 02:43:0365 bool HasEstablishedConnection() const override { return false; }
Matt Menke977e61b2019-01-10 19:36:0266 int ConnectInternal() override {
67 SetSocket(std::unique_ptr<StreamSocket>(new MockTCPClientSocket(
68 AddressList(), net_log().net_log(), &socket_data_provider_)));
69 return socket()->Connect(base::BindOnce(
70 &TestConnectJob::NotifyDelegateOfCompletion, base::Unretained(this)));
71 }
72 void ChangePriorityInternal(RequestPriority priority) override {
73 last_seen_priority_ = priority;
74 }
75
76 using ConnectJob::ResetTimer;
77
78 // The priority seen during the most recent call to ChangePriorityInternal().
79 RequestPriority last_seen_priority() const { return last_seen_priority_; }
80
Matt Menkea6f99ad2019-03-08 02:26:4381 protected:
Matt Menke977e61b2019-01-10 19:36:0282 const JobType job_type_;
83 StaticSocketDataProvider socket_data_provider_;
84 RequestPriority last_seen_priority_;
85
86 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
87};
88
89class ConnectJobTest : public testing::Test {
90 public:
91 ConnectJobTest()
Gabriel Charette694c3c332019-08-19 14:53:0592 : task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME),
Matt Menkea6f99ad2019-03-08 02:26:4393 common_connect_job_params_(
94 nullptr /* client_socket_factory */,
95 nullptr /* host_resolver */,
Matt Menkeb88837e2019-03-20 11:50:4096 nullptr /* http_auth_cache */,
97 nullptr /* http_auth_handler_factory */,
98 nullptr /* spdy_session_pool */,
Matt Menkeb5fb42b2019-03-22 17:26:1399 nullptr /* quic_supported_versions */,
Matt Menkeb88837e2019-03-20 11:50:40100 nullptr /* quic_stream_factory */,
Matt Menkea6f99ad2019-03-08 02:26:43101 nullptr /* proxy_delegate */,
Matt Menked732ea42019-03-08 12:05:00102 nullptr /* http_user_agent_settings */,
David Benjamin24725be2019-07-24 20:57:18103 nullptr /* ssl_client_context */,
Matt Menkea6f99ad2019-03-08 02:26:43104 nullptr /* socket_performance_watcher_factory */,
105 nullptr /* network_quality_estimator */,
106 &net_log_,
107 nullptr /* websocket_endpoint_lock_manager */) {}
Matt Menke977e61b2019-01-10 19:36:02108 ~ConnectJobTest() override = default;
109
110 protected:
Gabriel Charette694c3c332019-08-19 14:53:05111 base::test::TaskEnvironment task_environment_;
Matt Menkea6f99ad2019-03-08 02:26:43112 TestNetLog net_log_;
113 const CommonConnectJobParams common_connect_job_params_;
Matt Menke977e61b2019-01-10 19:36:02114 TestConnectJobDelegate delegate_;
115};
116
117// Even though a timeout is specified, it doesn't time out on a synchronous
118// completion.
119TEST_F(ConnectJobTest, NoTimeoutOnSyncCompletion) {
120 TestConnectJob job(TestConnectJob::JobType::kSyncSuccess,
Matt Menkea6f99ad2019-03-08 02:26:43121 base::TimeDelta::FromMicroseconds(1),
122 &common_connect_job_params_, &delegate_);
Matt Menke977e61b2019-01-10 19:36:02123 EXPECT_THAT(job.Connect(), test::IsOk());
124}
125
126// Even though a timeout is specified, it doesn't time out on an asynchronous
127// completion.
128TEST_F(ConnectJobTest, NoTimeoutOnAsyncCompletion) {
129 TestConnectJob job(TestConnectJob::JobType::kAsyncSuccess,
Matt Menkea6f99ad2019-03-08 02:26:43130 base::TimeDelta::FromMinutes(1),
131 &common_connect_job_params_, &delegate_);
Matt Menke977e61b2019-01-10 19:36:02132 ASSERT_THAT(job.Connect(), test::IsError(ERR_IO_PENDING));
133 EXPECT_THAT(delegate_.WaitForResult(), test::IsOk());
134}
135
136// Job shouldn't timeout when passed a TimeDelta of zero.
137TEST_F(ConnectJobTest, NoTimeoutWithNoTimeDelta) {
138 TestConnectJob job(TestConnectJob::JobType::kHung, base::TimeDelta(),
Matt Menkea6f99ad2019-03-08 02:26:43139 &common_connect_job_params_, &delegate_);
Matt Menke977e61b2019-01-10 19:36:02140 ASSERT_THAT(job.Connect(), test::IsError(ERR_IO_PENDING));
Gabriel Charette694c3c332019-08-19 14:53:05141 task_environment_.RunUntilIdle();
Matt Menke977e61b2019-01-10 19:36:02142 EXPECT_FALSE(delegate_.has_result());
143}
144
145// Make sure that ChangePriority() works, and new priority is visible to
146// subclasses during the SetPriorityInternal call.
147TEST_F(ConnectJobTest, SetPriority) {
148 TestConnectJob job(TestConnectJob::JobType::kAsyncSuccess,
Matt Menkea6f99ad2019-03-08 02:26:43149 base::TimeDelta::FromMicroseconds(1),
150 &common_connect_job_params_, &delegate_);
Matt Menke977e61b2019-01-10 19:36:02151 ASSERT_THAT(job.Connect(), test::IsError(ERR_IO_PENDING));
152
153 job.ChangePriority(HIGHEST);
154 EXPECT_EQ(HIGHEST, job.priority());
155 EXPECT_EQ(HIGHEST, job.last_seen_priority());
156
157 job.ChangePriority(MEDIUM);
158 EXPECT_EQ(MEDIUM, job.priority());
159 EXPECT_EQ(MEDIUM, job.last_seen_priority());
160
161 EXPECT_THAT(delegate_.WaitForResult(), test::IsOk());
162}
163
164TEST_F(ConnectJobTest, TimedOut) {
165 const base::TimeDelta kTimeout = base::TimeDelta::FromHours(1);
Matt Menke977e61b2019-01-10 19:36:02166
Matt Menkea6f99ad2019-03-08 02:26:43167 std::unique_ptr<TestConnectJob> job =
168 std::make_unique<TestConnectJob>(TestConnectJob::JobType::kHung, kTimeout,
169 &common_connect_job_params_, &delegate_);
Matt Menke977e61b2019-01-10 19:36:02170 ASSERT_THAT(job->Connect(), test::IsError(ERR_IO_PENDING));
171
172 // Nothing should happen before the specified time.
Gabriel Charette694c3c332019-08-19 14:53:05173 task_environment_.FastForwardBy(kTimeout -
174 base::TimeDelta::FromMilliseconds(1));
Matt Menke977e61b2019-01-10 19:36:02175 base::RunLoop().RunUntilIdle();
176 EXPECT_FALSE(delegate_.has_result());
177
178 // At which point the job should time out.
Gabriel Charette694c3c332019-08-19 14:53:05179 task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(1));
Matt Menke977e61b2019-01-10 19:36:02180 EXPECT_THAT(delegate_.WaitForResult(), test::IsError(ERR_TIMED_OUT));
181
182 // Have to delete the job for it to log the end event.
183 job.reset();
184
Eric Roman79cc7552019-07-19 02:17:54185 auto entries = net_log_.GetEntries();
Matt Menke977e61b2019-01-10 19:36:02186
187 EXPECT_EQ(6u, entries.size());
Matt Menke1a6c92d2019-02-23 00:25:38188 EXPECT_TRUE(LogContainsBeginEvent(entries, 0, NetLogEventType::CONNECT_JOB));
Matt Menke977e61b2019-01-10 19:36:02189 EXPECT_TRUE(LogContainsBeginEvent(
Matt Menke1a6c92d2019-02-23 00:25:38190 entries, 1, NetLogEventType::TRANSPORT_CONNECT_JOB_CONNECT));
Matt Menke977e61b2019-01-10 19:36:02191 EXPECT_TRUE(LogContainsEvent(entries, 2,
192 NetLogEventType::CONNECT_JOB_SET_SOCKET,
193 NetLogEventPhase::NONE));
Matt Menke1a6c92d2019-02-23 00:25:38194 EXPECT_TRUE(LogContainsEvent(entries, 3,
195 NetLogEventType::CONNECT_JOB_TIMED_OUT,
196 NetLogEventPhase::NONE));
Matt Menke977e61b2019-01-10 19:36:02197 EXPECT_TRUE(LogContainsEndEvent(
Matt Menke1a6c92d2019-02-23 00:25:38198 entries, 4, NetLogEventType::TRANSPORT_CONNECT_JOB_CONNECT));
199 EXPECT_TRUE(LogContainsEndEvent(entries, 5, NetLogEventType::CONNECT_JOB));
Matt Menke977e61b2019-01-10 19:36:02200}
201
202TEST_F(ConnectJobTest, TimedOutWithRestartedTimer) {
203 const base::TimeDelta kTimeout = base::TimeDelta::FromHours(1);
204
Matt Menkea6f99ad2019-03-08 02:26:43205 TestConnectJob job(TestConnectJob::JobType::kHung, kTimeout,
206 &common_connect_job_params_, &delegate_);
Matt Menke977e61b2019-01-10 19:36:02207 ASSERT_THAT(job.Connect(), test::IsError(ERR_IO_PENDING));
208
209 // Nothing should happen before the specified time.
Gabriel Charette694c3c332019-08-19 14:53:05210 task_environment_.FastForwardBy(kTimeout -
211 base::TimeDelta::FromMilliseconds(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);
Gabriel Charette694c3c332019-08-19 14:53:05217 task_environment_.FastForwardBy(kTimeout -
218 base::TimeDelta::FromMilliseconds(1));
Matt Menke977e61b2019-01-10 19:36:02219 base::RunLoop().RunUntilIdle();
220 EXPECT_FALSE(delegate_.has_result());
221
Gabriel Charette694c3c332019-08-19 14:53:05222 task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(1));
Matt Menke977e61b2019-01-10 19:36:02223 EXPECT_THAT(delegate_.WaitForResult(), test::IsError(ERR_TIMED_OUT));
224}
225
226} // namespace
227} // namespace net