blob: 8c826557bb96e36b3fc24b8c498ee5b7042e9aa0 [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"
Gabriel Charettec7108742019-08-23 03:31:4012#include "base/test/task_environment.h"
Matt Menke977e61b2019-01-10 19:36:0213#include "net/base/address_list.h"
14#include "net/base/net_errors.h"
15#include "net/base/request_priority.h"
dalykedd30d982019-12-16 15:31:1016#include "net/dns/public/resolve_error_info.h"
Matt Menke977e61b2019-01-10 19:36:0217#include "net/log/test_net_log.h"
18#include "net/log/test_net_log_util.h"
Matt Menke3abc57c2019-01-10 21:48:4219#include "net/socket/connect_job_test_util.h"
Matt Menke977e61b2019-01-10 19:36:0220#include "net/socket/socket_tag.h"
21#include "net/socket/socket_test_util.h"
22#include "net/test/gtest_util.h"
23#include "testing/gtest/include/gtest/gtest.h"
24
25namespace net {
26namespace {
27
Matt Menke977e61b2019-01-10 19:36:0228class TestConnectJob : public ConnectJob {
29 public:
30 enum class JobType {
31 kSyncSuccess,
32 kAsyncSuccess,
33 kHung,
34 };
35
36 TestConnectJob(JobType job_type,
37 base::TimeDelta timeout_duration,
Matt Menkea6f99ad2019-03-08 02:26:4338 const CommonConnectJobParams* common_connect_job_params,
39 ConnectJob::Delegate* delegate)
Matt Menke1a6c92d2019-02-23 00:25:3840 : ConnectJob(DEFAULT_PRIORITY,
Matt Menkea6f99ad2019-03-08 02:26:4341 SocketTag(),
Matt Menke1a6c92d2019-02-23 00:25:3842 timeout_duration,
Matt Menkea6f99ad2019-03-08 02:26:4343 common_connect_job_params,
Matt Menke1a6c92d2019-02-23 00:25:3844 delegate,
45 nullptr /* net_log */,
46 NetLogSourceType::TRANSPORT_CONNECT_JOB,
47 NetLogEventType::TRANSPORT_CONNECT_JOB_CONNECT),
Matt Menke977e61b2019-01-10 19:36:0248 job_type_(job_type),
49 last_seen_priority_(DEFAULT_PRIORITY) {
50 switch (job_type_) {
51 case JobType::kSyncSuccess:
52 socket_data_provider_.set_connect_data(MockConnect(SYNCHRONOUS, OK));
53 return;
54 case JobType::kAsyncSuccess:
55 socket_data_provider_.set_connect_data(MockConnect(ASYNC, OK));
56 return;
57 case JobType::kHung:
58 socket_data_provider_.set_connect_data(
59 MockConnect(SYNCHRONOUS, ERR_IO_PENDING));
60 return;
61 }
62 }
63
64 // 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 {
71 SetSocket(std::unique_ptr<StreamSocket>(new MockTCPClientSocket(
72 AddressList(), net_log().net_log(), &socket_data_provider_)));
73 return socket()->Connect(base::BindOnce(
74 &TestConnectJob::NotifyDelegateOfCompletion, base::Unretained(this)));
75 }
76 void ChangePriorityInternal(RequestPriority priority) override {
77 last_seen_priority_ = priority;
78 }
79
80 using ConnectJob::ResetTimer;
81
82 // The priority seen during the most recent call to ChangePriorityInternal().
83 RequestPriority last_seen_priority() const { return last_seen_priority_; }
84
Matt Menkea6f99ad2019-03-08 02:26:4385 protected:
Matt Menke977e61b2019-01-10 19:36:0286 const JobType job_type_;
87 StaticSocketDataProvider socket_data_provider_;
88 RequestPriority last_seen_priority_;
89
90 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
91};
92
93class ConnectJobTest : public testing::Test {
94 public:
95 ConnectJobTest()
Gabriel Charette694c3c332019-08-19 14:53:0596 : task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME),
Matt Menkea6f99ad2019-03-08 02:26:4397 common_connect_job_params_(
98 nullptr /* client_socket_factory */,
99 nullptr /* host_resolver */,
Matt Menkeb88837e2019-03-20 11:50:40100 nullptr /* http_auth_cache */,
101 nullptr /* http_auth_handler_factory */,
102 nullptr /* spdy_session_pool */,
Matt Menkeb5fb42b2019-03-22 17:26:13103 nullptr /* quic_supported_versions */,
Matt Menkeb88837e2019-03-20 11:50:40104 nullptr /* quic_stream_factory */,
Matt Menkea6f99ad2019-03-08 02:26:43105 nullptr /* proxy_delegate */,
Matt Menked732ea42019-03-08 12:05:00106 nullptr /* http_user_agent_settings */,
David Benjamin24725be2019-07-24 20:57:18107 nullptr /* ssl_client_context */,
Matt Menkea6f99ad2019-03-08 02:26:43108 nullptr /* socket_performance_watcher_factory */,
109 nullptr /* network_quality_estimator */,
110 &net_log_,
111 nullptr /* websocket_endpoint_lock_manager */) {}
Matt Menke977e61b2019-01-10 19:36:02112 ~ConnectJobTest() override = default;
113
114 protected:
Gabriel Charette694c3c332019-08-19 14:53:05115 base::test::TaskEnvironment task_environment_;
Matt Muellerd9342e3a2019-11-26 01:41:14116 RecordingTestNetLog net_log_;
Matt Menkea6f99ad2019-03-08 02:26:43117 const CommonConnectJobParams common_connect_job_params_;
Matt Menke977e61b2019-01-10 19:36:02118 TestConnectJobDelegate delegate_;
119};
120
121// Even though a timeout is specified, it doesn't time out on a synchronous
122// completion.
123TEST_F(ConnectJobTest, NoTimeoutOnSyncCompletion) {
124 TestConnectJob job(TestConnectJob::JobType::kSyncSuccess,
Matt Menkea6f99ad2019-03-08 02:26:43125 base::TimeDelta::FromMicroseconds(1),
126 &common_connect_job_params_, &delegate_);
Matt Menke977e61b2019-01-10 19:36:02127 EXPECT_THAT(job.Connect(), test::IsOk());
128}
129
130// Even though a timeout is specified, it doesn't time out on an asynchronous
131// completion.
132TEST_F(ConnectJobTest, NoTimeoutOnAsyncCompletion) {
133 TestConnectJob job(TestConnectJob::JobType::kAsyncSuccess,
Matt Menkea6f99ad2019-03-08 02:26:43134 base::TimeDelta::FromMinutes(1),
135 &common_connect_job_params_, &delegate_);
Matt Menke977e61b2019-01-10 19:36:02136 ASSERT_THAT(job.Connect(), test::IsError(ERR_IO_PENDING));
137 EXPECT_THAT(delegate_.WaitForResult(), test::IsOk());
138}
139
140// Job shouldn't timeout when passed a TimeDelta of zero.
141TEST_F(ConnectJobTest, NoTimeoutWithNoTimeDelta) {
142 TestConnectJob job(TestConnectJob::JobType::kHung, base::TimeDelta(),
Matt Menkea6f99ad2019-03-08 02:26:43143 &common_connect_job_params_, &delegate_);
Matt Menke977e61b2019-01-10 19:36:02144 ASSERT_THAT(job.Connect(), test::IsError(ERR_IO_PENDING));
Gabriel Charette694c3c332019-08-19 14:53:05145 task_environment_.RunUntilIdle();
Matt Menke977e61b2019-01-10 19:36:02146 EXPECT_FALSE(delegate_.has_result());
147}
148
149// Make sure that ChangePriority() works, and new priority is visible to
150// subclasses during the SetPriorityInternal call.
151TEST_F(ConnectJobTest, SetPriority) {
152 TestConnectJob job(TestConnectJob::JobType::kAsyncSuccess,
Matt Menkea6f99ad2019-03-08 02:26:43153 base::TimeDelta::FromMicroseconds(1),
154 &common_connect_job_params_, &delegate_);
Matt Menke977e61b2019-01-10 19:36:02155 ASSERT_THAT(job.Connect(), test::IsError(ERR_IO_PENDING));
156
157 job.ChangePriority(HIGHEST);
158 EXPECT_EQ(HIGHEST, job.priority());
159 EXPECT_EQ(HIGHEST, job.last_seen_priority());
160
161 job.ChangePriority(MEDIUM);
162 EXPECT_EQ(MEDIUM, job.priority());
163 EXPECT_EQ(MEDIUM, job.last_seen_priority());
164
165 EXPECT_THAT(delegate_.WaitForResult(), test::IsOk());
166}
167
168TEST_F(ConnectJobTest, TimedOut) {
169 const base::TimeDelta kTimeout = base::TimeDelta::FromHours(1);
Matt Menke977e61b2019-01-10 19:36:02170
Matt Menkea6f99ad2019-03-08 02:26:43171 std::unique_ptr<TestConnectJob> job =
172 std::make_unique<TestConnectJob>(TestConnectJob::JobType::kHung, kTimeout,
173 &common_connect_job_params_, &delegate_);
Matt Menke977e61b2019-01-10 19:36:02174 ASSERT_THAT(job->Connect(), test::IsError(ERR_IO_PENDING));
175
176 // Nothing should happen before the specified time.
Gabriel Charette694c3c332019-08-19 14:53:05177 task_environment_.FastForwardBy(kTimeout -
178 base::TimeDelta::FromMilliseconds(1));
Matt Menke977e61b2019-01-10 19:36:02179 base::RunLoop().RunUntilIdle();
180 EXPECT_FALSE(delegate_.has_result());
181
182 // At which point the job should time out.
Gabriel Charette694c3c332019-08-19 14:53:05183 task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(1));
Matt Menke977e61b2019-01-10 19:36:02184 EXPECT_THAT(delegate_.WaitForResult(), test::IsError(ERR_TIMED_OUT));
185
186 // Have to delete the job for it to log the end event.
187 job.reset();
188
Eric Roman79cc7552019-07-19 02:17:54189 auto entries = net_log_.GetEntries();
Matt Menke977e61b2019-01-10 19:36:02190
191 EXPECT_EQ(6u, entries.size());
Matt Menke1a6c92d2019-02-23 00:25:38192 EXPECT_TRUE(LogContainsBeginEvent(entries, 0, NetLogEventType::CONNECT_JOB));
Matt Menke977e61b2019-01-10 19:36:02193 EXPECT_TRUE(LogContainsBeginEvent(
Matt Menke1a6c92d2019-02-23 00:25:38194 entries, 1, NetLogEventType::TRANSPORT_CONNECT_JOB_CONNECT));
Matt Menke977e61b2019-01-10 19:36:02195 EXPECT_TRUE(LogContainsEvent(entries, 2,
196 NetLogEventType::CONNECT_JOB_SET_SOCKET,
197 NetLogEventPhase::NONE));
Matt Menke1a6c92d2019-02-23 00:25:38198 EXPECT_TRUE(LogContainsEvent(entries, 3,
199 NetLogEventType::CONNECT_JOB_TIMED_OUT,
200 NetLogEventPhase::NONE));
Matt Menke977e61b2019-01-10 19:36:02201 EXPECT_TRUE(LogContainsEndEvent(
Matt Menke1a6c92d2019-02-23 00:25:38202 entries, 4, NetLogEventType::TRANSPORT_CONNECT_JOB_CONNECT));
203 EXPECT_TRUE(LogContainsEndEvent(entries, 5, NetLogEventType::CONNECT_JOB));
Matt Menke977e61b2019-01-10 19:36:02204}
205
206TEST_F(ConnectJobTest, TimedOutWithRestartedTimer) {
207 const base::TimeDelta kTimeout = base::TimeDelta::FromHours(1);
208
Matt Menkea6f99ad2019-03-08 02:26:43209 TestConnectJob job(TestConnectJob::JobType::kHung, kTimeout,
210 &common_connect_job_params_, &delegate_);
Matt Menke977e61b2019-01-10 19:36:02211 ASSERT_THAT(job.Connect(), test::IsError(ERR_IO_PENDING));
212
213 // Nothing should happen before the specified time.
Gabriel Charette694c3c332019-08-19 14:53:05214 task_environment_.FastForwardBy(kTimeout -
215 base::TimeDelta::FromMilliseconds(1));
Matt Menke977e61b2019-01-10 19:36:02216 base::RunLoop().RunUntilIdle();
217 EXPECT_FALSE(delegate_.has_result());
218
219 // Make sure restarting the timer is respected.
220 job.ResetTimer(kTimeout);
Gabriel Charette694c3c332019-08-19 14:53:05221 task_environment_.FastForwardBy(kTimeout -
222 base::TimeDelta::FromMilliseconds(1));
Matt Menke977e61b2019-01-10 19:36:02223 base::RunLoop().RunUntilIdle();
224 EXPECT_FALSE(delegate_.has_result());
225
Gabriel Charette694c3c332019-08-19 14:53:05226 task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(1));
Matt Menke977e61b2019-01-10 19:36:02227 EXPECT_THAT(delegate_.WaitForResult(), test::IsError(ERR_TIMED_OUT));
228}
229
230} // namespace
231} // namespace net