blob: 38c57bb3dcb1be2884466682dc755307b0d88c7a [file] [log] [blame]
[email protected]e34400c32012-01-24 02:49:331// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]f6d1d6eb2009-06-24 20:16:092// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Matt Menke9fa17d52019-03-25 19:12:265#include "net/socket/transport_client_socket_pool.h"
[email protected]f6d1d6eb2009-06-24 20:16:096
tbansalf82cc8e2015-10-14 20:05:497#include <stdint.h>
dchengc7eeda422015-12-26 03:56:488#include <utility>
[email protected]51fdc7c2012-04-10 19:19:489#include <vector>
10
[email protected]6ecf2b92011-12-15 01:14:5211#include "base/bind.h"
12#include "base/bind_helpers.h"
[email protected]2041cf342010-02-19 03:15:5913#include "base/callback.h"
skyostil4891b25b2015-06-11 11:43:4514#include "base/location.h"
mmenke33d24423d2015-05-19 19:41:0915#include "base/logging.h"
[email protected]3b63f8f42011-03-28 01:54:1516#include "base/memory/ref_counted.h"
[email protected]6ea7b152011-12-21 21:21:1317#include "base/memory/weak_ptr.h"
Alexander Timin4f9c35c2018-11-01 20:15:2018#include "base/message_loop/message_loop.h"
Matt Menkef09e64c2019-04-23 22:16:2819#include "base/optional.h"
[email protected]034df0f32013-01-07 23:17:4820#include "base/run_loop.h"
skyostil4891b25b2015-06-11 11:43:4521#include "base/single_thread_task_runner.h"
Avi Drissman4365a4782018-12-28 19:26:2422#include "base/stl_util.h"
[email protected]fc9be5802013-06-11 10:56:5123#include "base/strings/string_number_conversions.h"
[email protected]18b577412013-07-18 04:19:1524#include "base/strings/stringprintf.h"
[email protected]f214f8792011-01-01 02:17:0825#include "base/threading/platform_thread.h"
gabf767595f2016-05-11 18:50:3526#include "base/threading/thread_task_runner_handle.h"
[email protected]f3a1c642011-07-12 19:15:0327#include "base/values.h"
[email protected]034df0f32013-01-07 23:17:4828#include "net/base/load_timing_info.h"
[email protected]b258e0792013-01-12 07:11:5929#include "net/base/load_timing_info_test_util.h"
[email protected]d8eb84242010-09-25 02:25:0630#include "net/base/net_errors.h"
Matt Menkebdf777802019-04-22 19:38:5931#include "net/base/privacy_mode.h"
Matt Menkeaafff542019-04-22 22:09:3632#include "net/base/proxy_server.h"
[email protected]ac790b42009-12-02 04:31:3133#include "net/base/request_priority.h"
[email protected]f6d1d6eb2009-06-24 20:16:0934#include "net/base/test_completion_callback.h"
[email protected]277d5942010-08-11 21:02:3535#include "net/http/http_response_headers.h"
Matt Menke39b7c5a2019-04-10 19:47:5136#include "net/http/http_response_info.h"
eroman87c53d62015-04-02 06:51:0737#include "net/log/net_log.h"
mikecirone8b85c432016-09-08 19:11:0038#include "net/log/net_log_event_type.h"
mikecironef22f9812016-10-04 03:40:1939#include "net/log/net_log_source.h"
mikecirone8b85c432016-09-08 19:11:0040#include "net/log/net_log_source_type.h"
mmenke16a7cbdd2015-04-24 23:00:5641#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4642#include "net/log/test_net_log_entry.h"
43#include "net/log/test_net_log_util.h"
[email protected]f6d1d6eb2009-06-24 20:16:0944#include "net/socket/client_socket_factory.h"
45#include "net/socket/client_socket_handle.h"
tfarina5dd13c22016-11-16 12:08:2646#include "net/socket/datagram_client_socket.h"
tbansalca83c002016-04-28 20:56:2847#include "net/socket/socket_performance_watcher.h"
Paul Jensen8d6f87ec2018-01-13 00:46:5448#include "net/socket/socket_tag.h"
[email protected]75439d3b2009-07-23 22:11:1749#include "net/socket/socket_test_util.h"
[email protected]18ccfdb2013-08-15 00:13:4450#include "net/socket/ssl_client_socket.h"
[email protected]3268023f2011-05-05 00:08:1051#include "net/socket/stream_socket.h"
Matt Menke9fa17d52019-03-25 19:12:2652#include "net/socket/transport_connect_job.h"
Matt Menke39b7c5a2019-04-10 19:47:5153#include "net/ssl/ssl_cert_request_info.h"
robpercival214763f2016-07-01 23:27:0154#include "net/test/gtest_util.h"
Bence Béky98447b12018-05-08 03:14:0155#include "net/test/test_with_scoped_task_environment.h"
Matt Menkef09e64c2019-04-23 22:16:2856#include "net/traffic_annotation/network_traffic_annotation.h"
Ramin Halavati0a08cc82018-02-06 07:46:3857#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
[email protected]51fdc7c2012-04-10 19:19:4858#include "testing/gmock/include/gmock/gmock.h"
[email protected]f6d1d6eb2009-06-24 20:16:0959#include "testing/gtest/include/gtest/gtest.h"
60
robpercival214763f2016-07-01 23:27:0161using net::test::IsError;
62using net::test::IsOk;
63
[email protected]51fdc7c2012-04-10 19:19:4864using ::testing::Invoke;
65using ::testing::Return;
66
[email protected]f6d1d6eb2009-06-24 20:16:0967namespace net {
68
69namespace {
70
[email protected]211d21722009-07-22 15:48:5371const int kDefaultMaxSockets = 4;
[email protected]c9d6a1d2009-07-14 16:15:2072const int kDefaultMaxSocketsPerGroup = 2;
Tarun Bansala7635092019-02-20 10:00:5973constexpr base::TimeDelta kUnusedIdleSocketTimeout =
74 base::TimeDelta::FromSeconds(10);
[email protected]0b7648c2009-07-06 20:14:0175
Matt Menkebdf777802019-04-22 19:38:5976ClientSocketPool::GroupId TestGroupId(
77 const std::string& host,
78 int port = 80,
79 ClientSocketPool::SocketType socket_type =
80 ClientSocketPool::SocketType::kHttp,
81 PrivacyMode privacy_mode = PrivacyMode::PRIVACY_MODE_DISABLED) {
Matt Menkec6b3edf72019-03-19 17:00:3982 return ClientSocketPool::GroupId(HostPortPair(host, port), socket_type,
83 privacy_mode);
84}
85
[email protected]034df0f32013-01-07 23:17:4886// Make sure |handle| sets load times correctly when it has been assigned a
87// reused socket.
88void TestLoadTimingInfoConnectedReused(const ClientSocketHandle& handle) {
89 LoadTimingInfo load_timing_info;
90 // Only pass true in as |is_reused|, as in general, HttpStream types should
91 // have stricter concepts of reuse than socket pools.
92 EXPECT_TRUE(handle.GetLoadTimingInfo(true, &load_timing_info));
93
94 EXPECT_EQ(true, load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:1995 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]034df0f32013-01-07 23:17:4896
[email protected]b258e0792013-01-12 07:11:5997 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
98 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:4899}
100
101// Make sure |handle| sets load times correctly when it has been assigned a
[email protected]b021ece62013-06-11 11:06:33102// fresh socket. Also runs TestLoadTimingInfoConnectedReused, since the owner
[email protected]034df0f32013-01-07 23:17:48103// of a connection where |is_reused| is false may consider the connection
104// reused.
105void TestLoadTimingInfoConnectedNotReused(const ClientSocketHandle& handle) {
106 EXPECT_FALSE(handle.is_reused());
107
108 LoadTimingInfo load_timing_info;
109 EXPECT_TRUE(handle.GetLoadTimingInfo(false, &load_timing_info));
110
111 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19112 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]034df0f32013-01-07 23:17:48113
[email protected]b258e0792013-01-12 07:11:59114 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
115 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
116 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:48117
118 TestLoadTimingInfoConnectedReused(handle);
119}
120
121// Make sure |handle| sets load times correctly, in the case that it does not
122// currently have a socket.
123void TestLoadTimingInfoNotConnected(const ClientSocketHandle& handle) {
124 // Should only be set to true once a socket is assigned, if at all.
125 EXPECT_FALSE(handle.is_reused());
126
127 LoadTimingInfo load_timing_info;
128 EXPECT_FALSE(handle.GetLoadTimingInfo(false, &load_timing_info));
129
130 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19131 EXPECT_EQ(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]034df0f32013-01-07 23:17:48132
[email protected]b258e0792013-01-12 07:11:59133 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
134 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:48135}
136
[email protected]3268023f2011-05-05 00:08:10137class MockClientSocket : public StreamSocket {
[email protected]f6d1d6eb2009-06-24 20:16:09138 public:
[email protected]034df0f32013-01-07 23:17:48139 explicit MockClientSocket(net::NetLog* net_log)
140 : connected_(false),
[email protected]0dc88b32014-03-26 20:12:28141 has_unread_data_(false),
tfarina428341112016-09-22 13:38:20142 net_log_(NetLogWithSource::Make(net_log, NetLogSourceType::SOCKET)),
Charlie Harrison3e4c0622018-05-13 15:44:30143 was_used_to_convey_data_(false) {}
[email protected]f6d1d6eb2009-06-24 20:16:09144
[email protected]0dc88b32014-03-26 20:12:28145 // Sets whether the socket has unread data. If true, the next call to Read()
146 // will return 1 byte and IsConnectedAndIdle() will return false.
147 void set_has_unread_data(bool has_unread_data) {
148 has_unread_data_ = has_unread_data;
149 }
150
[email protected]3f55aa12011-12-07 02:03:33151 // Socket implementation.
dchengb03027d2014-10-21 12:00:20152 int Read(IOBuffer* /* buf */,
153 int len,
Brad Lassey3a814172018-04-26 03:30:21154 CompletionOnceCallback /* callback */) override {
[email protected]0dc88b32014-03-26 20:12:28155 if (has_unread_data_ && len > 0) {
156 has_unread_data_ = false;
157 was_used_to_convey_data_ = true;
158 return 1;
159 }
[email protected]e86df8dc2013-03-30 13:18:28160 return ERR_UNEXPECTED;
[email protected]3f55aa12011-12-07 02:03:33161 }
[email protected]ab838892009-06-30 18:49:05162
[email protected]a2b2cfc2017-12-06 09:06:08163 int Write(
164 IOBuffer* /* buf */,
165 int len,
Brad Lassey3a814172018-04-26 03:30:21166 CompletionOnceCallback /* callback */,
[email protected]a2b2cfc2017-12-06 09:06:08167 const NetworkTrafficAnnotationTag& /*traffic_annotation*/) override {
[email protected]0f873e82010-09-02 16:09:01168 was_used_to_convey_data_ = true;
169 return len;
[email protected]ab838892009-06-30 18:49:05170 }
Avi Drissman13fc8932015-12-20 04:40:46171 int SetReceiveBufferSize(int32_t size) override { return OK; }
172 int SetSendBufferSize(int32_t size) override { return OK; }
[email protected]ab838892009-06-30 18:49:05173
[email protected]dbf036f2011-12-06 23:33:24174 // StreamSocket implementation.
Brad Lassey3a814172018-04-26 03:30:21175 int Connect(CompletionOnceCallback callback) override {
[email protected]dbf036f2011-12-06 23:33:24176 connected_ = true;
177 return OK;
178 }
[email protected]f6d1d6eb2009-06-24 20:16:09179
dchengb03027d2014-10-21 12:00:20180 void Disconnect() override { connected_ = false; }
181 bool IsConnected() const override { return connected_; }
182 bool IsConnectedAndIdle() const override {
[email protected]0dc88b32014-03-26 20:12:28183 return connected_ && !has_unread_data_;
184 }
[email protected]0b7648c2009-07-06 20:14:01185
dchengb03027d2014-10-21 12:00:20186 int GetPeerAddress(IPEndPoint* /* address */) const override {
[email protected]9f864b32010-01-20 15:01:16187 return ERR_UNEXPECTED;
[email protected]f6d1d6eb2009-06-24 20:16:09188 }
[email protected]f6d1d6eb2009-06-24 20:16:09189
dchengb03027d2014-10-21 12:00:20190 int GetLocalAddress(IPEndPoint* /* address */) const override {
[email protected]e7f74da2011-04-19 23:49:35191 return ERR_UNEXPECTED;
192 }
193
tfarina428341112016-09-22 13:38:20194 const NetLogWithSource& NetLog() const override { return net_log_; }
[email protected]a2006ece2010-04-23 16:44:02195
dchengb03027d2014-10-21 12:00:20196 bool WasEverUsed() const override { return was_used_to_convey_data_; }
tfarina2846404c2016-12-25 14:31:37197 bool WasAlpnNegotiated() const override { return false; }
dchengb03027d2014-10-21 12:00:20198 NextProto GetNegotiatedProtocol() const override { return kProtoUnknown; }
199 bool GetSSLInfo(SSLInfo* ssl_info) override { return false; }
ttuttle23fdb7b2015-05-15 01:28:03200 void GetConnectionAttempts(ConnectionAttempts* out) const override {
201 out->clear();
202 }
203 void ClearConnectionAttempts() override {}
204 void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
tbansalf82cc8e2015-10-14 20:05:49205 int64_t GetTotalReceivedBytes() const override {
206 NOTIMPLEMENTED();
207 return 0;
208 }
Paul Jensen0f49dec2017-12-12 23:39:58209 void ApplySocketTag(const SocketTag& tag) override {}
[email protected]9b5614a2010-08-25 20:29:45210
[email protected]f6d1d6eb2009-06-24 20:16:09211 private:
212 bool connected_;
[email protected]0dc88b32014-03-26 20:12:28213 bool has_unread_data_;
tfarina428341112016-09-22 13:38:20214 NetLogWithSource net_log_;
[email protected]0f873e82010-09-02 16:09:01215 bool was_used_to_convey_data_;
[email protected]f6d1d6eb2009-06-24 20:16:09216
[email protected]ab838892009-06-30 18:49:05217 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
[email protected]f6d1d6eb2009-06-24 20:16:09218};
219
[email protected]5fc08e32009-07-15 17:09:57220class TestConnectJob;
221
[email protected]f6d1d6eb2009-06-24 20:16:09222class MockClientSocketFactory : public ClientSocketFactory {
223 public:
[email protected]ab838892009-06-30 18:49:05224 MockClientSocketFactory() : allocation_count_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:09225
danakj655b66c2016-04-16 00:51:38226 std::unique_ptr<DatagramClientSocket> CreateDatagramClientSocket(
[email protected]5370c012011-06-29 03:47:04227 DatagramSocket::BindType bind_type,
[email protected]98b0e582011-06-22 14:31:41228 NetLog* net_log,
mikecironef22f9812016-10-04 03:40:19229 const NetLogSource& source) override {
[email protected]98b0e582011-06-22 14:31:41230 NOTREACHED();
danakj655b66c2016-04-16 00:51:38231 return std::unique_ptr<DatagramClientSocket>();
[email protected]98b0e582011-06-22 14:31:41232 }
233
Helen Lid5bb9222018-04-12 15:33:09234 std::unique_ptr<TransportClientSocket> CreateTransportClientSocket(
[email protected]0a0b7682010-08-25 17:08:07235 const AddressList& addresses,
danakj655b66c2016-04-16 00:51:38236 std::unique_ptr<
237 SocketPerformanceWatcher> /* socket_performance_watcher */,
[email protected]0a0b7682010-08-25 17:08:07238 NetLog* /* net_log */,
mikecironef22f9812016-10-04 03:40:19239 const NetLogSource& /*source*/) override {
[email protected]f6d1d6eb2009-06-24 20:16:09240 allocation_count_++;
Helen Lid5bb9222018-04-12 15:33:09241 return nullptr;
[email protected]f6d1d6eb2009-06-24 20:16:09242 }
243
danakj655b66c2016-04-16 00:51:38244 std::unique_ptr<SSLClientSocket> CreateSSLClientSocket(
Matt Menke841fc412019-03-05 23:20:12245 std::unique_ptr<StreamSocket> stream_socket,
[email protected]4f4de7e62010-11-12 19:55:27246 const HostPortPair& host_and_port,
[email protected]7ab5bbd12010-10-19 13:33:21247 const SSLConfig& ssl_config,
mostynbba063d6032014-10-09 11:01:13248 const SSLClientSocketContext& context) override {
[email protected]f6d1d6eb2009-06-24 20:16:09249 NOTIMPLEMENTED();
danakj655b66c2016-04-16 00:51:38250 return std::unique_ptr<SSLClientSocket>();
[email protected]f6d1d6eb2009-06-24 20:16:09251 }
Matt Menkefd956922019-02-04 23:44:03252
Matt Menke52cd95a2019-02-08 06:16:27253 std::unique_ptr<ProxyClientSocket> CreateProxyClientSocket(
254 std::unique_ptr<StreamSocket> stream_socket,
255 const std::string& user_agent,
256 const HostPortPair& endpoint,
257 const ProxyServer& proxy_server,
258 HttpAuthController* http_auth_controller,
259 bool tunnel,
260 bool using_spdy,
261 NextProto negotiated_protocol,
262 ProxyDelegate* proxy_delegate,
Matt Menke52cd95a2019-02-08 06:16:27263 const NetworkTrafficAnnotationTag& traffic_annotation) override {
264 NOTIMPLEMENTED();
265 return nullptr;
266 }
267
[email protected]5fc08e32009-07-15 17:09:57268 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
[email protected]03b7c8c2013-07-20 04:38:55269
[email protected]5fc08e32009-07-15 17:09:57270 void SignalJobs();
271
[email protected]03b7c8c2013-07-20 04:38:55272 void SignalJob(size_t job);
273
274 void SetJobLoadState(size_t job, LoadState load_state);
275
Matt Menke141b87f22019-01-30 02:43:03276 // Sets the HasConnectionEstablished value of the specified job to true,
277 // without invoking the callback.
278 void SetJobHasEstablishedConnection(size_t job);
279
[email protected]f6d1d6eb2009-06-24 20:16:09280 int allocation_count() const { return allocation_count_; }
281
[email protected]f6d1d6eb2009-06-24 20:16:09282 private:
283 int allocation_count_;
[email protected]5fc08e32009-07-15 17:09:57284 std::vector<TestConnectJob*> waiting_jobs_;
[email protected]f6d1d6eb2009-06-24 20:16:09285};
286
[email protected]ab838892009-06-30 18:49:05287class TestConnectJob : public ConnectJob {
288 public:
289 enum JobType {
290 kMockJob,
291 kMockFailingJob,
292 kMockPendingJob,
293 kMockPendingFailingJob,
[email protected]5fc08e32009-07-15 17:09:57294 kMockWaitingJob,
Matt Menkeb57663b32019-03-01 17:17:10295
296 // Certificate errors return a socket in addition to an error code.
297 kMockCertErrorJob,
298 kMockPendingCertErrorJob,
299
[email protected]e60e47a2010-07-14 03:37:18300 kMockAdditionalErrorStateJob,
301 kMockPendingAdditionalErrorStateJob,
[email protected]0dc88b32014-03-26 20:12:28302 kMockUnreadDataJob,
Matt Menkeb57663b32019-03-01 17:17:10303
304 kMockAuthChallengeOnceJob,
305 kMockAuthChallengeTwiceJob,
306 kMockAuthChallengeOnceFailingJob,
307 kMockAuthChallengeTwiceFailingJob,
[email protected]ab838892009-06-30 18:49:05308 };
309
[email protected]994d4932010-07-12 17:55:13310 // The kMockPendingJob uses a slight delay before allowing the connect
311 // to complete.
312 static const int kPendingConnectDelay = 2;
313
[email protected]ab838892009-06-30 18:49:05314 TestConnectJob(JobType job_type,
Matt Menke16f5c2e52019-03-25 21:50:40315 RequestPriority request_priority,
316 SocketTag socket_tag,
[email protected]974ebd62009-08-03 23:14:34317 base::TimeDelta timeout_duration,
Matt Menkea6f99ad2019-03-08 02:26:43318 const CommonConnectJobParams* common_connect_job_params,
[email protected]ab838892009-06-30 18:49:05319 ConnectJob::Delegate* delegate,
Matt Menkea6f99ad2019-03-08 02:26:43320 MockClientSocketFactory* client_socket_factory)
Matt Menke16f5c2e52019-03-25 21:50:40321 : ConnectJob(request_priority,
322 socket_tag,
Matt Menke1a6c92d2019-02-23 00:25:38323 timeout_duration,
Matt Menkea6f99ad2019-03-08 02:26:43324 common_connect_job_params,
Matt Menke1a6c92d2019-02-23 00:25:38325 delegate,
326 nullptr /* net_log */,
327 NetLogSourceType::TRANSPORT_CONNECT_JOB,
328 NetLogEventType::TRANSPORT_CONNECT_JOB_CONNECT),
[email protected]2ab05b52009-07-01 23:57:58329 job_type_(job_type),
[email protected]ab838892009-06-30 18:49:05330 client_socket_factory_(client_socket_factory),
[email protected]e60e47a2010-07-14 03:37:18331 load_state_(LOAD_STATE_IDLE),
Matt Menke141b87f22019-01-30 02:43:03332 has_established_connection_(false),
[email protected]d5492c52013-11-10 20:44:39333 store_additional_error_state_(false),
mmenked3641e12016-01-28 16:06:15334 weak_factory_(this) {}
[email protected]ab838892009-06-30 18:49:05335
[email protected]974ebd62009-08-03 23:14:34336 void Signal() {
[email protected]e772db3f2010-07-12 18:11:13337 DoConnect(waiting_success_, true /* async */, false /* recoverable */);
[email protected]974ebd62009-08-03 23:14:34338 }
339
[email protected]03b7c8c2013-07-20 04:38:55340 void set_load_state(LoadState load_state) { load_state_ = load_state; }
341
Matt Menke141b87f22019-01-30 02:43:03342 void set_has_established_connection() {
343 DCHECK(!has_established_connection_);
344 has_established_connection_ = true;
345 }
346
[email protected]03b7c8c2013-07-20 04:38:55347 // From ConnectJob:
348
dchengb03027d2014-10-21 12:00:20349 LoadState GetLoadState() const override { return load_state_; }
[email protected]46451352009-09-01 14:54:21350
Matt Menke141b87f22019-01-30 02:43:03351 bool HasEstablishedConnection() const override {
352 return has_established_connection_;
353 }
354
Matt Menke6f84d1f12019-04-11 19:26:47355 bool IsSSLError() const override { return store_additional_error_state_; }
356
357 scoped_refptr<SSLCertRequestInfo> GetCertRequestInfo() override {
358 if (store_additional_error_state_)
359 return base::MakeRefCounted<SSLCertRequestInfo>();
360 return nullptr;
[email protected]e60e47a2010-07-14 03:37:18361 }
362
[email protected]974ebd62009-08-03 23:14:34363 private:
[email protected]03b7c8c2013-07-20 04:38:55364 // From ConnectJob:
[email protected]ab838892009-06-30 18:49:05365
dchengb03027d2014-10-21 12:00:20366 int ConnectInternal() override {
[email protected]ab838892009-06-30 18:49:05367 AddressList ignored;
Raul Tambre94493c652019-03-11 17:18:35368 client_socket_factory_->CreateTransportClientSocket(
369 ignored, nullptr, nullptr, NetLogSource());
[email protected]ab838892009-06-30 18:49:05370 switch (job_type_) {
371 case kMockJob:
[email protected]e772db3f2010-07-12 18:11:13372 return DoConnect(true /* successful */, false /* sync */,
Matt Menkeb57663b32019-03-01 17:17:10373 false /* cert_error */);
[email protected]ab838892009-06-30 18:49:05374 case kMockFailingJob:
[email protected]e772db3f2010-07-12 18:11:13375 return DoConnect(false /* error */, false /* sync */,
Matt Menkeb57663b32019-03-01 17:17:10376 false /* cert_error */);
[email protected]ab838892009-06-30 18:49:05377 case kMockPendingJob:
[email protected]5fc08e32009-07-15 17:09:57378 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47379
380 // Depending on execution timings, posting a delayed task can result
381 // in the task getting executed the at the earliest possible
382 // opportunity or only after returning once from the message loop and
383 // then a second call into the message loop. In order to make behavior
384 // more deterministic, we change the default delay to 2ms. This should
385 // always require us to wait for the second call into the message loop.
386 //
387 // N.B. The correct fix for this and similar timing problems is to
388 // abstract time for the purpose of unittests. Unfortunately, we have
389 // a lot of third-party components that directly call the various
390 // time functions, so this change would be rather invasive.
skyostil4891b25b2015-06-11 11:43:45391 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05392 FROM_HERE,
kylecharf4fe5172019-02-15 18:53:49393 base::BindOnce(base::IgnoreResult(&TestConnectJob::DoConnect),
394 weak_factory_.GetWeakPtr(), true /* successful */,
Matt Menkeb57663b32019-03-01 17:17:10395 true /* async */, false /* cert_error */),
[email protected]5761ab9c2012-02-04 16:44:53396 base::TimeDelta::FromMilliseconds(kPendingConnectDelay));
[email protected]ab838892009-06-30 18:49:05397 return ERR_IO_PENDING;
398 case kMockPendingFailingJob:
[email protected]5fc08e32009-07-15 17:09:57399 set_load_state(LOAD_STATE_CONNECTING);
skyostil4891b25b2015-06-11 11:43:45400 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05401 FROM_HERE,
kylecharf4fe5172019-02-15 18:53:49402 base::BindOnce(base::IgnoreResult(&TestConnectJob::DoConnect),
403 weak_factory_.GetWeakPtr(), false /* error */,
Matt Menkeb57663b32019-03-01 17:17:10404 true /* async */, false /* cert_error */),
[email protected]5761ab9c2012-02-04 16:44:53405 base::TimeDelta::FromMilliseconds(2));
[email protected]ab838892009-06-30 18:49:05406 return ERR_IO_PENDING;
[email protected]5fc08e32009-07-15 17:09:57407 case kMockWaitingJob:
[email protected]03b7c8c2013-07-20 04:38:55408 set_load_state(LOAD_STATE_CONNECTING);
[email protected]5fc08e32009-07-15 17:09:57409 client_socket_factory_->WaitForSignal(this);
410 waiting_success_ = true;
411 return ERR_IO_PENDING;
Matt Menkeb57663b32019-03-01 17:17:10412 case kMockCertErrorJob:
[email protected]e772db3f2010-07-12 18:11:13413 return DoConnect(false /* error */, false /* sync */,
Matt Menkeb57663b32019-03-01 17:17:10414 true /* cert_error */);
415 case kMockPendingCertErrorJob:
[email protected]e772db3f2010-07-12 18:11:13416 set_load_state(LOAD_STATE_CONNECTING);
skyostil4891b25b2015-06-11 11:43:45417 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]e772db3f2010-07-12 18:11:13418 FROM_HERE,
kylecharf4fe5172019-02-15 18:53:49419 base::BindOnce(base::IgnoreResult(&TestConnectJob::DoConnect),
420 weak_factory_.GetWeakPtr(), false /* error */,
Matt Menkeb57663b32019-03-01 17:17:10421 true /* async */, true /* cert_error */),
[email protected]5761ab9c2012-02-04 16:44:53422 base::TimeDelta::FromMilliseconds(2));
[email protected]e772db3f2010-07-12 18:11:13423 return ERR_IO_PENDING;
[email protected]e60e47a2010-07-14 03:37:18424 case kMockAdditionalErrorStateJob:
425 store_additional_error_state_ = true;
426 return DoConnect(false /* error */, false /* sync */,
Matt Menkeb57663b32019-03-01 17:17:10427 false /* cert_error */);
[email protected]e60e47a2010-07-14 03:37:18428 case kMockPendingAdditionalErrorStateJob:
429 set_load_state(LOAD_STATE_CONNECTING);
430 store_additional_error_state_ = true;
skyostil4891b25b2015-06-11 11:43:45431 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]e60e47a2010-07-14 03:37:18432 FROM_HERE,
kylecharf4fe5172019-02-15 18:53:49433 base::BindOnce(base::IgnoreResult(&TestConnectJob::DoConnect),
434 weak_factory_.GetWeakPtr(), false /* error */,
Matt Menkeb57663b32019-03-01 17:17:10435 true /* async */, false /* cert_error */),
[email protected]5761ab9c2012-02-04 16:44:53436 base::TimeDelta::FromMilliseconds(2));
[email protected]e60e47a2010-07-14 03:37:18437 return ERR_IO_PENDING;
[email protected]0dc88b32014-03-26 20:12:28438 case kMockUnreadDataJob: {
439 int ret = DoConnect(true /* successful */, false /* sync */,
Matt Menkeb57663b32019-03-01 17:17:10440 false /* cert_error */);
[email protected]0dc88b32014-03-26 20:12:28441 static_cast<MockClientSocket*>(socket())->set_has_unread_data(true);
442 return ret;
443 }
Matt Menkeb57663b32019-03-01 17:17:10444 case kMockAuthChallengeOnceJob:
Matt Menke4b69f932019-03-04 16:20:01445 set_load_state(LOAD_STATE_CONNECTING);
Matt Menkeb57663b32019-03-01 17:17:10446 DoAdvanceAuthChallenge(1, true /* succeed_after_last_challenge */);
447 return ERR_IO_PENDING;
448 case kMockAuthChallengeTwiceJob:
Matt Menke4b69f932019-03-04 16:20:01449 set_load_state(LOAD_STATE_CONNECTING);
Matt Menkeb57663b32019-03-01 17:17:10450 DoAdvanceAuthChallenge(2, true /* succeed_after_last_challenge */);
451 return ERR_IO_PENDING;
452 case kMockAuthChallengeOnceFailingJob:
Matt Menke4b69f932019-03-04 16:20:01453 set_load_state(LOAD_STATE_CONNECTING);
Matt Menkeb57663b32019-03-01 17:17:10454 DoAdvanceAuthChallenge(1, false /* succeed_after_last_challenge */);
455 return ERR_IO_PENDING;
456 case kMockAuthChallengeTwiceFailingJob:
Matt Menke4b69f932019-03-04 16:20:01457 set_load_state(LOAD_STATE_CONNECTING);
Matt Menkeb57663b32019-03-01 17:17:10458 DoAdvanceAuthChallenge(2, false /* succeed_after_last_challenge */);
459 return ERR_IO_PENDING;
[email protected]ab838892009-06-30 18:49:05460 default:
461 NOTREACHED();
danakj655b66c2016-04-16 00:51:38462 SetSocket(std::unique_ptr<StreamSocket>());
[email protected]ab838892009-06-30 18:49:05463 return ERR_FAILED;
464 }
465 }
466
Lily Chen02ef29a2018-11-30 16:31:43467 void ChangePriorityInternal(RequestPriority priority) override {}
468
Matt Menkeb57663b32019-03-01 17:17:10469 int DoConnect(bool succeed, bool was_async, bool cert_error) {
[email protected]e772db3f2010-07-12 18:11:13470 int result = OK;
Matt Menke141b87f22019-01-30 02:43:03471 has_established_connection_ = true;
[email protected]ab838892009-06-30 18:49:05472 if (succeed) {
Matt Menkeb57663b32019-03-01 17:17:10473 SetSocket(std::make_unique<MockClientSocket>(net_log().net_log()));
Bence Békybdbb0e72018-08-07 21:42:59474 socket()->Connect(CompletionOnceCallback());
Matt Menkeb57663b32019-03-01 17:17:10475 } else if (cert_error) {
476 SetSocket(std::make_unique<MockClientSocket>(net_log().net_log()));
477 result = ERR_CERT_COMMON_NAME_INVALID;
[email protected]6e713f02009-08-06 02:56:40478 } else {
[email protected]e772db3f2010-07-12 18:11:13479 result = ERR_CONNECTION_FAILED;
danakj655b66c2016-04-16 00:51:38480 SetSocket(std::unique_ptr<StreamSocket>());
[email protected]ab838892009-06-30 18:49:05481 }
[email protected]2ab05b52009-07-01 23:57:58482
483 if (was_async)
[email protected]fd7b7c92009-08-20 19:38:30484 NotifyDelegateOfCompletion(result);
[email protected]ab838892009-06-30 18:49:05485 return result;
486 }
487
Matt Menkeb57663b32019-03-01 17:17:10488 void DoAdvanceAuthChallenge(int remaining_challenges,
489 bool succeed_after_last_challenge) {
490 base::ThreadTaskRunnerHandle::Get()->PostTask(
491 FROM_HERE,
492 base::BindOnce(&TestConnectJob::InvokeNextProxyAuthCallback,
493 weak_factory_.GetWeakPtr(), remaining_challenges,
494 succeed_after_last_challenge));
495 }
496
497 void InvokeNextProxyAuthCallback(int remaining_challenges,
498 bool succeed_after_last_challenge) {
Matt Menke4b69f932019-03-04 16:20:01499 set_load_state(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL);
Matt Menkeb57663b32019-03-01 17:17:10500 if (remaining_challenges == 0) {
501 DoConnect(succeed_after_last_challenge, true /* was_async */,
502 false /* cert_error */);
503 return;
504 }
505
506 // Integration tests make sure HttpResponseInfo and HttpAuthController work.
507 // The auth tests here are just focused on ConnectJob bookkeeping.
508 HttpResponseInfo info;
509 NotifyDelegateOfProxyAuth(
510 info, nullptr /* http_auth_controller */,
511 base::BindOnce(&TestConnectJob::DoAdvanceAuthChallenge,
512 weak_factory_.GetWeakPtr(), remaining_challenges - 1,
513 succeed_after_last_challenge));
514 }
515
[email protected]5fc08e32009-07-15 17:09:57516 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05517 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57518 MockClientSocketFactory* const client_socket_factory_;
[email protected]46451352009-09-01 14:54:21519 LoadState load_state_;
Matt Menke141b87f22019-01-30 02:43:03520 bool has_established_connection_;
[email protected]e60e47a2010-07-14 03:37:18521 bool store_additional_error_state_;
[email protected]ab838892009-06-30 18:49:05522
[email protected]d5492c52013-11-10 20:44:39523 base::WeakPtrFactory<TestConnectJob> weak_factory_;
524
[email protected]ab838892009-06-30 18:49:05525 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
526};
527
[email protected]d80a4322009-08-14 07:07:49528class TestConnectJobFactory
Matt Menke16f5c2e52019-03-25 21:50:40529 : public TransportClientSocketPool::ConnectJobFactory {
[email protected]ab838892009-06-30 18:49:05530 public:
[email protected]034df0f32013-01-07 23:17:48531 TestConnectJobFactory(MockClientSocketFactory* client_socket_factory,
532 NetLog* net_log)
Matt Menkea6f99ad2019-03-08 02:26:43533 : common_connect_job_params_(
534 nullptr /* client_socket_factory */,
535 nullptr /* host_resolver */,
Matt Menkeb88837e2019-03-20 11:50:40536 nullptr /* http_auth_cache */,
537 nullptr /* http_auth_handler_factory */,
538 nullptr /* spdy_session_pool */,
Matt Menkeb5fb42b2019-03-22 17:26:13539 nullptr /* quic_supported_versions */,
Matt Menkeb88837e2019-03-20 11:50:40540 nullptr /* quic_stream_factory */,
Matt Menkea6f99ad2019-03-08 02:26:43541 nullptr /* proxy_delegate */,
Matt Menked732ea42019-03-08 12:05:00542 nullptr /* http_user_agent_settings */,
Matt Menkea6f99ad2019-03-08 02:26:43543 SSLClientSocketContext(),
544 SSLClientSocketContext(),
545 nullptr /* socket_performance_watcher_factory */,
546 nullptr /* network_quality_estimator */,
547 net_log,
548 nullptr /* websocket_endpoint_lock_manager */),
549 job_type_(TestConnectJob::kMockJob),
Raul Tambre94493c652019-03-11 17:18:35550 job_types_(nullptr),
Matt Menkea6f99ad2019-03-08 02:26:43551 client_socket_factory_(client_socket_factory) {}
[email protected]ab838892009-06-30 18:49:05552
Chris Watkins7a41d3552017-12-01 02:13:27553 ~TestConnectJobFactory() override = default;
[email protected]ab838892009-06-30 18:49:05554
555 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
556
[email protected]51fdc7c2012-04-10 19:19:48557 void set_job_types(std::list<TestConnectJob::JobType>* job_types) {
558 job_types_ = job_types;
559 CHECK(!job_types_->empty());
560 }
561
[email protected]974ebd62009-08-03 23:14:34562 void set_timeout_duration(base::TimeDelta timeout_duration) {
563 timeout_duration_ = timeout_duration;
564 }
565
[email protected]3f55aa12011-12-07 02:03:33566 // ConnectJobFactory implementation.
[email protected]83039bb2011-12-09 18:43:55567
danakj655b66c2016-04-16 00:51:38568 std::unique_ptr<ConnectJob> NewConnectJob(
Matt Menkeaafff542019-04-22 22:09:36569 ClientSocketPool::GroupId group_id,
570 scoped_refptr<ClientSocketPool::SocketParams> socket_params,
Matt Menkef09e64c2019-04-23 22:16:28571 const base::Optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
Matt Menke16f5c2e52019-03-25 21:50:40572 RequestPriority request_priority,
573 SocketTag socket_tag,
mostynbba063d6032014-10-09 11:01:13574 ConnectJob::Delegate* delegate) const override {
[email protected]51fdc7c2012-04-10 19:19:48575 EXPECT_TRUE(!job_types_ || !job_types_->empty());
576 TestConnectJob::JobType job_type = job_type_;
577 if (job_types_ && !job_types_->empty()) {
578 job_type = job_types_->front();
579 job_types_->pop_front();
580 }
Matt Menkea6f99ad2019-03-08 02:26:43581 return std::make_unique<TestConnectJob>(
Matt Menke16f5c2e52019-03-25 21:50:40582 job_type, request_priority, socket_tag, timeout_duration_,
583 &common_connect_job_params_, delegate, client_socket_factory_);
[email protected]ab838892009-06-30 18:49:05584 }
585
586 private:
Matt Menkea6f99ad2019-03-08 02:26:43587 const CommonConnectJobParams common_connect_job_params_;
[email protected]ab838892009-06-30 18:49:05588 TestConnectJob::JobType job_type_;
[email protected]51fdc7c2012-04-10 19:19:48589 std::list<TestConnectJob::JobType>* job_types_;
[email protected]974ebd62009-08-03 23:14:34590 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57591 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05592
593 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
594};
595
[email protected]a937a06d2009-08-19 21:19:24596} // namespace
597
[email protected]a937a06d2009-08-19 21:19:24598namespace {
599
[email protected]5fc08e32009-07-15 17:09:57600void MockClientSocketFactory::SignalJobs() {
jdoerrie22a91d8b92018-10-05 08:43:26601 for (auto it = waiting_jobs_.begin(); it != waiting_jobs_.end(); ++it) {
[email protected]5fc08e32009-07-15 17:09:57602 (*it)->Signal();
603 }
604 waiting_jobs_.clear();
605}
606
[email protected]03b7c8c2013-07-20 04:38:55607void MockClientSocketFactory::SignalJob(size_t job) {
608 ASSERT_LT(job, waiting_jobs_.size());
609 waiting_jobs_[job]->Signal();
610 waiting_jobs_.erase(waiting_jobs_.begin() + job);
611}
612
613void MockClientSocketFactory::SetJobLoadState(size_t job,
614 LoadState load_state) {
615 ASSERT_LT(job, waiting_jobs_.size());
616 waiting_jobs_[job]->set_load_state(load_state);
617}
618
Matt Menke141b87f22019-01-30 02:43:03619void MockClientSocketFactory::SetJobHasEstablishedConnection(size_t job) {
620 ASSERT_LT(job, waiting_jobs_.size());
621 waiting_jobs_[job]->set_has_established_connection();
622}
623
Bence Béky98447b12018-05-08 03:14:01624class ClientSocketPoolBaseTest : public TestWithScopedTaskEnvironment {
[email protected]f6d1d6eb2009-06-24 20:16:09625 protected:
Alex Clarke0def2092018-12-10 12:01:45626 ClientSocketPoolBaseTest()
627 : TestWithScopedTaskEnvironment(
628 base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME),
Matt Menke870e19ab2019-04-23 16:23:03629 params_(ClientSocketPool::SocketParams::CreateForHttpForTesting()) {
[email protected]636b8252011-04-08 19:56:54630 connect_backup_jobs_enabled_ =
Matt Menke16f5c2e52019-03-25 21:50:40631 TransportClientSocketPool::connect_backup_jobs_enabled();
632 TransportClientSocketPool::set_connect_backup_jobs_enabled(true);
[email protected]636b8252011-04-08 19:56:54633 }
[email protected]2431756e2010-09-29 20:26:13634
dcheng67be2b1f2014-10-27 21:47:29635 ~ClientSocketPoolBaseTest() override {
Matt Menke16f5c2e52019-03-25 21:50:40636 TransportClientSocketPool::set_connect_backup_jobs_enabled(
[email protected]636b8252011-04-08 19:56:54637 connect_backup_jobs_enabled_);
638 }
[email protected]c9d6a1d2009-07-14 16:15:20639
Matt Menke9fa17d52019-03-25 19:12:26640 void CreatePool(int max_sockets,
641 int max_sockets_per_group,
642 bool enable_backup_connect_jobs = false) {
Tarun Bansala7635092019-02-20 10:00:59643 CreatePoolWithIdleTimeouts(max_sockets, max_sockets_per_group,
644 kUnusedIdleSocketTimeout,
Matt Menke9fa17d52019-03-25 19:12:26645 ClientSocketPool::used_idle_socket_timeout(),
646 enable_backup_connect_jobs);
[email protected]9bf28db2009-08-29 01:35:16647 }
648
Matt Menke9fa17d52019-03-25 19:12:26649 void CreatePoolWithIdleTimeouts(int max_sockets,
650 int max_sockets_per_group,
651 base::TimeDelta unused_idle_socket_timeout,
652 base::TimeDelta used_idle_socket_timeout,
653 bool enable_backup_connect_jobs = false) {
[email protected]c9d6a1d2009-07-14 16:15:20654 DCHECK(!pool_.get());
Matt Menke9fa17d52019-03-25 19:12:26655 std::unique_ptr<TestConnectJobFactory> connect_job_factory =
656 std::make_unique<TestConnectJobFactory>(&client_socket_factory_,
657 &net_log_);
658 connect_job_factory_ = connect_job_factory.get();
659 pool_ = TransportClientSocketPool::CreateForTesting(
660 max_sockets, max_sockets_per_group, unused_idle_socket_timeout,
661 used_idle_socket_timeout, std::move(connect_job_factory),
662 nullptr /* ssl_config_service */, enable_backup_connect_jobs);
[email protected]c9d6a1d2009-07-14 16:15:20663 }
[email protected]f6d1d6eb2009-06-24 20:16:09664
mmenked3641e12016-01-28 16:06:15665 int StartRequestWithIgnoreLimits(
Matt Menkec6b3edf72019-03-19 17:00:39666 const ClientSocketPool::GroupId& group_id,
[email protected]b021ece62013-06-11 11:06:33667 RequestPriority priority,
mmenked3641e12016-01-28 16:06:15668 ClientSocketPool::RespectLimits respect_limits) {
Matt Menkec6b3edf72019-03-19 17:00:39669 return test_base_.StartRequestUsingPool(pool_.get(), group_id, priority,
mmenked3641e12016-01-28 16:06:15670 respect_limits, params_);
[email protected]b021ece62013-06-11 11:06:33671 }
672
Matt Menkec6b3edf72019-03-19 17:00:39673 int StartRequest(const ClientSocketPool::GroupId& group_id,
674 RequestPriority priority) {
mmenked3641e12016-01-28 16:06:15675 return StartRequestWithIgnoreLimits(
Matt Menkec6b3edf72019-03-19 17:00:39676 group_id, priority, ClientSocketPool::RespectLimits::ENABLED);
[email protected]f6d1d6eb2009-06-24 20:16:09677 }
678
[email protected]2431756e2010-09-29 20:26:13679 int GetOrderOfRequest(size_t index) const {
680 return test_base_.GetOrderOfRequest(index);
[email protected]f6d1d6eb2009-06-24 20:16:09681 }
682
[email protected]2431756e2010-09-29 20:26:13683 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
684 return test_base_.ReleaseOneConnection(keep_alive);
685 }
686
687 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
688 test_base_.ReleaseAllConnections(keep_alive);
689 }
690
691 TestSocketRequest* request(int i) { return test_base_.request(i); }
692 size_t requests_size() const { return test_base_.requests_size(); }
danakj655b66c2016-04-16 00:51:38693 std::vector<std::unique_ptr<TestSocketRequest>>* requests() {
olli.raula9d66b7d2015-11-23 08:30:42694 return test_base_.requests();
695 }
rdsmith29dbad12017-02-17 02:22:18696 // Only counts the requests that get sockets asynchronously;
697 // synchronous completions are not registered by this count.
[email protected]2431756e2010-09-29 20:26:13698 size_t completion_count() const { return test_base_.completion_count(); }
699
vishal.b62985ca92015-04-17 08:45:51700 TestNetLog net_log_;
[email protected]636b8252011-04-08 19:56:54701 bool connect_backup_jobs_enabled_;
[email protected]f6d1d6eb2009-06-24 20:16:09702 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04703 TestConnectJobFactory* connect_job_factory_;
Matt Menke9fa17d52019-03-25 19:12:26704 // These parameters are never actually used to create a TransportConnectJob.
Matt Menke84d11e562019-03-27 00:11:19705 scoped_refptr<ClientSocketPool::SocketParams> params_;
Matt Menke9fa17d52019-03-25 19:12:26706 std::unique_ptr<TransportClientSocketPool> pool_;
[email protected]2431756e2010-09-29 20:26:13707 ClientSocketPoolTest test_base_;
[email protected]f6d1d6eb2009-06-24 20:16:09708};
709
[email protected]5fc08e32009-07-15 17:09:57710TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53711 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20712
[email protected]6ecf2b92011-12-15 01:14:52713 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06714 ClientSocketHandle handle;
vishal.b62985ca92015-04-17 08:45:51715 BoundTestNetLog log;
[email protected]034df0f32013-01-07 23:17:48716 TestLoadTimingInfoNotConnected(handle);
[email protected]9e743cd2010-03-16 07:03:53717
Matt Menkef09e64c2019-04-23 22:16:28718 EXPECT_EQ(OK, handle.Init(
719 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
720 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
721 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
722 pool_.get(), log.bound()));
[email protected]f6d1d6eb2009-06-24 20:16:09723 EXPECT_TRUE(handle.is_initialized());
724 EXPECT_TRUE(handle.socket());
[email protected]034df0f32013-01-07 23:17:48725 TestLoadTimingInfoConnectedNotReused(handle);
726
[email protected]f6d1d6eb2009-06-24 20:16:09727 handle.Reset();
[email protected]034df0f32013-01-07 23:17:48728 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:30729
mmenke43758e62015-05-04 21:09:46730 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40731 log.GetEntries(&entries);
732
Matt Menke9fa17d52019-03-25 19:12:26733 EXPECT_EQ(5u, entries.size());
[email protected]9e743cd2010-03-16 07:03:53734 EXPECT_TRUE(LogContainsEvent(
Matt Menke9fa17d52019-03-25 19:12:26735 entries, 0, NetLogEventType::TCP_CLIENT_SOCKET_POOL_REQUESTED_SOCKET,
mikecirone8b85c432016-09-08 19:11:00736 NetLogEventPhase::NONE));
Matt Menke9fa17d52019-03-25 19:12:26737 EXPECT_TRUE(LogContainsBeginEvent(entries, 1, NetLogEventType::SOCKET_POOL));
738 EXPECT_TRUE(LogContainsEvent(
739 entries, 2, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
740 NetLogEventPhase::NONE));
741 EXPECT_TRUE(LogContainsEvent(entries, 3,
mikecirone8b85c432016-09-08 19:11:00742 NetLogEventType::SOCKET_POOL_BOUND_TO_SOCKET,
743 NetLogEventPhase::NONE));
Matt Menke9fa17d52019-03-25 19:12:26744 EXPECT_TRUE(LogContainsEndEvent(entries, 4, NetLogEventType::SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09745}
746
[email protected]ab838892009-06-30 18:49:05747TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53748 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20749
[email protected]ab838892009-06-30 18:49:05750 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
vishal.b62985ca92015-04-17 08:45:51751 BoundTestNetLog log;
[email protected]9e743cd2010-03-16 07:03:53752
[email protected]2431756e2010-09-29 20:26:13753 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:52754 TestCompletionCallback callback;
[email protected]e60e47a2010-07-14 03:37:18755 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:13756 handle.set_is_ssl_error(true);
Matt Menke39b7c5a2019-04-10 19:47:51757 handle.set_ssl_cert_request_info(base::MakeRefCounted<SSLCertRequestInfo>());
Matt Menke28ac03e2019-02-25 22:25:50758 EXPECT_EQ(
759 ERR_CONNECTION_FAILED,
Matt Menkef09e64c2019-04-23 22:16:28760 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
761 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
762 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
763 pool_.get(), log.bound()));
[email protected]2431756e2010-09-29 20:26:13764 EXPECT_FALSE(handle.socket());
765 EXPECT_FALSE(handle.is_ssl_error());
Matt Menke39b7c5a2019-04-10 19:47:51766 EXPECT_FALSE(handle.ssl_cert_request_info());
[email protected]034df0f32013-01-07 23:17:48767 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:30768
mmenke43758e62015-05-04 21:09:46769 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40770 log.GetEntries(&entries);
771
Matt Menke9fa17d52019-03-25 19:12:26772 EXPECT_EQ(4u, entries.size());
[email protected]06650c52010-06-03 00:49:17773 EXPECT_TRUE(LogContainsEvent(
Matt Menke9fa17d52019-03-25 19:12:26774 entries, 0, NetLogEventType::TCP_CLIENT_SOCKET_POOL_REQUESTED_SOCKET,
mikecirone8b85c432016-09-08 19:11:00775 NetLogEventPhase::NONE));
Matt Menke9fa17d52019-03-25 19:12:26776 EXPECT_TRUE(LogContainsBeginEvent(entries, 1, NetLogEventType::SOCKET_POOL));
777 EXPECT_TRUE(LogContainsEvent(
778 entries, 2, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
779 NetLogEventPhase::NONE));
780 EXPECT_TRUE(LogContainsEndEvent(entries, 3, NetLogEventType::SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09781}
782
Matt Menkef6edce752019-03-19 17:21:56783// Make sure different groups do not share sockets.
784TEST_F(ClientSocketPoolBaseTest, GroupSeparation) {
785 CreatePool(1000 /* max_sockets */, 2 /* max_sockets_per_group */);
786
787 const HostPortPair kHostPortPairs[] = {
788 {"a", 80},
789 {"a", 443},
790 {"b", 80},
791 };
792
793 const ClientSocketPool::SocketType kSocketTypes[] = {
794 ClientSocketPool::SocketType::kHttp,
795 ClientSocketPool::SocketType::kSsl,
Matt Menkef6edce752019-03-19 17:21:56796 ClientSocketPool::SocketType::kFtp,
797 };
798
Matt Menkebdf777802019-04-22 19:38:59799 const PrivacyMode kPrivacyModes[] = {PrivacyMode::PRIVACY_MODE_DISABLED,
800 PrivacyMode::PRIVACY_MODE_ENABLED};
Matt Menkef6edce752019-03-19 17:21:56801
802 int total_idle_sockets = 0;
803
804 // Walk through each GroupId, making sure that requesting a socket for one
805 // group does not return a previously connected socket for another group.
806 for (const auto& host_port_pair : kHostPortPairs) {
807 SCOPED_TRACE(host_port_pair.ToString());
808 for (const auto& socket_type : kSocketTypes) {
809 SCOPED_TRACE(static_cast<int>(socket_type));
810 for (const auto& privacy_mode : kPrivacyModes) {
811 SCOPED_TRACE(privacy_mode);
812
813 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
814
815 ClientSocketPool::GroupId group_id(host_port_pair, socket_type,
816 privacy_mode);
817
Matt Menke9fa17d52019-03-25 19:12:26818 EXPECT_FALSE(pool_->HasGroupForTesting(group_id));
Matt Menkef6edce752019-03-19 17:21:56819
820 TestCompletionCallback callback;
821 ClientSocketHandle handle;
822
823 // Since the group is empty, requesting a socket should not complete
824 // synchronously.
825 EXPECT_THAT(
Matt Menkef09e64c2019-04-23 22:16:28826 handle.Init(group_id, params_, base::nullopt, DEFAULT_PRIORITY,
827 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menkef6edce752019-03-19 17:21:56828 callback.callback(),
829 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
830 NetLogWithSource()),
831 IsError(ERR_IO_PENDING));
Matt Menke9fa17d52019-03-25 19:12:26832 EXPECT_TRUE(pool_->HasGroupForTesting(group_id));
Matt Menkef6edce752019-03-19 17:21:56833 EXPECT_EQ(total_idle_sockets, pool_->IdleSocketCount());
834
835 EXPECT_THAT(callback.WaitForResult(), IsOk());
836 EXPECT_TRUE(handle.socket());
Matt Menke9fa17d52019-03-25 19:12:26837 EXPECT_TRUE(pool_->HasGroupForTesting(group_id));
Matt Menkef6edce752019-03-19 17:21:56838 EXPECT_EQ(total_idle_sockets, pool_->IdleSocketCount());
839
840 // Return socket to pool.
841 handle.Reset();
842 EXPECT_EQ(total_idle_sockets + 1, pool_->IdleSocketCount());
843
844 // Requesting a socket again should return the same socket as before, so
845 // should complete synchronously.
846 EXPECT_THAT(
Matt Menkef09e64c2019-04-23 22:16:28847 handle.Init(group_id, params_, base::nullopt, DEFAULT_PRIORITY,
848 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menkef6edce752019-03-19 17:21:56849 callback.callback(),
850 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
851 NetLogWithSource()),
852 IsOk());
853 EXPECT_TRUE(handle.socket());
854 EXPECT_EQ(total_idle_sockets, pool_->IdleSocketCount());
855
856 // Return socket to pool again.
857 handle.Reset();
858 EXPECT_EQ(total_idle_sockets + 1, pool_->IdleSocketCount());
859
860 ++total_idle_sockets;
861 }
862 }
863 }
864}
865
[email protected]211d21722009-07-22 15:48:53866TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
867 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
868
[email protected]9e743cd2010-03-16 07:03:53869 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30870
Matt Menkec6b3edf72019-03-19 17:00:39871 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
872 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
873 EXPECT_THAT(StartRequest(TestGroupId("c"), DEFAULT_PRIORITY), IsOk());
874 EXPECT_THAT(StartRequest(TestGroupId("d"), DEFAULT_PRIORITY), IsOk());
[email protected]211d21722009-07-22 15:48:53875
[email protected]2431756e2010-09-29 20:26:13876 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53877 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13878 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53879
Matt Menkec6b3edf72019-03-19 17:00:39880 EXPECT_THAT(StartRequest(TestGroupId("e"), DEFAULT_PRIORITY),
881 IsError(ERR_IO_PENDING));
882 EXPECT_THAT(StartRequest(TestGroupId("f"), DEFAULT_PRIORITY),
883 IsError(ERR_IO_PENDING));
884 EXPECT_THAT(StartRequest(TestGroupId("g"), DEFAULT_PRIORITY),
885 IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:53886
[email protected]2431756e2010-09-29 20:26:13887 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53888
[email protected]2431756e2010-09-29 20:26:13889 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53890 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13891 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53892
893 EXPECT_EQ(1, GetOrderOfRequest(1));
894 EXPECT_EQ(2, GetOrderOfRequest(2));
895 EXPECT_EQ(3, GetOrderOfRequest(3));
896 EXPECT_EQ(4, GetOrderOfRequest(4));
897 EXPECT_EQ(5, GetOrderOfRequest(5));
898 EXPECT_EQ(6, GetOrderOfRequest(6));
899 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17900
901 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13902 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53903}
904
905TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
906 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
907
[email protected]9e743cd2010-03-16 07:03:53908 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30909
[email protected]211d21722009-07-22 15:48:53910 // Reach all limits: max total sockets, and max sockets per group.
Matt Menkec6b3edf72019-03-19 17:00:39911 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
912 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
913 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
914 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
[email protected]211d21722009-07-22 15:48:53915
[email protected]2431756e2010-09-29 20:26:13916 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53917 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13918 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53919
920 // Now create a new group and verify that we don't starve it.
Matt Menkec6b3edf72019-03-19 17:00:39921 EXPECT_THAT(StartRequest(TestGroupId("c"), DEFAULT_PRIORITY),
922 IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:53923
[email protected]2431756e2010-09-29 20:26:13924 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53925
[email protected]2431756e2010-09-29 20:26:13926 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53927 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13928 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53929
930 EXPECT_EQ(1, GetOrderOfRequest(1));
931 EXPECT_EQ(2, GetOrderOfRequest(2));
932 EXPECT_EQ(3, GetOrderOfRequest(3));
933 EXPECT_EQ(4, GetOrderOfRequest(4));
934 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17935
936 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13937 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53938}
939
940TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
941 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
942
Matt Menkec6b3edf72019-03-19 17:00:39943 EXPECT_THAT(StartRequest(TestGroupId("b"), LOWEST), IsOk());
944 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsOk());
945 EXPECT_THAT(StartRequest(TestGroupId("b"), HIGHEST), IsOk());
946 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsOk());
[email protected]211d21722009-07-22 15:48:53947
[email protected]2431756e2010-09-29 20:26:13948 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53949 client_socket_factory_.allocation_count());
950
Matt Menkec6b3edf72019-03-19 17:00:39951 EXPECT_THAT(StartRequest(TestGroupId("c"), LOWEST), IsError(ERR_IO_PENDING));
952 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
953 EXPECT_THAT(StartRequest(TestGroupId("b"), HIGHEST), IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:53954
[email protected]2431756e2010-09-29 20:26:13955 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53956
[email protected]2431756e2010-09-29 20:26:13957 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53958
959 // First 4 requests don't have to wait, and finish in order.
960 EXPECT_EQ(1, GetOrderOfRequest(1));
961 EXPECT_EQ(2, GetOrderOfRequest(2));
962 EXPECT_EQ(3, GetOrderOfRequest(3));
963 EXPECT_EQ(4, GetOrderOfRequest(4));
964
Matt Menkec6b3edf72019-03-19 17:00:39965 // Request ("b", HIGHEST) has the highest priority, then (TestGroupId("a"),
966 // MEDIUM), and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:53967 EXPECT_EQ(7, GetOrderOfRequest(5));
968 EXPECT_EQ(6, GetOrderOfRequest(6));
969 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17970
971 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13972 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]211d21722009-07-22 15:48:53973}
974
rdsmith29dbad12017-02-17 02:22:18975// Test reprioritizing a request before completion doesn't interfere with
976// its completion.
977TEST_F(ClientSocketPoolBaseTest, ReprioritizeOne) {
978 CreatePool(kDefaultMaxSockets, 1);
979
Matt Menkec6b3edf72019-03-19 17:00:39980 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(OK));
981 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
rdsmith29dbad12017-02-17 02:22:18982 EXPECT_TRUE(request(0)->handle()->socket());
983 EXPECT_FALSE(request(1)->handle()->socket());
984
Lily Chenecebf932018-11-02 17:15:43985 request(1)->handle()->SetPriority(HIGHEST);
rdsmith29dbad12017-02-17 02:22:18986
987 ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE);
988
989 EXPECT_TRUE(request(1)->handle()->socket());
990}
991
992// Reprioritize a request up past another one and make sure that changes the
993// completion order.
994TEST_F(ClientSocketPoolBaseTest, ReprioritizeUpReorder) {
995 CreatePool(kDefaultMaxSockets, 1);
996
Matt Menkec6b3edf72019-03-19 17:00:39997 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(OK));
998 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
999 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
rdsmith29dbad12017-02-17 02:22:181000 EXPECT_TRUE(request(0)->handle()->socket());
1001 EXPECT_FALSE(request(1)->handle()->socket());
1002 EXPECT_FALSE(request(2)->handle()->socket());
1003
1004 request(2)->handle()->SetPriority(HIGHEST);
1005
1006 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1007
1008 EXPECT_EQ(1, GetOrderOfRequest(1));
1009 EXPECT_EQ(3, GetOrderOfRequest(2));
1010 EXPECT_EQ(2, GetOrderOfRequest(3));
1011}
1012
1013// Reprioritize a request without changing relative priorities and check
1014// that the order doesn't change.
1015TEST_F(ClientSocketPoolBaseTest, ReprioritizeUpNoReorder) {
1016 CreatePool(kDefaultMaxSockets, 1);
1017
Matt Menkec6b3edf72019-03-19 17:00:391018 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(OK));
1019 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1020 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsError(ERR_IO_PENDING));
rdsmith29dbad12017-02-17 02:22:181021 EXPECT_TRUE(request(0)->handle()->socket());
1022 EXPECT_FALSE(request(1)->handle()->socket());
1023 EXPECT_FALSE(request(2)->handle()->socket());
1024
1025 request(2)->handle()->SetPriority(MEDIUM);
1026
1027 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1028
1029 EXPECT_EQ(1, GetOrderOfRequest(1));
1030 EXPECT_EQ(2, GetOrderOfRequest(2));
1031 EXPECT_EQ(3, GetOrderOfRequest(3));
1032}
1033
1034// Reprioritize a request past down another one and make sure that changes the
1035// completion order.
1036TEST_F(ClientSocketPoolBaseTest, ReprioritizeDownReorder) {
1037 CreatePool(kDefaultMaxSockets, 1);
1038
Matt Menkec6b3edf72019-03-19 17:00:391039 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(OK));
1040 EXPECT_THAT(StartRequest(TestGroupId("a"), HIGHEST), IsError(ERR_IO_PENDING));
1041 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
rdsmith29dbad12017-02-17 02:22:181042 EXPECT_TRUE(request(0)->handle()->socket());
1043 EXPECT_FALSE(request(1)->handle()->socket());
1044 EXPECT_FALSE(request(2)->handle()->socket());
1045
1046 request(1)->handle()->SetPriority(LOW);
1047
1048 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1049
1050 EXPECT_EQ(1, GetOrderOfRequest(1));
1051 EXPECT_EQ(3, GetOrderOfRequest(2));
1052 EXPECT_EQ(2, GetOrderOfRequest(3));
1053}
1054
1055// Reprioritize a request to the same level as another and confirm it is
1056// put after the old request.
1057TEST_F(ClientSocketPoolBaseTest, ReprioritizeResetFIFO) {
1058 CreatePool(kDefaultMaxSockets, 1);
1059
Matt Menkec6b3edf72019-03-19 17:00:391060 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(OK));
1061 EXPECT_THAT(StartRequest(TestGroupId("a"), HIGHEST), IsError(ERR_IO_PENDING));
1062 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
rdsmith29dbad12017-02-17 02:22:181063 EXPECT_TRUE(request(0)->handle()->socket());
1064 EXPECT_FALSE(request(1)->handle()->socket());
1065 EXPECT_FALSE(request(2)->handle()->socket());
1066
1067 request(1)->handle()->SetPriority(MEDIUM);
1068
1069 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1070
1071 EXPECT_EQ(1, GetOrderOfRequest(1));
1072 EXPECT_EQ(3, GetOrderOfRequest(2));
1073 EXPECT_EQ(2, GetOrderOfRequest(3));
1074}
1075
[email protected]211d21722009-07-22 15:48:531076TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
1077 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1078
Matt Menkec6b3edf72019-03-19 17:00:391079 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsOk());
1080 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsOk());
1081 EXPECT_THAT(StartRequest(TestGroupId("b"), HIGHEST), IsOk());
1082 EXPECT_THAT(StartRequest(TestGroupId("b"), MEDIUM), IsOk());
[email protected]211d21722009-07-22 15:48:531083
[email protected]2431756e2010-09-29 20:26:131084 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531085 client_socket_factory_.allocation_count());
1086
Matt Menkec6b3edf72019-03-19 17:00:391087 EXPECT_THAT(StartRequest(TestGroupId("c"), MEDIUM), IsError(ERR_IO_PENDING));
1088 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsError(ERR_IO_PENDING));
1089 EXPECT_THAT(StartRequest(TestGroupId("b"), HIGHEST), IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:531090
[email protected]2431756e2010-09-29 20:26:131091 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:531092
[email protected]2431756e2010-09-29 20:26:131093 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531094 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131095 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:531096
1097 // First 4 requests don't have to wait, and finish in order.
1098 EXPECT_EQ(1, GetOrderOfRequest(1));
1099 EXPECT_EQ(2, GetOrderOfRequest(2));
1100 EXPECT_EQ(3, GetOrderOfRequest(3));
1101 EXPECT_EQ(4, GetOrderOfRequest(4));
1102
1103 // Request ("b", 7) has the highest priority, but we can't make new socket for
1104 // group "b", because it has reached the per-group limit. Then we make
1105 // socket for ("c", 6), because it has higher priority than ("a", 4),
1106 // and we still can't make a socket for group "b".
1107 EXPECT_EQ(5, GetOrderOfRequest(5));
1108 EXPECT_EQ(6, GetOrderOfRequest(6));
1109 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171110
1111 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131112 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:531113}
1114
1115// Make sure that we count connecting sockets against the total limit.
1116TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
1117 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1118
Matt Menkec6b3edf72019-03-19 17:00:391119 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1120 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
1121 EXPECT_THAT(StartRequest(TestGroupId("c"), DEFAULT_PRIORITY), IsOk());
[email protected]211d21722009-07-22 15:48:531122
1123 // Create one asynchronous request.
1124 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
Matt Menkec6b3edf72019-03-19 17:00:391125 EXPECT_THAT(StartRequest(TestGroupId("d"), DEFAULT_PRIORITY),
1126 IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:531127
[email protected]6b175382009-10-13 06:47:471128 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1129 // actually become pending until 2ms after they have been created. In order
1130 // to flush all tasks, we need to wait so that we know there are no
1131 // soon-to-be-pending tasks waiting.
Alex Clarke0def2092018-12-10 12:01:451132 FastForwardBy(base::TimeDelta::FromMilliseconds(10));
[email protected]6b175382009-10-13 06:47:471133
[email protected]211d21722009-07-22 15:48:531134 // The next synchronous request should wait for its turn.
1135 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
Matt Menkec6b3edf72019-03-19 17:00:391136 EXPECT_THAT(StartRequest(TestGroupId("e"), DEFAULT_PRIORITY),
1137 IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:531138
[email protected]2431756e2010-09-29 20:26:131139 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:531140
[email protected]2431756e2010-09-29 20:26:131141 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531142 client_socket_factory_.allocation_count());
1143
1144 EXPECT_EQ(1, GetOrderOfRequest(1));
1145 EXPECT_EQ(2, GetOrderOfRequest(2));
1146 EXPECT_EQ(3, GetOrderOfRequest(3));
1147 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:171148 EXPECT_EQ(5, GetOrderOfRequest(5));
1149
1150 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131151 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:531152}
1153
[email protected]6427fe22010-04-16 22:27:411154TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
1155 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1156 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1157
Matt Menkec6b3edf72019-03-19 17:00:391158 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1159 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1160 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1161 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
[email protected]6427fe22010-04-16 22:27:411162
1163 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1164
1165 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1166
Matt Menkec6b3edf72019-03-19 17:00:391167 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY),
1168 IsError(ERR_IO_PENDING));
1169 EXPECT_THAT(StartRequest(TestGroupId("c"), DEFAULT_PRIORITY),
1170 IsError(ERR_IO_PENDING));
[email protected]6427fe22010-04-16 22:27:411171
1172 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1173
[email protected]2431756e2010-09-29 20:26:131174 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411175 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131176 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411177 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131178 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1179 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411180 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
1181}
1182
[email protected]d7027bb2010-05-10 18:58:541183TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
1184 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1185 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1186
1187 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521188 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:501189 EXPECT_EQ(
1190 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:281191 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
1192 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1193 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1194 pool_.get(), NetLogWithSource()));
[email protected]d7027bb2010-05-10 18:58:541195
1196 ClientSocketHandle handles[4];
Avi Drissman4365a4782018-12-28 19:26:241197 for (size_t i = 0; i < base::size(handles); ++i) {
[email protected]6ecf2b92011-12-15 01:14:521198 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:501199 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:391200 handles[i].Init(
Matt Menkef09e64c2019-04-23 22:16:281201 TestGroupId("b"), params_, base::nullopt, DEFAULT_PRIORITY,
1202 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1203 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1204 pool_.get(), NetLogWithSource()));
[email protected]d7027bb2010-05-10 18:58:541205 }
1206
1207 // One will be stalled, cancel all the handles now.
1208 // This should hit the OnAvailableSocketSlot() code where we previously had
1209 // stalled groups, but no longer have any.
Avi Drissman4365a4782018-12-28 19:26:241210 for (size_t i = 0; i < base::size(handles); ++i)
[email protected]d7027bb2010-05-10 18:58:541211 handles[i].Reset();
1212}
1213
[email protected]eb5a99382010-07-11 03:18:261214TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
[email protected]43a21b82010-06-10 21:30:541215 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1216 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1217
[email protected]eb5a99382010-07-11 03:18:261218 {
1219 ClientSocketHandle handles[kDefaultMaxSockets];
[email protected]6ecf2b92011-12-15 01:14:521220 TestCompletionCallback callbacks[kDefaultMaxSockets];
[email protected]eb5a99382010-07-11 03:18:261221 for (int i = 0; i < kDefaultMaxSockets; ++i) {
Matt Menkef09e64c2019-04-23 22:16:281222 EXPECT_EQ(OK,
1223 handles[i].Init(TestGroupId(base::NumberToString(i)), params_,
1224 base::nullopt, DEFAULT_PRIORITY, SocketTag(),
1225 ClientSocketPool::RespectLimits::ENABLED,
1226 callbacks[i].callback(),
1227 ClientSocketPool::ProxyAuthCallback(),
1228 pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261229 }
1230
1231 // Force a stalled group.
1232 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521233 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:201234 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:391235 stalled_handle.Init(
Matt Menkef09e64c2019-04-23 22:16:281236 TestGroupId("foo"), params_, base::nullopt, DEFAULT_PRIORITY,
1237 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1238 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1239 pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261240
1241 // Cancel the stalled request.
1242 stalled_handle.Reset();
1243
1244 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1245 EXPECT_EQ(0, pool_->IdleSocketCount());
1246
1247 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541248 }
1249
[email protected]43a21b82010-06-10 21:30:541250 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1251 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
[email protected]eb5a99382010-07-11 03:18:261252}
[email protected]43a21b82010-06-10 21:30:541253
[email protected]eb5a99382010-07-11 03:18:261254TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
1255 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1256 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1257
1258 {
1259 ClientSocketHandle handles[kDefaultMaxSockets];
1260 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:521261 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:201262 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:391263 handles[i].Init(TestGroupId(base::NumberToString(i)), params_,
Matt Menkef09e64c2019-04-23 22:16:281264 base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menkec6b3edf72019-03-19 17:00:391265 ClientSocketPool::RespectLimits::ENABLED,
1266 callback.callback(),
1267 ClientSocketPool::ProxyAuthCallback(),
1268 pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261269 }
1270
1271 // Force a stalled group.
1272 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1273 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521274 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:201275 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:391276 stalled_handle.Init(
Matt Menkef09e64c2019-04-23 22:16:281277 TestGroupId("foo"), params_, base::nullopt, DEFAULT_PRIORITY,
1278 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1279 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1280 pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261281
1282 // Since it is stalled, it should have no connect jobs.
Matt Menke9fa17d52019-03-25 19:12:261283 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("foo")));
1284 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
1285 TestGroupId("foo")));
1286 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroupForTesting(
1287 TestGroupId("foo")));
[email protected]eb5a99382010-07-11 03:18:261288
1289 // Cancel the stalled request.
1290 handles[0].Reset();
1291
[email protected]eb5a99382010-07-11 03:18:261292 // Now we should have a connect job.
Matt Menke9fa17d52019-03-25 19:12:261293 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("foo")));
1294 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
1295 TestGroupId("foo")));
1296 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroupForTesting(
1297 TestGroupId("foo")));
[email protected]eb5a99382010-07-11 03:18:261298
1299 // The stalled socket should connect.
robpercival214763f2016-07-01 23:27:011300 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:261301
1302 EXPECT_EQ(kDefaultMaxSockets + 1,
1303 client_socket_factory_.allocation_count());
1304 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menke9fa17d52019-03-25 19:12:261305 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("foo")));
1306 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
1307 TestGroupId("foo")));
1308 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroupForTesting(
1309 TestGroupId("foo")));
[email protected]eb5a99382010-07-11 03:18:261310
1311 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541312 }
1313
[email protected]eb5a99382010-07-11 03:18:261314 EXPECT_EQ(1, pool_->IdleSocketCount());
1315}
[email protected]43a21b82010-06-10 21:30:541316
[email protected]eb5a99382010-07-11 03:18:261317TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
1318 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1319 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]43a21b82010-06-10 21:30:541320
[email protected]eb5a99382010-07-11 03:18:261321 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521322 TestCompletionCallback callback;
[email protected]eb5a99382010-07-11 03:18:261323 {
[email protected]51fdc7c2012-04-10 19:19:481324 EXPECT_FALSE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261325 ClientSocketHandle handles[kDefaultMaxSockets];
1326 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:521327 TestCompletionCallback callback;
Matt Menkec6b3edf72019-03-19 17:00:391328 EXPECT_EQ(
Matt Menkef09e64c2019-04-23 22:16:281329 OK, handles[i].Init(
1330 TestGroupId(base::StringPrintf("Take 2: %d", i)), params_,
1331 base::nullopt, DEFAULT_PRIORITY, SocketTag(),
1332 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1333 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
1334 NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261335 }
1336
1337 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1338 EXPECT_EQ(0, pool_->IdleSocketCount());
[email protected]51fdc7c2012-04-10 19:19:481339 EXPECT_FALSE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261340
1341 // Now we will hit the socket limit.
tfarina428341112016-09-22 13:38:201342 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:391343 stalled_handle.Init(
Matt Menkef09e64c2019-04-23 22:16:281344 TestGroupId("foo"), params_, base::nullopt, DEFAULT_PRIORITY,
1345 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1346 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1347 pool_.get(), NetLogWithSource()));
[email protected]51fdc7c2012-04-10 19:19:481348 EXPECT_TRUE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261349
1350 // Dropping out of scope will close all handles and return them to idle.
1351 }
[email protected]43a21b82010-06-10 21:30:541352
1353 // But if we wait for it, the released idle sockets will be closed in
1354 // preference of the waiting request.
robpercival214763f2016-07-01 23:27:011355 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:261356
1357 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1358 EXPECT_EQ(3, pool_->IdleSocketCount());
[email protected]43a21b82010-06-10 21:30:541359}
1360
1361// Regression test for http://crbug.com/40952.
1362TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
Matt Menke9fa17d52019-03-25 19:12:261363 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1364 true /* enable_backup_connect_jobs */);
[email protected]43a21b82010-06-10 21:30:541365 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1366
1367 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1368 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521369 TestCompletionCallback callback;
Matt Menkec6b3edf72019-03-19 17:00:391370 EXPECT_EQ(OK, handle.Init(TestGroupId(base::NumberToString(i)), params_,
Matt Menkef09e64c2019-04-23 22:16:281371 base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menkec6b3edf72019-03-19 17:00:391372 ClientSocketPool::RespectLimits::ENABLED,
1373 callback.callback(),
1374 ClientSocketPool::ProxyAuthCallback(),
1375 pool_.get(), NetLogWithSource()));
[email protected]43a21b82010-06-10 21:30:541376 }
1377
1378 // Flush all the DoReleaseSocket tasks.
fdoray5eeb7642016-06-22 16:11:281379 base::RunLoop().RunUntilIdle();
[email protected]43a21b82010-06-10 21:30:541380
1381 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
1382 // reuse a socket.
1383 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1384 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521385 TestCompletionCallback callback;
[email protected]43a21b82010-06-10 21:30:541386
1387 // "0" is special here, since it should be the first entry in the sorted map,
1388 // which is the one which we would close an idle socket for. We shouldn't
1389 // close an idle socket though, since we should reuse the idle socket.
Matt Menkec6b3edf72019-03-19 17:00:391390 EXPECT_EQ(OK, handle.Init(
Matt Menkef09e64c2019-04-23 22:16:281391 TestGroupId("0"), params_, base::nullopt, DEFAULT_PRIORITY,
1392 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menkec6b3edf72019-03-19 17:00:391393 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1394 pool_.get(), NetLogWithSource()));
[email protected]43a21b82010-06-10 21:30:541395
1396 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1397 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
1398}
1399
[email protected]ab838892009-06-30 18:49:051400TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:531401 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091402
Matt Menkec6b3edf72019-03-19 17:00:391403 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1404 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1405 EXPECT_THAT(StartRequest(TestGroupId("a"), IDLE), IsError(ERR_IO_PENDING));
1406 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
1407 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1408 EXPECT_THAT(StartRequest(TestGroupId("a"), HIGHEST), IsError(ERR_IO_PENDING));
1409 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsError(ERR_IO_PENDING));
1410 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091411
[email protected]2431756e2010-09-29 20:26:131412 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]c9d6a1d2009-07-14 16:15:201413 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1414 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131415 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1416 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091417
[email protected]c9d6a1d2009-07-14 16:15:201418 EXPECT_EQ(1, GetOrderOfRequest(1));
1419 EXPECT_EQ(2, GetOrderOfRequest(2));
[email protected]c9c6f5c2010-07-31 01:30:031420 EXPECT_EQ(8, GetOrderOfRequest(3));
1421 EXPECT_EQ(6, GetOrderOfRequest(4));
1422 EXPECT_EQ(4, GetOrderOfRequest(5));
1423 EXPECT_EQ(3, GetOrderOfRequest(6));
1424 EXPECT_EQ(5, GetOrderOfRequest(7));
1425 EXPECT_EQ(7, GetOrderOfRequest(8));
[email protected]75439d3b2009-07-23 22:11:171426
1427 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131428 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]f6d1d6eb2009-06-24 20:16:091429}
1430
[email protected]ab838892009-06-30 18:49:051431TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:531432 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091433
Matt Menkec6b3edf72019-03-19 17:00:391434 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1435 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1436 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
1437 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1438 EXPECT_THAT(StartRequest(TestGroupId("a"), HIGHEST), IsError(ERR_IO_PENDING));
1439 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsError(ERR_IO_PENDING));
1440 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091441
[email protected]2431756e2010-09-29 20:26:131442 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091443
[email protected]2431756e2010-09-29 20:26:131444 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i)
robpercival214763f2016-07-01 23:27:011445 EXPECT_THAT(request(i)->WaitForResult(), IsOk());
[email protected]c9d6a1d2009-07-14 16:15:201446
[email protected]2431756e2010-09-29 20:26:131447 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]c9d6a1d2009-07-14 16:15:201448 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131449 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1450 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091451}
1452
Matt Menke7eb405e2019-04-25 20:48:211453TEST_F(ClientSocketPoolBaseTest, ResetAndCloseSocket) {
1454 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1455
1456 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1457 ClientSocketHandle handle;
1458 TestCompletionCallback callback;
1459 EXPECT_EQ(
1460 ERR_IO_PENDING,
1461 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
1462 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1463 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1464 pool_.get(), NetLogWithSource()));
1465
1466 EXPECT_THAT(callback.WaitForResult(), IsOk());
1467 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1468 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1469 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
1470 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
1471
1472 handle.ResetAndCloseSocket();
1473 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
1474}
1475
Matt Menke99251ea42019-04-25 22:59:021476// This test will start up a socket request and then call Reset() on the handle.
1477// The pending ConnectJob should not be destroyed.
Matt Menke7eb405e2019-04-25 20:48:211478TEST_F(ClientSocketPoolBaseTest, CancelRequestKeepsConnectJob) {
[email protected]211d21722009-07-22 15:48:531479 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201480
[email protected]ab838892009-06-30 18:49:051481 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131482 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521483 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:501484 EXPECT_EQ(
1485 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:281486 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
1487 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1488 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1489 pool_.get(), NetLogWithSource()));
[email protected]2431756e2010-09-29 20:26:131490 handle.Reset();
Matt Menke7eb405e2019-04-25 20:48:211491 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1492 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1493}
1494
Matt Menke99251ea42019-04-25 22:59:021495// This test will start up a socket request and then call ResetAndCloseSocket()
1496// on the handle. The pending ConnectJob or connected socket should be
1497// destroyed.
Matt Menke7eb405e2019-04-25 20:48:211498TEST_F(ClientSocketPoolBaseTest, CancelRequestAndCloseSocket) {
1499 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1500
Matt Menke99251ea42019-04-25 22:59:021501 // When true, the socket connects before it's canceled.
1502 for (bool cancel_when_callback_pending : {false, true}) {
1503 if (cancel_when_callback_pending) {
1504 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1505 } else {
1506 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1507 }
1508 ClientSocketHandle handle;
1509 TestCompletionCallback callback;
1510 EXPECT_EQ(
1511 ERR_IO_PENDING,
1512 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
1513 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1514 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1515 pool_.get(), NetLogWithSource()));
1516 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1517 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1518
1519 if (cancel_when_callback_pending) {
1520 client_socket_factory_.SignalJobs();
1521 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1522 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
1523 }
1524
1525 handle.ResetAndCloseSocket();
1526 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
1527 }
Matt Menke7eb405e2019-04-25 20:48:211528}
1529
1530TEST_F(ClientSocketPoolBaseTest,
1531 CancelRequestAndCloseSocketWhenMoreRequestsThanConnectJobs) {
1532 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1533
Matt Menke99251ea42019-04-25 22:59:021534 // When true, the sockets connect before they're canceled.
1535 for (bool cancel_when_callback_pending : {false, true}) {
1536 if (cancel_when_callback_pending) {
1537 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1538 } else {
1539 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1540 }
Matt Menke7eb405e2019-04-25 20:48:211541
Matt Menke99251ea42019-04-25 22:59:021542 std::vector<std::unique_ptr<ClientSocketHandle>> handles;
1543 TestCompletionCallback callback;
1544 // Make |kDefaultMaxSockets + 1| socket requests.
1545 for (int i = 0; i < kDefaultMaxSocketsPerGroup + 1; ++i) {
1546 std::unique_ptr<ClientSocketHandle> handle =
1547 std::make_unique<ClientSocketHandle>();
1548 EXPECT_EQ(ERR_IO_PENDING,
1549 handle->Init(
1550 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
1551 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1552 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1553 pool_.get(), NetLogWithSource()));
1554 handles.push_back(std::move(handle));
Matt Menke7eb405e2019-04-25 20:48:211555 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
Matt Menke99251ea42019-04-25 22:59:021556 EXPECT_EQ(
1557 static_cast<size_t>(std::min(i + 1, kDefaultMaxSocketsPerGroup)),
1558 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1559 }
1560
1561 if (cancel_when_callback_pending) {
1562 client_socket_factory_.SignalJobs();
1563 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1564 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1565 pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
1566 }
1567
1568 // Calling ResetAndCloseSocket() on a handle should not cancel a ConnectJob
1569 // or close a socket, since there are more requests than ConnectJobs or
1570 // sockets.
1571 handles[kDefaultMaxSocketsPerGroup]->ResetAndCloseSocket();
1572 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1573 if (cancel_when_callback_pending) {
1574 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1575 pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
1576 } else {
1577 EXPECT_EQ(static_cast<size_t>(kDefaultMaxSocketsPerGroup),
Matt Menke7eb405e2019-04-25 20:48:211578 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1579 }
Matt Menke99251ea42019-04-25 22:59:021580
1581 // Calling ResetAndCloseSocket() on other handles should cancel a ConnectJob
1582 // or close a socket.
1583 for (int i = kDefaultMaxSocketsPerGroup - 1; i >= 0; --i) {
1584 handles[i]->ResetAndCloseSocket();
1585 if (i > 0) {
1586 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1587 if (cancel_when_callback_pending) {
1588 EXPECT_EQ(i,
1589 pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
1590 } else {
1591 EXPECT_EQ(static_cast<size_t>(i),
1592 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1593 }
1594 } else {
1595 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
1596 }
1597 }
Matt Menke7eb405e2019-04-25 20:48:211598 }
[email protected]f6d1d6eb2009-06-24 20:16:091599}
1600
[email protected]ab838892009-06-30 18:49:051601TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531602 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201603
[email protected]ab838892009-06-30 18:49:051604 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061605 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521606 TestCompletionCallback callback;
[email protected]f6d1d6eb2009-06-24 20:16:091607
Matt Menke28ac03e2019-02-25 22:25:501608 EXPECT_EQ(
1609 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:281610 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
1611 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1612 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1613 pool_.get(), NetLogWithSource()));
[email protected]f6d1d6eb2009-06-24 20:16:091614
1615 handle.Reset();
Matt Menke7eb405e2019-04-25 20:48:211616 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1617 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]f6d1d6eb2009-06-24 20:16:091618
Matt Menke7eb405e2019-04-25 20:48:211619 // This will create a second ConnectJob, since the other ConnectJob was
1620 // previously assigned to a request.
[email protected]6ecf2b92011-12-15 01:14:521621 TestCompletionCallback callback2;
Matt Menke28ac03e2019-02-25 22:25:501622 EXPECT_EQ(
1623 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:281624 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
1625 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501626 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
1627 pool_.get(), NetLogWithSource()));
[email protected]f6d1d6eb2009-06-24 20:16:091628
Matt Menke7eb405e2019-04-25 20:48:211629 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1630 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1631
robpercival214763f2016-07-01 23:27:011632 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]f6d1d6eb2009-06-24 20:16:091633 EXPECT_FALSE(callback.have_result());
Matt Menke7eb405e2019-04-25 20:48:211634 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1635 // One ConnectJob completed, and its socket is now assigned to |handle|.
1636 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
1637 // The other ConnectJob should have either completed, or still be connecting.
1638 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")) +
1639 pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]f6d1d6eb2009-06-24 20:16:091640
1641 handle.Reset();
Matt Menke7eb405e2019-04-25 20:48:211642 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1643 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")) +
1644 pool_->IdleSocketCountInGroup(TestGroupId("a")));
1645 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
[email protected]f6d1d6eb2009-06-24 20:16:091646}
1647
[email protected]ab838892009-06-30 18:49:051648TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531649 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091650
Matt Menkec6b3edf72019-03-19 17:00:391651 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1652 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1653 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
1654 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1655 EXPECT_THAT(StartRequest(TestGroupId("a"), HIGHEST), IsError(ERR_IO_PENDING));
1656 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsError(ERR_IO_PENDING));
1657 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091658
1659 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:201660 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]2431756e2010-09-29 20:26:131661 EXPECT_FALSE((*requests())[index_to_cancel]->handle()->is_initialized());
1662 (*requests())[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091663
[email protected]2431756e2010-09-29 20:26:131664 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091665
[email protected]c9d6a1d2009-07-14 16:15:201666 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1667 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131668 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup - 1,
1669 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091670
[email protected]c9d6a1d2009-07-14 16:15:201671 EXPECT_EQ(1, GetOrderOfRequest(1));
1672 EXPECT_EQ(2, GetOrderOfRequest(2));
1673 EXPECT_EQ(5, GetOrderOfRequest(3));
1674 EXPECT_EQ(3, GetOrderOfRequest(4));
[email protected]2431756e2010-09-29 20:26:131675 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
1676 GetOrderOfRequest(5)); // Canceled request.
[email protected]c9d6a1d2009-07-14 16:15:201677 EXPECT_EQ(4, GetOrderOfRequest(6));
1678 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171679
1680 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131681 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:091682}
1683
mmenke33d24423d2015-05-19 19:41:091684// Function to be used as a callback on socket request completion. It first
1685// disconnects the successfully connected socket from the first request, and
1686// then reuses the ClientSocketHandle to request another socket.
1687//
1688// |nested_callback| is called with the result of the second socket request.
1689void RequestSocketOnComplete(ClientSocketHandle* handle,
Matt Menke9fa17d52019-03-25 19:12:261690 TransportClientSocketPool* pool,
mmenke33d24423d2015-05-19 19:41:091691 TestConnectJobFactory* test_connect_job_factory,
1692 TestConnectJob::JobType next_job_type,
Bence Békya4a50932018-08-10 13:39:411693 TestCompletionCallback* nested_callback,
mmenke33d24423d2015-05-19 19:41:091694 int first_request_result) {
robpercival214763f2016-07-01 23:27:011695 EXPECT_THAT(first_request_result, IsOk());
mmenke33d24423d2015-05-19 19:41:091696
1697 test_connect_job_factory->set_job_type(next_job_type);
1698
1699 // Don't allow reuse of the socket. Disconnect it and then release it.
1700 if (handle->socket())
1701 handle->socket()->Disconnect();
1702 handle->Reset();
1703
mmenke33d24423d2015-05-19 19:41:091704 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:501705 int rv = handle->Init(
Matt Menke870e19ab2019-04-23 16:23:031706 TestGroupId("a"),
Matt Menkef09e64c2019-04-23 22:16:281707 ClientSocketPool::SocketParams::CreateForHttpForTesting(), base::nullopt,
1708 LOWEST, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke870e19ab2019-04-23 16:23:031709 nested_callback->callback(), ClientSocketPool::ProxyAuthCallback(), pool,
1710 NetLogWithSource());
mmenke33d24423d2015-05-19 19:41:091711 if (rv != ERR_IO_PENDING) {
1712 DCHECK_EQ(TestConnectJob::kMockJob, next_job_type);
Bence Békya4a50932018-08-10 13:39:411713 nested_callback->callback().Run(rv);
mmenke33d24423d2015-05-19 19:41:091714 } else {
1715 DCHECK_EQ(TestConnectJob::kMockPendingJob, next_job_type);
[email protected]6ecf2b92011-12-15 01:14:521716 }
mmenke33d24423d2015-05-19 19:41:091717}
[email protected]f6d1d6eb2009-06-24 20:16:091718
mmenke33d24423d2015-05-19 19:41:091719// Tests the case where a second socket is requested in a completion callback,
1720// and the second socket connects asynchronously. Reuses the same
1721// ClientSocketHandle for the second socket, after disconnecting the first.
[email protected]2ab05b52009-07-01 23:57:581722TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531723 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201724
[email protected]0b7648c2009-07-06 20:14:011725 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061726 ClientSocketHandle handle;
mmenke33d24423d2015-05-19 19:41:091727 TestCompletionCallback second_result_callback;
1728 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:281729 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Paul Jensen8d6f87ec2018-01-13 00:46:541730 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501731 base::BindOnce(&RequestSocketOnComplete, &handle, pool_.get(),
1732 connect_job_factory_, TestConnectJob::kMockPendingJob,
1733 &second_result_callback),
1734 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011735 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091736
robpercival214763f2016-07-01 23:27:011737 EXPECT_THAT(second_result_callback.WaitForResult(), IsOk());
[email protected]2ab05b52009-07-01 23:57:581738}
[email protected]f6d1d6eb2009-06-24 20:16:091739
mmenke33d24423d2015-05-19 19:41:091740// Tests the case where a second socket is requested in a completion callback,
1741// and the second socket connects synchronously. Reuses the same
1742// ClientSocketHandle for the second socket, after disconnecting the first.
[email protected]2ab05b52009-07-01 23:57:581743TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531744 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201745
[email protected]0b7648c2009-07-06 20:14:011746 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061747 ClientSocketHandle handle;
mmenke33d24423d2015-05-19 19:41:091748 TestCompletionCallback second_result_callback;
1749 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:281750 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Paul Jensen8d6f87ec2018-01-13 00:46:541751 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501752 base::BindOnce(&RequestSocketOnComplete, &handle, pool_.get(),
1753 connect_job_factory_, TestConnectJob::kMockPendingJob,
1754 &second_result_callback),
1755 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011756 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2ab05b52009-07-01 23:57:581757
robpercival214763f2016-07-01 23:27:011758 EXPECT_THAT(second_result_callback.WaitForResult(), IsOk());
[email protected]f6d1d6eb2009-06-24 20:16:091759}
1760
1761// Make sure that pending requests get serviced after active requests get
1762// cancelled.
[email protected]ab838892009-06-30 18:49:051763TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531764 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201765
[email protected]0b7648c2009-07-06 20:14:011766 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091767
Matt Menkec6b3edf72019-03-19 17:00:391768 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1769 IsError(ERR_IO_PENDING));
1770 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1771 IsError(ERR_IO_PENDING));
1772 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1773 IsError(ERR_IO_PENDING));
1774 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1775 IsError(ERR_IO_PENDING));
1776 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1777 IsError(ERR_IO_PENDING));
1778 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1779 IsError(ERR_IO_PENDING));
1780 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1781 IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091782
[email protected]c9d6a1d2009-07-14 16:15:201783 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1784 // Let's cancel them.
1785 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]2431756e2010-09-29 20:26:131786 ASSERT_FALSE(request(i)->handle()->is_initialized());
1787 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091788 }
1789
[email protected]f6d1d6eb2009-06-24 20:16:091790 // Let's wait for the rest to complete now.
[email protected]2431756e2010-09-29 20:26:131791 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i) {
robpercival214763f2016-07-01 23:27:011792 EXPECT_THAT(request(i)->WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:131793 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091794 }
1795
[email protected]2431756e2010-09-29 20:26:131796 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1797 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091798}
1799
1800// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051801TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531802 const size_t kMaxSockets = 5;
1803 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201804
[email protected]0b7648c2009-07-06 20:14:011805 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091806
[email protected]211d21722009-07-22 15:48:531807 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1808 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091809
1810 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531811 for (size_t i = 0; i < kNumberOfRequests; ++i)
Matt Menkec6b3edf72019-03-19 17:00:391812 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1813 IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091814
[email protected]211d21722009-07-22 15:48:531815 for (size_t i = 0; i < kNumberOfRequests; ++i)
robpercival214763f2016-07-01 23:27:011816 EXPECT_THAT(request(i)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]f6d1d6eb2009-06-24 20:16:091817}
1818
mmenke9d72fe42017-05-18 22:36:071819// Make sure that pending requests that complete synchronously get serviced
1820// after active requests fail. See https://crbug.com/723748
1821TEST_F(ClientSocketPoolBaseTest, HandleMultipleSyncFailuresAfterAsyncFailure) {
1822 const size_t kNumberOfRequests = 10;
1823 const size_t kMaxSockets = 1;
1824 CreatePool(kMaxSockets, kMaxSockets);
1825
1826 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1827
Matt Menkec6b3edf72019-03-19 17:00:391828 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1829 IsError(ERR_IO_PENDING));
mmenke9d72fe42017-05-18 22:36:071830
1831 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
1832
1833 // Queue up all the other requests
1834 for (size_t i = 1; i < kNumberOfRequests; ++i)
Matt Menkec6b3edf72019-03-19 17:00:391835 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1836 IsError(ERR_IO_PENDING));
mmenke9d72fe42017-05-18 22:36:071837
1838 // Make sure all requests fail, instead of hanging.
1839 for (size_t i = 0; i < kNumberOfRequests; ++i)
1840 EXPECT_THAT(request(i)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
1841}
1842
[email protected]5fc08e32009-07-15 17:09:571843TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531844 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571845
1846 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1847
[email protected]2431756e2010-09-29 20:26:131848 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521849 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:501850 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:281851 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:501852 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1853 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011854 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:571855
1856 // Cancel the active request.
[email protected]2431756e2010-09-29 20:26:131857 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571858
Matt Menkef09e64c2019-04-23 22:16:281859 rv = handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
1860 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501861 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1862 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011863 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1864 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]5fc08e32009-07-15 17:09:571865
[email protected]2431756e2010-09-29 20:26:131866 EXPECT_FALSE(handle.is_reused());
[email protected]034df0f32013-01-07 23:17:481867 TestLoadTimingInfoConnectedNotReused(handle);
[email protected]5fc08e32009-07-15 17:09:571868 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1869}
1870
xunjieli26619e72016-11-23 19:39:551871TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsForced) {
xunjieli26619e72016-11-23 19:39:551872 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1873 ClientSocketHandle handle;
1874 TestCompletionCallback callback;
1875 BoundTestNetLog log;
Matt Menke28ac03e2019-02-25 22:25:501876 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:281877 TestGroupId("a"), params_, base::nullopt, LOWEST, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:501878 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1879 ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound());
xunjieli26619e72016-11-23 19:39:551880 EXPECT_THAT(rv, IsOk());
1881 handle.Reset();
1882 EXPECT_EQ(1, pool_->IdleSocketCount());
1883 pool_->CloseIdleSockets();
xunjieli26619e72016-11-23 19:39:551884}
1885
xunjieli92feb332017-03-03 17:19:231886TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsInGroupForced) {
xunjieli92feb332017-03-03 17:19:231887 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1888 TestCompletionCallback callback;
1889 BoundTestNetLog log;
1890 ClientSocketHandle handle1;
Matt Menke28ac03e2019-02-25 22:25:501891 int rv = handle1.Init(
Matt Menkef09e64c2019-04-23 22:16:281892 TestGroupId("a"), params_, base::nullopt, LOWEST, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:501893 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1894 ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound());
xunjieli92feb332017-03-03 17:19:231895 EXPECT_THAT(rv, IsOk());
1896 ClientSocketHandle handle2;
Matt Menkef09e64c2019-04-23 22:16:281897 rv = handle2.Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
1898 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501899 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1900 pool_.get(), log.bound());
xunjieli92feb332017-03-03 17:19:231901 ClientSocketHandle handle3;
Matt Menkef09e64c2019-04-23 22:16:281902 rv = handle3.Init(TestGroupId("b"), params_, base::nullopt, LOWEST,
1903 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501904 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1905 pool_.get(), log.bound());
xunjieli92feb332017-03-03 17:19:231906 EXPECT_THAT(rv, IsOk());
1907 handle1.Reset();
1908 handle2.Reset();
1909 handle3.Reset();
1910 EXPECT_EQ(3, pool_->IdleSocketCount());
Matt Menkec6b3edf72019-03-19 17:00:391911 pool_->CloseIdleSocketsInGroup(TestGroupId("a"));
xunjieli92feb332017-03-03 17:19:231912 EXPECT_EQ(1, pool_->IdleSocketCount());
xunjieli92feb332017-03-03 17:19:231913}
1914
xunjieli26619e72016-11-23 19:39:551915TEST_F(ClientSocketPoolBaseTest, CleanUpUnusableIdleSockets) {
xunjieli26619e72016-11-23 19:39:551916 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1917 ClientSocketHandle handle;
1918 TestCompletionCallback callback;
1919 BoundTestNetLog log;
Matt Menke28ac03e2019-02-25 22:25:501920 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:281921 TestGroupId("a"), params_, base::nullopt, LOWEST, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:501922 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1923 ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound());
xunjieli26619e72016-11-23 19:39:551924 EXPECT_THAT(rv, IsOk());
1925 StreamSocket* socket = handle.socket();
1926 handle.Reset();
1927 EXPECT_EQ(1, pool_->IdleSocketCount());
1928
1929 // Disconnect socket now to make the socket unusable.
1930 socket->Disconnect();
1931 ClientSocketHandle handle2;
Matt Menkef09e64c2019-04-23 22:16:281932 rv = handle2.Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
1933 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501934 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1935 pool_.get(), log.bound());
xunjieli26619e72016-11-23 19:39:551936 EXPECT_THAT(rv, IsOk());
1937 EXPECT_FALSE(handle2.is_reused());
xunjieli26619e72016-11-23 19:39:551938}
1939
[email protected]2b7523d2009-07-29 20:29:231940// Regression test for http://crbug.com/17985.
1941TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1942 const int kMaxSockets = 3;
1943 const int kMaxSocketsPerGroup = 2;
1944 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1945
[email protected]ac790b42009-12-02 04:31:311946 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231947
Matt Menkec6b3edf72019-03-19 17:00:391948 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1949 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
[email protected]2b7523d2009-07-29 20:29:231950
1951 // This is going to be a pending request in an otherwise empty group.
Matt Menkec6b3edf72019-03-19 17:00:391952 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1953 IsError(ERR_IO_PENDING));
[email protected]2b7523d2009-07-29 20:29:231954
1955 // Reach the maximum socket limit.
Matt Menkec6b3edf72019-03-19 17:00:391956 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
[email protected]2b7523d2009-07-29 20:29:231957
1958 // Create a stalled group with high priorities.
Matt Menkec6b3edf72019-03-19 17:00:391959 EXPECT_THAT(StartRequest(TestGroupId("c"), kHighPriority),
1960 IsError(ERR_IO_PENDING));
1961 EXPECT_THAT(StartRequest(TestGroupId("c"), kHighPriority),
1962 IsError(ERR_IO_PENDING));
[email protected]2b7523d2009-07-29 20:29:231963
Matt Menkec6b3edf72019-03-19 17:00:391964 // Release the first two sockets from TestGroupId("a"). Because this is a
1965 // keepalive, the first release will unblock the pending request for
1966 // TestGroupId("a"). The second release will unblock a request for "c",
1967 // because it is the next high priority socket.
[email protected]2431756e2010-09-29 20:26:131968 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1969 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]2b7523d2009-07-29 20:29:231970
1971 // Closing idle sockets should not get us into trouble, but in the bug
1972 // we were hitting a CHECK here.
Matt Menkec6b3edf72019-03-19 17:00:391973 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]43a21b82010-06-10 21:30:541974 pool_->CloseIdleSockets();
[email protected]eb5a99382010-07-11 03:18:261975
[email protected]2da659e2013-05-23 20:51:341976 // Run the released socket wakeups.
fdoray5eeb7642016-06-22 16:11:281977 base::RunLoop().RunUntilIdle();
[email protected]2b7523d2009-07-29 20:29:231978}
1979
[email protected]4d3b05d2010-01-27 21:27:291980TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531981 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571982
1983 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131984 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521985 TestCompletionCallback callback;
vishal.b62985ca92015-04-17 08:45:511986 BoundTestNetLog log;
Matt Menke28ac03e2019-02-25 22:25:501987 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:281988 TestGroupId("a"), params_, base::nullopt, LOWEST, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:501989 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1990 ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound());
robpercival214763f2016-07-01 23:27:011991 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Matt Menkec6b3edf72019-03-19 17:00:391992 EXPECT_EQ(LOAD_STATE_CONNECTING,
1993 pool_->GetLoadState(TestGroupId("a"), &handle));
[email protected]034df0f32013-01-07 23:17:481994 TestLoadTimingInfoNotConnected(handle);
1995
robpercival214763f2016-07-01 23:27:011996 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:131997 EXPECT_TRUE(handle.is_initialized());
1998 EXPECT_TRUE(handle.socket());
[email protected]034df0f32013-01-07 23:17:481999 TestLoadTimingInfoConnectedNotReused(handle);
2000
[email protected]2431756e2010-09-29 20:26:132001 handle.Reset();
[email protected]034df0f32013-01-07 23:17:482002 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:302003
mmenke43758e62015-05-04 21:09:462004 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:402005 log.GetEntries(&entries);
2006
Matt Menke9fa17d52019-03-25 19:12:262007 EXPECT_EQ(5u, entries.size());
[email protected]06650c52010-06-03 00:49:172008 EXPECT_TRUE(LogContainsEvent(
Matt Menke9fa17d52019-03-25 19:12:262009 entries, 0, NetLogEventType::TCP_CLIENT_SOCKET_POOL_REQUESTED_SOCKET,
mikecirone8b85c432016-09-08 19:11:002010 NetLogEventPhase::NONE));
Matt Menke9fa17d52019-03-25 19:12:262011 EXPECT_TRUE(LogContainsBeginEvent(entries, 1, NetLogEventType::SOCKET_POOL));
2012 EXPECT_TRUE(LogContainsEvent(
2013 entries, 2, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
2014 NetLogEventPhase::NONE));
2015 EXPECT_TRUE(LogContainsEvent(entries, 3,
mikecirone8b85c432016-09-08 19:11:002016 NetLogEventType::SOCKET_POOL_BOUND_TO_SOCKET,
2017 NetLogEventPhase::NONE));
Matt Menke9fa17d52019-03-25 19:12:262018 EXPECT_TRUE(LogContainsEndEvent(entries, 4, NetLogEventType::SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:572019}
2020
[email protected]4d3b05d2010-01-27 21:27:292021TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:572022 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:532023 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:572024
2025 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]2431756e2010-09-29 20:26:132026 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522027 TestCompletionCallback callback;
vishal.b62985ca92015-04-17 08:45:512028 BoundTestNetLog log;
[email protected]e60e47a2010-07-14 03:37:182029 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:132030 handle.set_is_ssl_error(true);
Matt Menke39b7c5a2019-04-10 19:47:512031 handle.set_ssl_cert_request_info(base::MakeRefCounted<SSLCertRequestInfo>());
Matt Menke28ac03e2019-02-25 22:25:502032 EXPECT_EQ(
2033 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:282034 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2035 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2036 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2037 pool_.get(), log.bound()));
Matt Menkec6b3edf72019-03-19 17:00:392038 EXPECT_EQ(LOAD_STATE_CONNECTING,
2039 pool_->GetLoadState(TestGroupId("a"), &handle));
robpercival214763f2016-07-01 23:27:012040 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]2431756e2010-09-29 20:26:132041 EXPECT_FALSE(handle.is_ssl_error());
Matt Menke39b7c5a2019-04-10 19:47:512042 EXPECT_FALSE(handle.ssl_cert_request_info());
[email protected]fd7b7c92009-08-20 19:38:302043
mmenke43758e62015-05-04 21:09:462044 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:402045 log.GetEntries(&entries);
2046
Matt Menke9fa17d52019-03-25 19:12:262047 EXPECT_EQ(4u, entries.size());
[email protected]06650c52010-06-03 00:49:172048 EXPECT_TRUE(LogContainsEvent(
Matt Menke9fa17d52019-03-25 19:12:262049 entries, 0, NetLogEventType::TCP_CLIENT_SOCKET_POOL_REQUESTED_SOCKET,
mikecirone8b85c432016-09-08 19:11:002050 NetLogEventPhase::NONE));
Matt Menke9fa17d52019-03-25 19:12:262051 EXPECT_TRUE(LogContainsBeginEvent(entries, 1, NetLogEventType::SOCKET_POOL));
2052 EXPECT_TRUE(LogContainsEvent(
2053 entries, 2, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
2054 NetLogEventPhase::NONE));
2055 EXPECT_TRUE(LogContainsEndEvent(entries, 3, NetLogEventType::SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:572056}
2057
mmenke6be122f2015-03-09 22:22:472058// Check that an async ConnectJob failure does not result in creation of a new
2059// ConnectJob when there's another pending request also waiting on its own
2060// ConnectJob. See http://crbug.com/463960.
2061TEST_F(ClientSocketPoolBaseTest, AsyncFailureWithPendingRequestWithJob) {
2062 CreatePool(2, 2);
2063 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2064
Matt Menkec6b3edf72019-03-19 17:00:392065 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2066 IsError(ERR_IO_PENDING));
2067 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2068 IsError(ERR_IO_PENDING));
mmenke6be122f2015-03-09 22:22:472069
robpercival214763f2016-07-01 23:27:012070 EXPECT_THAT(request(0)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
2071 EXPECT_THAT(request(1)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
mmenke6be122f2015-03-09 22:22:472072
2073 EXPECT_EQ(2, client_socket_factory_.allocation_count());
2074}
2075
[email protected]4d3b05d2010-01-27 21:27:292076TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]b22b5162010-03-16 07:53:102077 // TODO(eroman): Add back the log expectations! Removed them because the
2078 // ordering is difficult, and some may fire during destructor.
[email protected]211d21722009-07-22 15:48:532079 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:572080
2081 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:132082 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522083 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132084 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522085 TestCompletionCallback callback2;
[email protected]5fc08e32009-07-15 17:09:572086
Matt Menke28ac03e2019-02-25 22:25:502087 EXPECT_EQ(
2088 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:282089 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2090 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2091 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2092 pool_.get(), NetLogWithSource()));
vishal.b62985ca92015-04-17 08:45:512093 BoundTestNetLog log2;
tfarina428341112016-09-22 13:38:202094 EXPECT_EQ(
2095 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:282096 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2097 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502098 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2099 pool_.get(), NetLogWithSource()));
[email protected]5fc08e32009-07-15 17:09:572100
[email protected]2431756e2010-09-29 20:26:132101 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:572102
[email protected]fd7b7c92009-08-20 19:38:302103
2104 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]fd7b7c92009-08-20 19:38:302105
robpercival214763f2016-07-01 23:27:012106 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132107 handle2.Reset();
[email protected]fd7b7c92009-08-20 19:38:302108
2109 // Now request 2 has actually finished.
[email protected]9e743cd2010-03-16 07:03:532110 // TODO(eroman): Add back log expectations.
[email protected]5fc08e32009-07-15 17:09:572111}
2112
[email protected]4d3b05d2010-01-27 21:27:292113TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:342114 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2115
[email protected]17a0c6c2009-08-04 00:07:042116 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2117
Matt Menkec6b3edf72019-03-19 17:00:392118 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
2119 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsError(ERR_IO_PENDING));
2120 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
2121 EXPECT_THAT(StartRequest(TestGroupId("a"), HIGHEST), IsError(ERR_IO_PENDING));
[email protected]974ebd62009-08-03 23:14:342122
Raul Tambre8335a6d2019-02-21 16:57:432123 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
Matt Menke9fa17d52019-03-25 19:12:262124 static_cast<int>(
2125 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))));
[email protected]2431756e2010-09-29 20:26:132126 (*requests())[2]->handle()->Reset();
2127 (*requests())[3]->handle()->Reset();
Raul Tambre8335a6d2019-02-21 16:57:432128 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
Matt Menke9fa17d52019-03-25 19:12:262129 static_cast<int>(
2130 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))));
[email protected]974ebd62009-08-03 23:14:342131
[email protected]2431756e2010-09-29 20:26:132132 (*requests())[1]->handle()->Reset();
Raul Tambre8335a6d2019-02-21 16:57:432133 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
Matt Menke9fa17d52019-03-25 19:12:262134 static_cast<int>(
2135 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))));
[email protected]974ebd62009-08-03 23:14:342136
[email protected]2431756e2010-09-29 20:26:132137 (*requests())[0]->handle()->Reset();
Raul Tambre8335a6d2019-02-21 16:57:432138 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
Matt Menke9fa17d52019-03-25 19:12:262139 static_cast<int>(
2140 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))));
[email protected]974ebd62009-08-03 23:14:342141}
2142
[email protected]5fc08e32009-07-15 17:09:572143// When requests and ConnectJobs are not coupled, the request will get serviced
2144// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:292145TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:532146 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:572147
2148 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:322149 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:572150
[email protected]2431756e2010-09-29 20:26:132151 std::vector<TestSocketRequest*> request_order;
2152 size_t completion_count; // unused
2153 TestSocketRequest req1(&request_order, &completion_count);
Matt Menke28ac03e2019-02-25 22:25:502154 int rv = req1.handle()->Init(
Matt Menkef09e64c2019-04-23 22:16:282155 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502156 ClientSocketPool::RespectLimits::ENABLED, req1.callback(),
2157 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012158 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2159 EXPECT_THAT(req1.WaitForResult(), IsOk());
[email protected]5fc08e32009-07-15 17:09:572160
2161 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
2162 // without a job.
2163 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2164
[email protected]2431756e2010-09-29 20:26:132165 TestSocketRequest req2(&request_order, &completion_count);
Matt Menke28ac03e2019-02-25 22:25:502166 rv = req2.handle()->Init(
Matt Menkef09e64c2019-04-23 22:16:282167 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502168 ClientSocketPool::RespectLimits::ENABLED, req2.callback(),
2169 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012170 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2431756e2010-09-29 20:26:132171 TestSocketRequest req3(&request_order, &completion_count);
Matt Menke28ac03e2019-02-25 22:25:502172 rv = req3.handle()->Init(
Matt Menkef09e64c2019-04-23 22:16:282173 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502174 ClientSocketPool::RespectLimits::ENABLED, req3.callback(),
2175 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012176 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:572177
2178 // Both Requests 2 and 3 are pending. We release socket 1 which should
2179 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:332180 req1.handle()->Reset();
[email protected]2da659e2013-05-23 20:51:342181 // Run the released socket wakeups.
fdoray5eeb7642016-06-22 16:11:282182 base::RunLoop().RunUntilIdle();
[email protected]a6c59f62009-07-29 16:33:332183 ASSERT_TRUE(req2.handle()->socket());
robpercival214763f2016-07-01 23:27:012184 EXPECT_THAT(req2.WaitForResult(), IsOk());
[email protected]a6c59f62009-07-29 16:33:332185 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:572186
2187 // Signal job 2, which should service request 3.
2188
2189 client_socket_factory_.SignalJobs();
robpercival214763f2016-07-01 23:27:012190 EXPECT_THAT(req3.WaitForResult(), IsOk());
[email protected]5fc08e32009-07-15 17:09:572191
Raul Tambre8335a6d2019-02-21 16:57:432192 ASSERT_EQ(3u, request_order.size());
[email protected]2431756e2010-09-29 20:26:132193 EXPECT_EQ(&req1, request_order[0]);
2194 EXPECT_EQ(&req2, request_order[1]);
2195 EXPECT_EQ(&req3, request_order[2]);
Matt Menkec6b3edf72019-03-19 17:00:392196 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]5fc08e32009-07-15 17:09:572197}
2198
2199// The requests are not coupled to the jobs. So, the requests should finish in
2200// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:292201TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:532202 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:572203 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:322204 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:572205
[email protected]2431756e2010-09-29 20:26:132206 std::vector<TestSocketRequest*> request_order;
2207 size_t completion_count; // unused
2208 TestSocketRequest req1(&request_order, &completion_count);
Matt Menke28ac03e2019-02-25 22:25:502209 int rv = req1.handle()->Init(
Matt Menkef09e64c2019-04-23 22:16:282210 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502211 ClientSocketPool::RespectLimits::ENABLED, req1.callback(),
2212 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012213 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:572214
[email protected]2431756e2010-09-29 20:26:132215 TestSocketRequest req2(&request_order, &completion_count);
Matt Menke28ac03e2019-02-25 22:25:502216 rv = req2.handle()->Init(
Matt Menkef09e64c2019-04-23 22:16:282217 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502218 ClientSocketPool::RespectLimits::ENABLED, req2.callback(),
2219 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012220 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:572221
2222 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:322223 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:572224
[email protected]2431756e2010-09-29 20:26:132225 TestSocketRequest req3(&request_order, &completion_count);
Matt Menke28ac03e2019-02-25 22:25:502226 rv = req3.handle()->Init(
Matt Menkef09e64c2019-04-23 22:16:282227 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502228 ClientSocketPool::RespectLimits::ENABLED, req3.callback(),
2229 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012230 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:572231
robpercival214763f2016-07-01 23:27:012232 EXPECT_THAT(req1.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
2233 EXPECT_THAT(req2.WaitForResult(), IsOk());
2234 EXPECT_THAT(req3.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]5fc08e32009-07-15 17:09:572235
Raul Tambre8335a6d2019-02-21 16:57:432236 ASSERT_EQ(3u, request_order.size());
[email protected]2431756e2010-09-29 20:26:132237 EXPECT_EQ(&req1, request_order[0]);
2238 EXPECT_EQ(&req2, request_order[1]);
2239 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:572240}
2241
[email protected]03b7c8c2013-07-20 04:38:552242// Test GetLoadState in the case there's only one socket request.
2243TEST_F(ClientSocketPoolBaseTest, LoadStateOneRequest) {
[email protected]211d21722009-07-22 15:48:532244 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]03b7c8c2013-07-20 04:38:552245 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
[email protected]5fc08e32009-07-15 17:09:572246
[email protected]2431756e2010-09-29 20:26:132247 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522248 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502249 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:282250 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502251 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2252 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012253 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552254 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:572255
[email protected]03b7c8c2013-07-20 04:38:552256 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2257 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
2258
2259 // No point in completing the connection, since ClientSocketHandles only
2260 // expect the LoadState to be checked while connecting.
2261}
2262
2263// Test GetLoadState in the case there are two socket requests.
2264TEST_F(ClientSocketPoolBaseTest, LoadStateTwoRequests) {
2265 CreatePool(2, 2);
2266 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2267
2268 ClientSocketHandle handle;
2269 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502270 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:282271 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502272 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2273 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012274 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
haavardm835c1d62015-04-22 08:18:002275 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_RESOLVING_HOST);
2276
2277 ClientSocketHandle handle2;
2278 TestCompletionCallback callback2;
Matt Menkef09e64c2019-04-23 22:16:282279 rv = handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2280 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502281 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2282 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012283 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
haavardm835c1d62015-04-22 08:18:002284 client_socket_factory_.SetJobLoadState(1, LOAD_STATE_RESOLVING_HOST);
2285
Matt Menke4b69f932019-03-04 16:20:012286 // Each handle should reflect the state of its own job.
haavardm835c1d62015-04-22 08:18:002287 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle.GetLoadState());
2288 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle2.GetLoadState());
2289
Matt Menke4b69f932019-03-04 16:20:012290 // Update the state of the first job.
haavardm835c1d62015-04-22 08:18:002291 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_CONNECTING);
2292
Matt Menke4b69f932019-03-04 16:20:012293 // Only the state of the first request should have changed.
haavardm835c1d62015-04-22 08:18:002294 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
haavardm835c1d62015-04-22 08:18:002295 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle2.GetLoadState());
Matt Menke4b69f932019-03-04 16:20:012296
2297 // Update the state of the second job.
2298 client_socket_factory_.SetJobLoadState(1, LOAD_STATE_SSL_HANDSHAKE);
2299
2300 // Only the state of the second request should have changed.
2301 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2302 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle2.GetLoadState());
2303
2304 // Second job connects and the first request gets the socket. The
2305 // second handle switches to the state of the remaining ConnectJob.
2306 client_socket_factory_.SignalJob(1);
2307 EXPECT_THAT(callback.WaitForResult(), IsOk());
2308 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
[email protected]03b7c8c2013-07-20 04:38:552309}
2310
2311// Test GetLoadState in the case the per-group limit is reached.
2312TEST_F(ClientSocketPoolBaseTest, LoadStateGroupLimit) {
2313 CreatePool(2, 1);
2314 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2315
2316 ClientSocketHandle handle;
2317 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502318 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:282319 TestGroupId("a"), params_, base::nullopt, MEDIUM, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502320 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2321 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012322 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552323 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2324
2325 // Request another socket from the same pool, buth with a higher priority.
2326 // The first request should now be stalled at the socket group limit.
2327 ClientSocketHandle handle2;
2328 TestCompletionCallback callback2;
Matt Menkef09e64c2019-04-23 22:16:282329 rv = handle2.Init(TestGroupId("a"), params_, base::nullopt, HIGHEST,
2330 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502331 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2332 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012333 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552334 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2335 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
2336
2337 // The first handle should remain stalled as the other socket goes through
2338 // the connect process.
2339
2340 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2341 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2342 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle2.GetLoadState());
2343
2344 client_socket_factory_.SignalJob(0);
robpercival214763f2016-07-01 23:27:012345 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]03b7c8c2013-07-20 04:38:552346 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2347
2348 // Closing the second socket should cause the stalled handle to finally get a
2349 // ConnectJob.
2350 handle2.socket()->Disconnect();
2351 handle2.Reset();
2352 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2353}
2354
2355// Test GetLoadState in the case the per-pool limit is reached.
2356TEST_F(ClientSocketPoolBaseTest, LoadStatePoolLimit) {
2357 CreatePool(2, 2);
2358 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2359
2360 ClientSocketHandle handle;
2361 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502362 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:282363 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502364 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2365 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012366 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552367
2368 // Request for socket from another pool.
2369 ClientSocketHandle handle2;
2370 TestCompletionCallback callback2;
Matt Menkef09e64c2019-04-23 22:16:282371 rv = handle2.Init(TestGroupId("b"), params_, base::nullopt, DEFAULT_PRIORITY,
2372 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502373 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2374 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012375 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552376
2377 // Request another socket from the first pool. Request should stall at the
2378 // socket pool limit.
2379 ClientSocketHandle handle3;
2380 TestCompletionCallback callback3;
Matt Menkef09e64c2019-04-23 22:16:282381 rv = handle3.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2382 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502383 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2384 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012385 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552386
2387 // The third handle should remain stalled as the other sockets in its group
2388 // goes through the connect process.
2389
2390 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2391 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2392
2393 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2394 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
2395 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2396
2397 client_socket_factory_.SignalJob(0);
robpercival214763f2016-07-01 23:27:012398 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]03b7c8c2013-07-20 04:38:552399 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2400
2401 // Closing a socket should allow the stalled handle to finally get a new
2402 // ConnectJob.
2403 handle.socket()->Disconnect();
2404 handle.Reset();
2405 EXPECT_EQ(LOAD_STATE_CONNECTING, handle3.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:572406}
2407
Matt Menkeb57663b32019-03-01 17:17:102408TEST_F(ClientSocketPoolBaseTest, CertError) {
[email protected]e772db3f2010-07-12 18:11:132409 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
Matt Menkeb57663b32019-03-01 17:17:102410 connect_job_factory_->set_job_type(TestConnectJob::kMockCertErrorJob);
[email protected]e772db3f2010-07-12 18:11:132411
[email protected]2431756e2010-09-29 20:26:132412 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522413 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502414 EXPECT_EQ(
Matt Menkeb57663b32019-03-01 17:17:102415 ERR_CERT_COMMON_NAME_INVALID,
Matt Menkef09e64c2019-04-23 22:16:282416 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2417 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2418 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2419 pool_.get(), NetLogWithSource()));
[email protected]2431756e2010-09-29 20:26:132420 EXPECT_TRUE(handle.is_initialized());
2421 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:132422}
2423
Matt Menkeb57663b32019-03-01 17:17:102424TEST_F(ClientSocketPoolBaseTest, AsyncCertError) {
[email protected]e772db3f2010-07-12 18:11:132425 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2426
Matt Menkeb57663b32019-03-01 17:17:102427 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingCertErrorJob);
[email protected]2431756e2010-09-29 20:26:132428 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522429 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502430 EXPECT_EQ(
2431 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:282432 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2433 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2434 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2435 pool_.get(), NetLogWithSource()));
Matt Menkec6b3edf72019-03-19 17:00:392436 EXPECT_EQ(LOAD_STATE_CONNECTING,
2437 pool_->GetLoadState(TestGroupId("a"), &handle));
Matt Menkeb57663b32019-03-01 17:17:102438 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CERT_COMMON_NAME_INVALID));
[email protected]2431756e2010-09-29 20:26:132439 EXPECT_TRUE(handle.is_initialized());
2440 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:132441}
2442
[email protected]e60e47a2010-07-14 03:37:182443TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) {
2444 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2445 connect_job_factory_->set_job_type(
2446 TestConnectJob::kMockAdditionalErrorStateJob);
2447
[email protected]2431756e2010-09-29 20:26:132448 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522449 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502450 EXPECT_EQ(
2451 ERR_CONNECTION_FAILED,
Matt Menkef09e64c2019-04-23 22:16:282452 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2453 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2454 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2455 pool_.get(), NetLogWithSource()));
[email protected]2431756e2010-09-29 20:26:132456 EXPECT_FALSE(handle.is_initialized());
2457 EXPECT_FALSE(handle.socket());
2458 EXPECT_TRUE(handle.is_ssl_error());
Matt Menke39b7c5a2019-04-10 19:47:512459 EXPECT_TRUE(handle.ssl_cert_request_info());
[email protected]e60e47a2010-07-14 03:37:182460}
2461
2462TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) {
2463 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2464
2465 connect_job_factory_->set_job_type(
2466 TestConnectJob::kMockPendingAdditionalErrorStateJob);
[email protected]2431756e2010-09-29 20:26:132467 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522468 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502469 EXPECT_EQ(
2470 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:282471 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2472 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2473 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2474 pool_.get(), NetLogWithSource()));
Matt Menkec6b3edf72019-03-19 17:00:392475 EXPECT_EQ(LOAD_STATE_CONNECTING,
2476 pool_->GetLoadState(TestGroupId("a"), &handle));
robpercival214763f2016-07-01 23:27:012477 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]2431756e2010-09-29 20:26:132478 EXPECT_FALSE(handle.is_initialized());
2479 EXPECT_FALSE(handle.socket());
2480 EXPECT_TRUE(handle.is_ssl_error());
Matt Menke39b7c5a2019-04-10 19:47:512481 EXPECT_TRUE(handle.ssl_cert_request_info());
[email protected]e60e47a2010-07-14 03:37:182482}
2483
martijn003cd612016-05-19 22:24:382484// Make sure we can reuse sockets.
2485TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSocketsReuse) {
[email protected]64770b7d2011-11-16 04:30:412486 CreatePoolWithIdleTimeouts(
2487 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
[email protected]e7b1c6d2c2012-05-05 00:54:032488 base::TimeDelta(), // Time out unused sockets immediately.
2489 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2490
2491 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2492
2493 ClientSocketHandle handle;
2494 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502495 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:282496 TestGroupId("a"), params_, base::nullopt, LOWEST, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502497 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2498 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012499 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
Matt Menkec6b3edf72019-03-19 17:00:392500 EXPECT_EQ(LOAD_STATE_CONNECTING,
2501 pool_->GetLoadState(TestGroupId("a"), &handle));
robpercival214763f2016-07-01 23:27:012502 ASSERT_THAT(callback.WaitForResult(), IsOk());
[email protected]e7b1c6d2c2012-05-05 00:54:032503
2504 // Use and release the socket.
Raul Tambre94493c652019-03-11 17:18:352505 EXPECT_EQ(1, handle.socket()->Write(nullptr, 1, CompletionOnceCallback(),
Ramin Halavati0a08cc82018-02-06 07:46:382506 TRAFFIC_ANNOTATION_FOR_TESTS));
[email protected]034df0f32013-01-07 23:17:482507 TestLoadTimingInfoConnectedNotReused(handle);
[email protected]e7b1c6d2c2012-05-05 00:54:032508 handle.Reset();
2509
2510 // Should now have one idle socket.
2511 ASSERT_EQ(1, pool_->IdleSocketCount());
2512
2513 // Request a new socket. This should reuse the old socket and complete
2514 // synchronously.
vishal.b62985ca92015-04-17 08:45:512515 BoundTestNetLog log;
Matt Menke28ac03e2019-02-25 22:25:502516 rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:282517 TestGroupId("a"), params_, base::nullopt, LOWEST, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502518 ClientSocketPool::RespectLimits::ENABLED, CompletionOnceCallback(),
2519 ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound());
robpercival214763f2016-07-01 23:27:012520 ASSERT_THAT(rv, IsOk());
[email protected]e7b1c6d2c2012-05-05 00:54:032521 EXPECT_TRUE(handle.is_reused());
[email protected]034df0f32013-01-07 23:17:482522 TestLoadTimingInfoConnectedReused(handle);
[email protected]e7b1c6d2c2012-05-05 00:54:032523
Matt Menke9fa17d52019-03-25 19:12:262524 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:392525 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menke9fa17d52019-03-25 19:12:262526 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
[email protected]e7b1c6d2c2012-05-05 00:54:032527
mmenke43758e62015-05-04 21:09:462528 TestNetLogEntry::List entries;
[email protected]e7b1c6d2c2012-05-05 00:54:032529 log.GetEntries(&entries);
Matt Menke9fa17d52019-03-25 19:12:262530 EXPECT_TRUE(LogContainsEvent(
2531 entries, 0, NetLogEventType::TCP_CLIENT_SOCKET_POOL_REQUESTED_SOCKET,
2532 NetLogEventPhase::NONE));
2533 EXPECT_TRUE(LogContainsBeginEvent(entries, 1, NetLogEventType::SOCKET_POOL));
[email protected]e7b1c6d2c2012-05-05 00:54:032534 EXPECT_TRUE(LogContainsEntryWithType(
Matt Menke9fa17d52019-03-25 19:12:262535 entries, 2, NetLogEventType::SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]e7b1c6d2c2012-05-05 00:54:032536}
2537
martijn003cd612016-05-19 22:24:382538// Make sure we cleanup old unused sockets.
Eric Romanb49715e2018-04-24 22:41:172539TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSocketsNoReuse) {
[email protected]e7b1c6d2c2012-05-05 00:54:032540 CreatePoolWithIdleTimeouts(
2541 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2542 base::TimeDelta(), // Time out unused sockets immediately
2543 base::TimeDelta()); // Time out used sockets immediately
[email protected]64770b7d2011-11-16 04:30:412544
2545 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2546
2547 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
2548
2549 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522550 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502551 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:282552 TestGroupId("a"), params_, base::nullopt, LOWEST, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502553 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2554 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012555 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
Matt Menkec6b3edf72019-03-19 17:00:392556 EXPECT_EQ(LOAD_STATE_CONNECTING,
2557 pool_->GetLoadState(TestGroupId("a"), &handle));
[email protected]64770b7d2011-11-16 04:30:412558
2559 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522560 TestCompletionCallback callback2;
Matt Menkef09e64c2019-04-23 22:16:282561 rv = handle2.Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
2562 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502563 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2564 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012565 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
Matt Menkec6b3edf72019-03-19 17:00:392566 EXPECT_EQ(LOAD_STATE_CONNECTING,
2567 pool_->GetLoadState(TestGroupId("a"), &handle2));
[email protected]64770b7d2011-11-16 04:30:412568
2569 // Cancel one of the requests. Wait for the other, which will get the first
2570 // job. Release the socket. Run the loop again to make sure the second
2571 // socket is sitting idle and the first one is released (since ReleaseSocket()
2572 // just posts a DoReleaseSocket() task).
2573
2574 handle.Reset();
robpercival214763f2016-07-01 23:27:012575 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]64770b7d2011-11-16 04:30:412576 // Use the socket.
Raul Tambre94493c652019-03-11 17:18:352577 EXPECT_EQ(1, handle2.socket()->Write(nullptr, 1, CompletionOnceCallback(),
Ramin Halavati0a08cc82018-02-06 07:46:382578 TRAFFIC_ANNOTATION_FOR_TESTS));
[email protected]64770b7d2011-11-16 04:30:412579 handle2.Reset();
2580
[email protected]e7b1c6d2c2012-05-05 00:54:032581 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
2582 // actually become pending until 2ms after they have been created. In order
2583 // to flush all tasks, we need to wait so that we know there are no
2584 // soon-to-be-pending tasks waiting.
Alex Clarke0def2092018-12-10 12:01:452585 FastForwardBy(base::TimeDelta::FromMilliseconds(10));
[email protected]64770b7d2011-11-16 04:30:412586
[email protected]e7b1c6d2c2012-05-05 00:54:032587 // Both sockets should now be idle.
[email protected]64770b7d2011-11-16 04:30:412588 ASSERT_EQ(2, pool_->IdleSocketCount());
2589
2590 // Request a new socket. This should cleanup the unused and timed out ones.
2591 // A new socket will be created rather than reusing the idle one.
vishal.b62985ca92015-04-17 08:45:512592 BoundTestNetLog log;
[email protected]6ecf2b92011-12-15 01:14:522593 TestCompletionCallback callback3;
Matt Menkef09e64c2019-04-23 22:16:282594 rv = handle.Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
2595 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502596 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
2597 pool_.get(), log.bound());
robpercival214763f2016-07-01 23:27:012598 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
2599 ASSERT_THAT(callback3.WaitForResult(), IsOk());
[email protected]64770b7d2011-11-16 04:30:412600 EXPECT_FALSE(handle.is_reused());
2601
[email protected]e7b1c6d2c2012-05-05 00:54:032602 // Make sure the idle socket is closed.
Matt Menke9fa17d52019-03-25 19:12:262603 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:392604 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menke9fa17d52019-03-25 19:12:262605 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
[email protected]64770b7d2011-11-16 04:30:412606
mmenke43758e62015-05-04 21:09:462607 TestNetLogEntry::List entries;
[email protected]64770b7d2011-11-16 04:30:412608 log.GetEntries(&entries);
2609 EXPECT_FALSE(LogContainsEntryWithType(
mikecirone8b85c432016-09-08 19:11:002610 entries, 1, NetLogEventType::SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]64770b7d2011-11-16 04:30:412611}
2612
[email protected]2041cf342010-02-19 03:15:592613// Make sure that we process all pending requests even when we're stalling
[email protected]4f2abec2010-02-03 18:10:162614// because of multiple releasing disconnected sockets.
2615TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
2616 CreatePoolWithIdleTimeouts(
2617 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2618 base::TimeDelta(), // Time out unused sockets immediately.
2619 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2620
2621 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2622
2623 // Startup 4 connect jobs. Two of them will be pending.
2624
[email protected]2431756e2010-09-29 20:26:132625 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522626 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502627 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:282628 TestGroupId("a"), params_, base::nullopt, LOWEST, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502629 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2630 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012631 EXPECT_THAT(rv, IsOk());
[email protected]4f2abec2010-02-03 18:10:162632
[email protected]2431756e2010-09-29 20:26:132633 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522634 TestCompletionCallback callback2;
Matt Menkef09e64c2019-04-23 22:16:282635 rv = handle2.Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
2636 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502637 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2638 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012639 EXPECT_THAT(rv, IsOk());
[email protected]4f2abec2010-02-03 18:10:162640
[email protected]2431756e2010-09-29 20:26:132641 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:522642 TestCompletionCallback callback3;
Matt Menkef09e64c2019-04-23 22:16:282643 rv = handle3.Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
2644 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502645 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
2646 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012647 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4f2abec2010-02-03 18:10:162648
[email protected]2431756e2010-09-29 20:26:132649 ClientSocketHandle handle4;
[email protected]6ecf2b92011-12-15 01:14:522650 TestCompletionCallback callback4;
Matt Menkef09e64c2019-04-23 22:16:282651 rv = handle4.Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
2652 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502653 callback4.callback(), ClientSocketPool::ProxyAuthCallback(),
2654 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012655 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4f2abec2010-02-03 18:10:162656
2657 // Release two disconnected sockets.
2658
[email protected]2431756e2010-09-29 20:26:132659 handle.socket()->Disconnect();
2660 handle.Reset();
2661 handle2.socket()->Disconnect();
2662 handle2.Reset();
[email protected]4f2abec2010-02-03 18:10:162663
robpercival214763f2016-07-01 23:27:012664 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132665 EXPECT_FALSE(handle3.is_reused());
robpercival214763f2016-07-01 23:27:012666 EXPECT_THAT(callback4.WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132667 EXPECT_FALSE(handle4.is_reused());
[email protected]4f2abec2010-02-03 18:10:162668}
2669
[email protected]d7027bb2010-05-10 18:58:542670// Regression test for http://crbug.com/42267.
2671// When DoReleaseSocket() is processed for one socket, it is blocked because the
2672// other stalled groups all have releasing sockets, so no progress can be made.
2673TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
2674 CreatePoolWithIdleTimeouts(
2675 4 /* socket limit */, 4 /* socket limit per group */,
2676 base::TimeDelta(), // Time out unused sockets immediately.
2677 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2678
2679 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2680
2681 // Max out the socket limit with 2 per group.
2682
[email protected]2431756e2010-09-29 20:26:132683 ClientSocketHandle handle_a[4];
[email protected]6ecf2b92011-12-15 01:14:522684 TestCompletionCallback callback_a[4];
[email protected]2431756e2010-09-29 20:26:132685 ClientSocketHandle handle_b[4];
[email protected]6ecf2b92011-12-15 01:14:522686 TestCompletionCallback callback_b[4];
[email protected]d7027bb2010-05-10 18:58:542687
2688 for (int i = 0; i < 2; ++i) {
Matt Menkef09e64c2019-04-23 22:16:282689 EXPECT_EQ(OK, handle_a[i].Init(TestGroupId("a"), params_, base::nullopt,
2690 LOWEST, SocketTag(),
2691 ClientSocketPool::RespectLimits::ENABLED,
2692 callback_a[i].callback(),
2693 ClientSocketPool::ProxyAuthCallback(),
2694 pool_.get(), NetLogWithSource()));
2695 EXPECT_EQ(OK, handle_b[i].Init(TestGroupId("b"), params_, base::nullopt,
2696 LOWEST, SocketTag(),
2697 ClientSocketPool::RespectLimits::ENABLED,
2698 callback_b[i].callback(),
2699 ClientSocketPool::ProxyAuthCallback(),
2700 pool_.get(), NetLogWithSource()));
[email protected]d7027bb2010-05-10 18:58:542701 }
[email protected]b89f7e42010-05-20 20:37:002702
[email protected]d7027bb2010-05-10 18:58:542703 // Make 4 pending requests, 2 per group.
2704
2705 for (int i = 2; i < 4; ++i) {
Matt Menkef09e64c2019-04-23 22:16:282706 EXPECT_EQ(
2707 ERR_IO_PENDING,
2708 handle_a[i].Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
2709 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2710 callback_a[i].callback(),
2711 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2712 NetLogWithSource()));
2713 EXPECT_EQ(
2714 ERR_IO_PENDING,
2715 handle_b[i].Init(TestGroupId("b"), params_, base::nullopt, LOWEST,
2716 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2717 callback_b[i].callback(),
2718 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2719 NetLogWithSource()));
[email protected]d7027bb2010-05-10 18:58:542720 }
2721
2722 // Release b's socket first. The order is important, because in
2723 // DoReleaseSocket(), we'll process b's released socket, and since both b and
2724 // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
2725 // first, which has a releasing socket, so it refuses to start up another
2726 // ConnectJob. So, we used to infinite loop on this.
[email protected]2431756e2010-09-29 20:26:132727 handle_b[0].socket()->Disconnect();
2728 handle_b[0].Reset();
2729 handle_a[0].socket()->Disconnect();
2730 handle_a[0].Reset();
[email protected]d7027bb2010-05-10 18:58:542731
2732 // Used to get stuck here.
fdoray5eeb7642016-06-22 16:11:282733 base::RunLoop().RunUntilIdle();
[email protected]d7027bb2010-05-10 18:58:542734
[email protected]2431756e2010-09-29 20:26:132735 handle_b[1].socket()->Disconnect();
2736 handle_b[1].Reset();
2737 handle_a[1].socket()->Disconnect();
2738 handle_a[1].Reset();
[email protected]d7027bb2010-05-10 18:58:542739
2740 for (int i = 2; i < 4; ++i) {
robpercival214763f2016-07-01 23:27:012741 EXPECT_THAT(callback_b[i].WaitForResult(), IsOk());
2742 EXPECT_THAT(callback_a[i].WaitForResult(), IsOk());
[email protected]d7027bb2010-05-10 18:58:542743 }
2744}
2745
[email protected]fd4fe0b2010-02-08 23:02:152746TEST_F(ClientSocketPoolBaseTest,
2747 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
2748 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2749
2750 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2751
Matt Menkec6b3edf72019-03-19 17:00:392752 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2753 IsError(ERR_IO_PENDING));
2754 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2755 IsError(ERR_IO_PENDING));
2756 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2757 IsError(ERR_IO_PENDING));
2758 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2759 IsError(ERR_IO_PENDING));
[email protected]fd4fe0b2010-02-08 23:02:152760
robpercival214763f2016-07-01 23:27:012761 EXPECT_THAT((*requests())[0]->WaitForResult(), IsOk());
2762 EXPECT_THAT((*requests())[1]->WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132763 EXPECT_EQ(2u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152764
2765 // Releases one connection.
[email protected]2431756e2010-09-29 20:26:132766 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
robpercival214763f2016-07-01 23:27:012767 EXPECT_THAT((*requests())[2]->WaitForResult(), IsOk());
[email protected]fd4fe0b2010-02-08 23:02:152768
[email protected]2431756e2010-09-29 20:26:132769 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
robpercival214763f2016-07-01 23:27:012770 EXPECT_THAT((*requests())[3]->WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132771 EXPECT_EQ(4u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152772
2773 EXPECT_EQ(1, GetOrderOfRequest(1));
2774 EXPECT_EQ(2, GetOrderOfRequest(2));
2775 EXPECT_EQ(3, GetOrderOfRequest(3));
2776 EXPECT_EQ(4, GetOrderOfRequest(4));
2777
2778 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:132779 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(5));
[email protected]fd4fe0b2010-02-08 23:02:152780}
2781
[email protected]6ecf2b92011-12-15 01:14:522782class TestReleasingSocketRequest : public TestCompletionCallbackBase {
[email protected]4f1e4982010-03-02 18:31:042783 public:
Matt Menke9fa17d52019-03-25 19:12:262784 TestReleasingSocketRequest(TransportClientSocketPool* pool,
[email protected]2431756e2010-09-29 20:26:132785 int expected_result,
[email protected]e60e47a2010-07-14 03:37:182786 bool reset_releasing_handle)
2787 : pool_(pool),
2788 expected_result_(expected_result),
Bence Béky8ddc2492018-06-13 01:02:042789 reset_releasing_handle_(reset_releasing_handle) {}
[email protected]6ecf2b92011-12-15 01:14:522790
Chris Watkins7a41d3552017-12-01 02:13:272791 ~TestReleasingSocketRequest() override = default;
[email protected]4f1e4982010-03-02 18:31:042792
2793 ClientSocketHandle* handle() { return &handle_; }
2794
Bence Béky8ddc2492018-06-13 01:02:042795 CompletionOnceCallback callback() {
2796 return base::BindOnce(&TestReleasingSocketRequest::OnComplete,
2797 base::Unretained(this));
2798 }
[email protected]4f1e4982010-03-02 18:31:042799
2800 private:
[email protected]6ecf2b92011-12-15 01:14:522801 void OnComplete(int result) {
2802 SetResult(result);
2803 if (reset_releasing_handle_)
2804 handle_.Reset();
2805
Matt Menkec6b3edf72019-03-19 17:00:392806 EXPECT_EQ(
2807 expected_result_,
Matt Menke870e19ab2019-04-23 16:23:032808 handle2_.Init(
2809 TestGroupId("a"),
2810 ClientSocketPool::SocketParams::CreateForHttpForTesting(),
Matt Menkef09e64c2019-04-23 22:16:282811 base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menke870e19ab2019-04-23 16:23:032812 ClientSocketPool::RespectLimits::ENABLED, CompletionOnceCallback(),
2813 ClientSocketPool::ProxyAuthCallback(), pool_, NetLogWithSource()));
[email protected]6ecf2b92011-12-15 01:14:522814 }
2815
Matt Menke9fa17d52019-03-25 19:12:262816 TransportClientSocketPool* const pool_;
[email protected]e60e47a2010-07-14 03:37:182817 int expected_result_;
2818 bool reset_releasing_handle_;
[email protected]4f1e4982010-03-02 18:31:042819 ClientSocketHandle handle_;
2820 ClientSocketHandle handle2_;
[email protected]4f1e4982010-03-02 18:31:042821};
2822
[email protected]e60e47a2010-07-14 03:37:182823
2824TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) {
2825 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2826
Matt Menkec6b3edf72019-03-19 17:00:392827 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
2828 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
2829 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
[email protected]e60e47a2010-07-14 03:37:182830
[email protected]2431756e2010-09-29 20:26:132831 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]e60e47a2010-07-14 03:37:182832 client_socket_factory_.allocation_count());
2833
2834 connect_job_factory_->set_job_type(
2835 TestConnectJob::kMockPendingAdditionalErrorStateJob);
2836 TestReleasingSocketRequest req(pool_.get(), OK, false);
Matt Menkef09e64c2019-04-23 22:16:282837 EXPECT_EQ(ERR_IO_PENDING,
2838 req.handle()->Init(
2839 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2840 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2841 req.callback(), ClientSocketPool::ProxyAuthCallback(),
2842 pool_.get(), NetLogWithSource()));
[email protected]e60e47a2010-07-14 03:37:182843 // The next job should complete synchronously
2844 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2845
robpercival214763f2016-07-01 23:27:012846 EXPECT_THAT(req.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:182847 EXPECT_FALSE(req.handle()->is_initialized());
2848 EXPECT_FALSE(req.handle()->socket());
2849 EXPECT_TRUE(req.handle()->is_ssl_error());
Matt Menke39b7c5a2019-04-10 19:47:512850 EXPECT_TRUE(req.handle()->ssl_cert_request_info());
[email protected]e60e47a2010-07-14 03:37:182851}
2852
[email protected]b6501d3d2010-06-03 23:53:342853// http://crbug.com/44724 regression test.
2854// We start releasing the pool when we flush on network change. When that
2855// happens, the only active references are in the ClientSocketHandles. When a
2856// ConnectJob completes and calls back into the last ClientSocketHandle, that
2857// callback can release the last reference and delete the pool. After the
2858// callback finishes, we go back to the stack frame within the now-deleted pool.
2859// Executing any code that refers to members of the now-deleted pool can cause
2860// crashes.
2861TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
2862 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2863 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2864
2865 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522866 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502867 EXPECT_EQ(
2868 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:282869 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2870 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2871 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2872 pool_.get(), NetLogWithSource()));
[email protected]b6501d3d2010-06-03 23:53:342873
[email protected]7af985a2012-12-14 22:40:422874 pool_->FlushWithError(ERR_NETWORK_CHANGED);
[email protected]b6501d3d2010-06-03 23:53:342875
2876 // We'll call back into this now.
2877 callback.WaitForResult();
2878}
2879
[email protected]a7e38572010-06-07 18:22:242880TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
2881 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2882 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2883
2884 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522885 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502886 EXPECT_EQ(
2887 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:282888 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2889 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2890 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2891 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:012892 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]a7e38572010-06-07 18:22:242893 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2894
[email protected]7af985a2012-12-14 22:40:422895 pool_->FlushWithError(ERR_NETWORK_CHANGED);
[email protected]a7e38572010-06-07 18:22:242896
2897 handle.Reset();
fdoray5eeb7642016-06-22 16:11:282898 base::RunLoop().RunUntilIdle();
[email protected]a7e38572010-06-07 18:22:242899
Matt Menke28ac03e2019-02-25 22:25:502900 EXPECT_EQ(
2901 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:282902 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2903 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2904 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2905 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:012906 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]a7e38572010-06-07 18:22:242907 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2908}
2909
[email protected]6ecf2b92011-12-15 01:14:522910class ConnectWithinCallback : public TestCompletionCallbackBase {
[email protected]06f92462010-08-31 19:24:142911 public:
Matt Menke9fa17d52019-03-25 19:12:262912 ConnectWithinCallback(
2913 const ClientSocketPool::GroupId& group_id,
Matt Menke84d11e562019-03-27 00:11:192914 const scoped_refptr<ClientSocketPool::SocketParams>& params,
Matt Menke9fa17d52019-03-25 19:12:262915 TransportClientSocketPool* pool)
Matt Menkec6b3edf72019-03-19 17:00:392916 : group_id_(group_id), params_(params), pool_(pool) {}
[email protected]06f92462010-08-31 19:24:142917
Chris Watkins7a41d3552017-12-01 02:13:272918 ~ConnectWithinCallback() override = default;
[email protected]06f92462010-08-31 19:24:142919
2920 int WaitForNestedResult() {
2921 return nested_callback_.WaitForResult();
2922 }
2923
Bence Béky8ddc2492018-06-13 01:02:042924 CompletionOnceCallback callback() {
2925 return base::BindOnce(&ConnectWithinCallback::OnComplete,
2926 base::Unretained(this));
2927 }
[email protected]6ecf2b92011-12-15 01:14:522928
[email protected]06f92462010-08-31 19:24:142929 private:
[email protected]6ecf2b92011-12-15 01:14:522930 void OnComplete(int result) {
2931 SetResult(result);
Matt Menkef09e64c2019-04-23 22:16:282932 EXPECT_EQ(
2933 ERR_IO_PENDING,
2934 handle_.Init(group_id_, params_, base::nullopt, DEFAULT_PRIORITY,
2935 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2936 nested_callback_.callback(),
2937 ClientSocketPool::ProxyAuthCallback(), pool_,
2938 NetLogWithSource()));
[email protected]6ecf2b92011-12-15 01:14:522939 }
2940
Matt Menkec6b3edf72019-03-19 17:00:392941 const ClientSocketPool::GroupId group_id_;
Matt Menke84d11e562019-03-27 00:11:192942 const scoped_refptr<ClientSocketPool::SocketParams> params_;
Matt Menke9fa17d52019-03-25 19:12:262943 TransportClientSocketPool* const pool_;
[email protected]06f92462010-08-31 19:24:142944 ClientSocketHandle handle_;
[email protected]6ecf2b92011-12-15 01:14:522945 TestCompletionCallback nested_callback_;
2946
2947 DISALLOW_COPY_AND_ASSIGN(ConnectWithinCallback);
[email protected]06f92462010-08-31 19:24:142948};
2949
2950TEST_F(ClientSocketPoolBaseTest, AbortAllRequestsOnFlush) {
2951 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2952
2953 // First job will be waiting until it gets aborted.
2954 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2955
2956 ClientSocketHandle handle;
Matt Menkec6b3edf72019-03-19 17:00:392957 ConnectWithinCallback callback(TestGroupId("a"), params_, pool_.get());
Matt Menke28ac03e2019-02-25 22:25:502958 EXPECT_EQ(
2959 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:282960 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2961 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2962 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2963 pool_.get(), NetLogWithSource()));
[email protected]06f92462010-08-31 19:24:142964
2965 // Second job will be started during the first callback, and will
2966 // asynchronously complete with OK.
2967 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]7af985a2012-12-14 22:40:422968 pool_->FlushWithError(ERR_NETWORK_CHANGED);
robpercival214763f2016-07-01 23:27:012969 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NETWORK_CHANGED));
2970 EXPECT_THAT(callback.WaitForNestedResult(), IsOk());
[email protected]06f92462010-08-31 19:24:142971}
2972
Matt Menke141b87f22019-01-30 02:43:032973TEST_F(ClientSocketPoolBaseTest, BackupSocketWaitsForHostResolution) {
Matt Menke9fa17d52019-03-25 19:12:262974 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets,
2975 true /* enable_backup_connect_jobs */);
Matt Menke141b87f22019-01-30 02:43:032976
2977 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2978 ClientSocketHandle handle;
2979 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502980 EXPECT_EQ(
2981 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:282982 handle.Init(TestGroupId("bar"), params_, base::nullopt, DEFAULT_PRIORITY,
2983 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2984 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2985 pool_.get(), NetLogWithSource()));
Matt Menke141b87f22019-01-30 02:43:032986 // The backup timer fires but doesn't start a new ConnectJob while resolving
2987 // the hostname.
2988 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_RESOLVING_HOST);
2989 FastForwardBy(base::TimeDelta::FromMilliseconds(
2990 ClientSocketPool::kMaxConnectRetryIntervalMs * 100));
2991 EXPECT_EQ(1, client_socket_factory_.allocation_count());
2992
2993 // Once the ConnectJob has finished resolving the hostname, the backup timer
2994 // will create a ConnectJob when it fires.
2995 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_CONNECTING);
2996 FastForwardBy(base::TimeDelta::FromMilliseconds(
2997 ClientSocketPool::kMaxConnectRetryIntervalMs));
2998 EXPECT_EQ(2, client_socket_factory_.allocation_count());
2999}
3000
3001// Test that no backup socket is created when a ConnectJob connects before it
3002// completes.
3003TEST_F(ClientSocketPoolBaseTest, NoBackupSocketWhenConnected) {
Matt Menke9fa17d52019-03-25 19:12:263004 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets,
3005 true /* enable_backup_connect_jobs */);
Matt Menke141b87f22019-01-30 02:43:033006
3007 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3008 ClientSocketHandle handle;
3009 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:503010 EXPECT_EQ(
3011 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283012 handle.Init(TestGroupId("bar"), params_, base::nullopt, DEFAULT_PRIORITY,
3013 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3014 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3015 pool_.get(), NetLogWithSource()));
Matt Menke141b87f22019-01-30 02:43:033016 // The backup timer fires but doesn't start a new ConnectJob while resolving
3017 // the hostname.
3018 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_RESOLVING_HOST);
3019 FastForwardBy(base::TimeDelta::FromMilliseconds(
3020 ClientSocketPool::kMaxConnectRetryIntervalMs * 100));
3021 EXPECT_EQ(1, client_socket_factory_.allocation_count());
3022
3023 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
3024 client_socket_factory_.SetJobHasEstablishedConnection(0);
3025 FastForwardBy(base::TimeDelta::FromMilliseconds(
3026 ClientSocketPool::kMaxConnectRetryIntervalMs * 100));
3027 EXPECT_EQ(1, client_socket_factory_.allocation_count());
3028}
3029
[email protected]25eea382010-07-10 23:55:263030// Cancel a pending socket request while we're at max sockets,
3031// and verify that the backup socket firing doesn't cause a crash.
3032TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
3033 // Max 4 sockets globally, max 4 sockets per group.
Matt Menke9fa17d52019-03-25 19:12:263034 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets,
3035 true /* enable_backup_connect_jobs */);
[email protected]25eea382010-07-10 23:55:263036
[email protected]4baaf9d2010-08-31 15:15:443037 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
3038 // timer.
[email protected]25eea382010-07-10 23:55:263039 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3040 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:523041 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:503042 EXPECT_EQ(
3043 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283044 handle.Init(TestGroupId("bar"), params_, base::nullopt, DEFAULT_PRIORITY,
3045 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3046 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3047 pool_.get(), NetLogWithSource()));
[email protected]25eea382010-07-10 23:55:263048
3049 // Start (MaxSockets - 1) connected sockets to reach max sockets.
3050 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3051 ClientSocketHandle handles[kDefaultMaxSockets];
3052 for (int i = 1; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:523053 TestCompletionCallback callback;
Matt Menkef09e64c2019-04-23 22:16:283054 EXPECT_EQ(OK, handles[i].Init(TestGroupId("bar"), params_, base::nullopt,
3055 DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203056 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503057 callback.callback(),
3058 ClientSocketPool::ProxyAuthCallback(),
3059 pool_.get(), NetLogWithSource()));
[email protected]25eea382010-07-10 23:55:263060 }
3061
fdoray5eeb7642016-06-22 16:11:283062 base::RunLoop().RunUntilIdle();
[email protected]25eea382010-07-10 23:55:263063
3064 // Cancel the pending request.
3065 handle.Reset();
3066
3067 // Wait for the backup timer to fire (add some slop to ensure it fires)
Alex Clarke0def2092018-12-10 12:01:453068 FastForwardBy(base::TimeDelta::FromMilliseconds(
[email protected]26b9973962012-01-28 00:57:003069 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]25eea382010-07-10 23:55:263070
[email protected]25eea382010-07-10 23:55:263071 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
3072}
3073
[email protected]3f00be82010-09-27 19:50:023074TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterCancelingAllRequests) {
Matt Menke9fa17d52019-03-25 19:12:263075 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets,
3076 true /* enable_backup_connect_jobs */);
[email protected]4baaf9d2010-08-31 15:15:443077
3078 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
3079 // timer.
3080 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3081 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:523082 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:503083 EXPECT_EQ(
3084 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283085 handle.Init(TestGroupId("bar"), params_, base::nullopt, DEFAULT_PRIORITY,
3086 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3087 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3088 pool_.get(), NetLogWithSource()));
Matt Menke9fa17d52019-03-25 19:12:263089 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("bar")));
3090 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("bar")));
3091 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3092 TestGroupId("bar")));
3093 EXPECT_EQ(
3094 0u, pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("bar")));
[email protected]4baaf9d2010-08-31 15:15:443095
3096 // Cancel the socket request. This should cancel the backup timer. Wait for
3097 // the backup time to see if it indeed got canceled.
3098 handle.Reset();
3099 // Wait for the backup timer to fire (add some slop to ensure it fires)
Alex Clarke0def2092018-12-10 12:01:453100 FastForwardBy(base::TimeDelta::FromMilliseconds(
[email protected]26b9973962012-01-28 00:57:003101 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
Matt Menke9fa17d52019-03-25 19:12:263102 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("bar")));
3103 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("bar")));
[email protected]4baaf9d2010-08-31 15:15:443104}
3105
[email protected]3f00be82010-09-27 19:50:023106TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterFinishingAllRequests) {
Matt Menke9fa17d52019-03-25 19:12:263107 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets,
3108 true /* enable_backup_connect_jobs */);
[email protected]3f00be82010-09-27 19:50:023109
3110 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
3111 // timer.
3112 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3113 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:523114 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:503115 EXPECT_EQ(
3116 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283117 handle.Init(TestGroupId("bar"), params_, base::nullopt, DEFAULT_PRIORITY,
3118 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3119 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3120 pool_.get(), NetLogWithSource()));
[email protected]3f00be82010-09-27 19:50:023121 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3122 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523123 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203124 EXPECT_EQ(
3125 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283126 handle2.Init(TestGroupId("bar"), params_, base::nullopt, DEFAULT_PRIORITY,
3127 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503128 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3129 pool_.get(), NetLogWithSource()));
Matt Menke9fa17d52019-03-25 19:12:263130 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("bar")));
3131 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("bar")));
[email protected]3f00be82010-09-27 19:50:023132
3133 // Cancel request 1 and then complete request 2. With the requests finished,
3134 // the backup timer should be cancelled.
3135 handle.Reset();
robpercival214763f2016-07-01 23:27:013136 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]3f00be82010-09-27 19:50:023137 // Wait for the backup timer to fire (add some slop to ensure it fires)
Alex Clarke0def2092018-12-10 12:01:453138 FastForwardBy(base::TimeDelta::FromMilliseconds(
[email protected]26b9973962012-01-28 00:57:003139 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]3f00be82010-09-27 19:50:023140}
3141
[email protected]eb5a99382010-07-11 03:18:263142// Test delayed socket binding for the case where we have two connects,
3143// and while one is waiting on a connect, the other frees up.
3144// The socket waiting on a connect should switch immediately to the freed
3145// up socket.
3146TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
3147 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3148 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3149
3150 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523151 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:503152 EXPECT_EQ(
3153 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283154 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3155 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503156 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3157 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013158 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:263159
3160 // No idle sockets, no pending jobs.
3161 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menke9fa17d52019-03-25 19:12:263162 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263163
3164 // Create a second socket to the same host, but this one will wait.
3165 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3166 ClientSocketHandle handle2;
Matt Menke28ac03e2019-02-25 22:25:503167 EXPECT_EQ(
3168 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283169 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3170 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503171 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3172 pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:263173 // No idle sockets, and one connecting job.
3174 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menke9fa17d52019-03-25 19:12:263175 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263176
3177 // Return the first handle to the pool. This will initiate the delayed
3178 // binding.
3179 handle1.Reset();
3180
fdoray5eeb7642016-06-22 16:11:283181 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263182
3183 // Still no idle sockets, still one pending connect job.
3184 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menke9fa17d52019-03-25 19:12:263185 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263186
3187 // The second socket connected, even though it was a Waiting Job.
robpercival214763f2016-07-01 23:27:013188 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:263189
3190 // And we can see there is still one job waiting.
Matt Menke9fa17d52019-03-25 19:12:263191 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263192
3193 // Finally, signal the waiting Connect.
3194 client_socket_factory_.SignalJobs();
Matt Menke9fa17d52019-03-25 19:12:263195 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263196
fdoray5eeb7642016-06-22 16:11:283197 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263198}
3199
3200// Test delayed socket binding when a group is at capacity and one
3201// of the group's sockets frees up.
3202TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
3203 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3204 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3205
3206 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523207 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:503208 EXPECT_EQ(
3209 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283210 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3211 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503212 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3213 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013214 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:263215
3216 // No idle sockets, no pending jobs.
3217 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menke9fa17d52019-03-25 19:12:263218 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263219
3220 // Create a second socket to the same host, but this one will wait.
3221 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3222 ClientSocketHandle handle2;
Matt Menke28ac03e2019-02-25 22:25:503223 EXPECT_EQ(
3224 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283225 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3226 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503227 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3228 pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:263229 // No idle sockets, and one connecting job.
3230 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menke9fa17d52019-03-25 19:12:263231 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263232
3233 // Return the first handle to the pool. This will initiate the delayed
3234 // binding.
3235 handle1.Reset();
3236
fdoray5eeb7642016-06-22 16:11:283237 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263238
3239 // Still no idle sockets, still one pending connect job.
3240 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menke9fa17d52019-03-25 19:12:263241 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263242
3243 // The second socket connected, even though it was a Waiting Job.
robpercival214763f2016-07-01 23:27:013244 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:263245
3246 // And we can see there is still one job waiting.
Matt Menke9fa17d52019-03-25 19:12:263247 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263248
3249 // Finally, signal the waiting Connect.
3250 client_socket_factory_.SignalJobs();
Matt Menke9fa17d52019-03-25 19:12:263251 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263252
fdoray5eeb7642016-06-22 16:11:283253 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263254}
3255
3256// Test out the case where we have one socket connected, one
3257// connecting, when the first socket finishes and goes idle.
[email protected]2abfe90a2010-08-25 17:49:513258// Although the second connection is pending, the second request
[email protected]eb5a99382010-07-11 03:18:263259// should complete, by taking the first socket's idle socket.
3260TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
3261 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3262 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3263
3264 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523265 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:503266 EXPECT_EQ(
3267 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283268 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3269 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503270 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3271 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013272 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:263273
3274 // No idle sockets, no pending jobs.
3275 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menke9fa17d52019-03-25 19:12:263276 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263277
3278 // Create a second socket to the same host, but this one will wait.
3279 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3280 ClientSocketHandle handle2;
Matt Menke28ac03e2019-02-25 22:25:503281 EXPECT_EQ(
3282 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283283 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3284 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503285 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3286 pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:263287 // No idle sockets, and one connecting job.
3288 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menke9fa17d52019-03-25 19:12:263289 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263290
3291 // Return the first handle to the pool. This will initiate the delayed
3292 // binding.
3293 handle1.Reset();
3294
fdoray5eeb7642016-06-22 16:11:283295 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263296
3297 // Still no idle sockets, still one pending connect job.
3298 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menke9fa17d52019-03-25 19:12:263299 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263300
3301 // The second socket connected, even though it was a Waiting Job.
robpercival214763f2016-07-01 23:27:013302 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:263303
3304 // And we can see there is still one job waiting.
Matt Menke9fa17d52019-03-25 19:12:263305 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263306
3307 // Finally, signal the waiting Connect.
3308 client_socket_factory_.SignalJobs();
Matt Menke9fa17d52019-03-25 19:12:263309 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263310
fdoray5eeb7642016-06-22 16:11:283311 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263312}
3313
[email protected]2abfe90a2010-08-25 17:49:513314// Cover the case where on an available socket slot, we have one pending
3315// request that completes synchronously, thereby making the Group empty.
3316TEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) {
3317 const int kUnlimitedSockets = 100;
3318 const int kOneSocketPerGroup = 1;
3319 CreatePool(kUnlimitedSockets, kOneSocketPerGroup);
3320
3321 // Make the first request asynchronous fail.
3322 // This will free up a socket slot later.
3323 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
3324
3325 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523326 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203327 EXPECT_EQ(
3328 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283329 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3330 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503331 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3332 pool_.get(), NetLogWithSource()));
Matt Menke9fa17d52019-03-25 19:12:263333 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]2abfe90a2010-08-25 17:49:513334
3335 // Make the second request synchronously fail. This should make the Group
3336 // empty.
3337 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3338 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523339 TestCompletionCallback callback2;
[email protected]2abfe90a2010-08-25 17:49:513340 // It'll be ERR_IO_PENDING now, but the TestConnectJob will synchronously fail
3341 // when created.
tfarina428341112016-09-22 13:38:203342 EXPECT_EQ(
3343 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283344 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3345 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503346 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3347 pool_.get(), NetLogWithSource()));
[email protected]2abfe90a2010-08-25 17:49:513348
Matt Menke9fa17d52019-03-25 19:12:263349 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]2abfe90a2010-08-25 17:49:513350
robpercival214763f2016-07-01 23:27:013351 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
3352 EXPECT_THAT(callback2.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
Matt Menke9fa17d52019-03-25 19:12:263353 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
[email protected]2abfe90a2010-08-25 17:49:513354}
3355
[email protected]e1b54dc2010-10-06 21:27:223356TEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) {
3357 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3358
3359 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3360
3361 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523362 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203363 EXPECT_EQ(
3364 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283365 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3366 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503367 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3368 pool_.get(), NetLogWithSource()));
[email protected]e1b54dc2010-10-06 21:27:223369
3370 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523371 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203372 EXPECT_EQ(
3373 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283374 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3375 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503376 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3377 pool_.get(), NetLogWithSource()));
[email protected]e1b54dc2010-10-06 21:27:223378 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:523379 TestCompletionCallback callback3;
tfarina428341112016-09-22 13:38:203380 EXPECT_EQ(
3381 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283382 handle3.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3383 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503384 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
3385 pool_.get(), NetLogWithSource()));
[email protected]e1b54dc2010-10-06 21:27:223386
robpercival214763f2016-07-01 23:27:013387 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3388 EXPECT_THAT(callback2.WaitForResult(), IsOk());
3389 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]e1b54dc2010-10-06 21:27:223390
3391 // Use the socket.
Raul Tambre94493c652019-03-11 17:18:353392 EXPECT_EQ(1, handle1.socket()->Write(nullptr, 1, CompletionOnceCallback(),
Ramin Halavati0a08cc82018-02-06 07:46:383393 TRAFFIC_ANNOTATION_FOR_TESTS));
Raul Tambre94493c652019-03-11 17:18:353394 EXPECT_EQ(1, handle3.socket()->Write(nullptr, 1, CompletionOnceCallback(),
Ramin Halavati0a08cc82018-02-06 07:46:383395 TRAFFIC_ANNOTATION_FOR_TESTS));
[email protected]e1b54dc2010-10-06 21:27:223396
3397 handle1.Reset();
3398 handle2.Reset();
3399 handle3.Reset();
3400
Matt Menkec6b3edf72019-03-19 17:00:393401 EXPECT_EQ(OK, handle1.Init(
Matt Menkef09e64c2019-04-23 22:16:283402 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3403 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menkec6b3edf72019-03-19 17:00:393404 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3405 pool_.get(), NetLogWithSource()));
3406 EXPECT_EQ(OK, handle2.Init(
Matt Menkef09e64c2019-04-23 22:16:283407 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3408 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menkec6b3edf72019-03-19 17:00:393409 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3410 pool_.get(), NetLogWithSource()));
3411 EXPECT_EQ(OK, handle3.Init(
Matt Menkef09e64c2019-04-23 22:16:283412 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3413 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menkec6b3edf72019-03-19 17:00:393414 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
3415 pool_.get(), NetLogWithSource()));
[email protected]e1b54dc2010-10-06 21:27:223416
3417 EXPECT_TRUE(handle1.socket()->WasEverUsed());
3418 EXPECT_TRUE(handle2.socket()->WasEverUsed());
3419 EXPECT_FALSE(handle3.socket()->WasEverUsed());
3420}
3421
[email protected]2c2bef152010-10-13 00:55:033422TEST_F(ClientSocketPoolBaseTest, RequestSockets) {
3423 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3424 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3425
Matt Menkef09e64c2019-04-23 22:16:283426 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
3427 NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033428
Matt Menke9fa17d52019-03-25 19:12:263429 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3430 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3431 EXPECT_EQ(2u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3432 TestGroupId("a")));
3433 EXPECT_EQ(2u,
3434 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393435 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033436
3437 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523438 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203439 EXPECT_EQ(
3440 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283441 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3442 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503443 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3444 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033445
3446 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523447 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203448 EXPECT_EQ(
3449 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283450 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3451 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503452 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3453 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033454
Matt Menke9fa17d52019-03-25 19:12:263455 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3456 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3457 TestGroupId("a")));
3458 EXPECT_EQ(0u,
3459 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393460 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033461
robpercival214763f2016-07-01 23:27:013462 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3463 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033464 handle1.Reset();
3465 handle2.Reset();
3466
Matt Menke9fa17d52019-03-25 19:12:263467 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3468 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3469 TestGroupId("a")));
3470 EXPECT_EQ(0u,
3471 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393472 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033473}
3474
3475TEST_F(ClientSocketPoolBaseTest, RequestSocketsWhenAlreadyHaveAConnectJob) {
3476 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3477 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3478
3479 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523480 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203481 EXPECT_EQ(
3482 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283483 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3484 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503485 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3486 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033487
Matt Menke9fa17d52019-03-25 19:12:263488 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3489 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3490 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3491 TestGroupId("a")));
3492 EXPECT_EQ(0u,
3493 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393494 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033495
Matt Menkef09e64c2019-04-23 22:16:283496 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
3497 NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033498
Matt Menke9fa17d52019-03-25 19:12:263499 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3500 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3501 TestGroupId("a")));
3502 EXPECT_EQ(1u,
3503 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393504 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033505
3506 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523507 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203508 EXPECT_EQ(
3509 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283510 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3511 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503512 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3513 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033514
Matt Menke9fa17d52019-03-25 19:12:263515 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3516 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3517 TestGroupId("a")));
3518 EXPECT_EQ(0u,
3519 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393520 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033521
robpercival214763f2016-07-01 23:27:013522 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3523 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033524 handle1.Reset();
3525 handle2.Reset();
3526
Matt Menke9fa17d52019-03-25 19:12:263527 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3528 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3529 TestGroupId("a")));
3530 EXPECT_EQ(0u,
3531 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393532 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033533}
3534
3535TEST_F(ClientSocketPoolBaseTest,
3536 RequestSocketsWhenAlreadyHaveMultipleConnectJob) {
3537 CreatePool(4, 4);
3538 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3539
3540 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523541 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203542 EXPECT_EQ(
3543 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283544 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3545 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503546 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3547 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033548
3549 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523550 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203551 EXPECT_EQ(
3552 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283553 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3554 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503555 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3556 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033557
3558 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:523559 TestCompletionCallback callback3;
tfarina428341112016-09-22 13:38:203560 EXPECT_EQ(
3561 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283562 handle3.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3563 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503564 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
3565 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033566
Matt Menke9fa17d52019-03-25 19:12:263567 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3568 EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3569 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3570 TestGroupId("a")));
3571 EXPECT_EQ(0u,
3572 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393573 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033574
Matt Menkef09e64c2019-04-23 22:16:283575 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
3576 NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033577
Matt Menke9fa17d52019-03-25 19:12:263578 EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3579 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3580 TestGroupId("a")));
3581 EXPECT_EQ(0u,
3582 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393583 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033584
robpercival214763f2016-07-01 23:27:013585 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3586 EXPECT_THAT(callback2.WaitForResult(), IsOk());
3587 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033588 handle1.Reset();
3589 handle2.Reset();
3590 handle3.Reset();
3591
Matt Menke9fa17d52019-03-25 19:12:263592 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3593 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3594 TestGroupId("a")));
3595 EXPECT_EQ(0u,
3596 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393597 EXPECT_EQ(3u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033598}
3599
3600TEST_F(ClientSocketPoolBaseTest, RequestSocketsAtMaxSocketLimit) {
3601 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3602 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3603
Matt Menke9fa17d52019-03-25 19:12:263604 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033605
Matt Menkef09e64c2019-04-23 22:16:283606 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt,
3607 kDefaultMaxSockets, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033608
Matt Menke9fa17d52019-03-25 19:12:263609 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
Raul Tambre8335a6d2019-02-21 16:57:433610 EXPECT_EQ(kDefaultMaxSockets,
Matt Menkec6b3edf72019-03-19 17:00:393611 static_cast<int>(
Matt Menke9fa17d52019-03-25 19:12:263612 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))));
3613 EXPECT_EQ(
3614 kDefaultMaxSockets,
3615 static_cast<int>(pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3616 TestGroupId("a"))));
Raul Tambre8335a6d2019-02-21 16:57:433617 EXPECT_EQ(kDefaultMaxSockets,
Matt Menke9fa17d52019-03-25 19:12:263618 static_cast<int>(pool_->NumUnassignedConnectJobsInGroupForTesting(
3619 TestGroupId("a"))));
[email protected]2c2bef152010-10-13 00:55:033620
Matt Menke9fa17d52019-03-25 19:12:263621 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("b")));
[email protected]2c2bef152010-10-13 00:55:033622
Matt Menkef09e64c2019-04-23 22:16:283623 pool_->RequestSockets(TestGroupId("b"), params_, base::nullopt,
3624 kDefaultMaxSockets, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033625
Matt Menke9fa17d52019-03-25 19:12:263626 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("b")));
[email protected]2c2bef152010-10-13 00:55:033627}
3628
3629TEST_F(ClientSocketPoolBaseTest, RequestSocketsHitMaxSocketLimit) {
3630 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3631 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3632
Matt Menke9fa17d52019-03-25 19:12:263633 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033634
Matt Menkef09e64c2019-04-23 22:16:283635 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt,
3636 kDefaultMaxSockets - 1, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033637
Matt Menke9fa17d52019-03-25 19:12:263638 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:433639 EXPECT_EQ(kDefaultMaxSockets - 1,
Matt Menkec6b3edf72019-03-19 17:00:393640 static_cast<int>(
Matt Menke9fa17d52019-03-25 19:12:263641 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))));
3642 EXPECT_EQ(
3643 kDefaultMaxSockets - 1,
3644 static_cast<int>(pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3645 TestGroupId("a"))));
Raul Tambre8335a6d2019-02-21 16:57:433646 EXPECT_EQ(kDefaultMaxSockets - 1,
Matt Menke9fa17d52019-03-25 19:12:263647 static_cast<int>(pool_->NumUnassignedConnectJobsInGroupForTesting(
3648 TestGroupId("a"))));
[email protected]51fdc7c2012-04-10 19:19:483649 EXPECT_FALSE(pool_->IsStalled());
[email protected]2c2bef152010-10-13 00:55:033650
Matt Menke9fa17d52019-03-25 19:12:263651 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("b")));
[email protected]2c2bef152010-10-13 00:55:033652
Matt Menkef09e64c2019-04-23 22:16:283653 pool_->RequestSockets(TestGroupId("b"), params_, base::nullopt,
3654 kDefaultMaxSockets, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033655
Matt Menke9fa17d52019-03-25 19:12:263656 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("b")));
3657 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
[email protected]51fdc7c2012-04-10 19:19:483658 EXPECT_FALSE(pool_->IsStalled());
[email protected]2c2bef152010-10-13 00:55:033659}
3660
3661TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) {
3662 CreatePool(4, 4);
3663 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3664
3665 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523666 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203667 EXPECT_EQ(
3668 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283669 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3670 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503671 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3672 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013673 ASSERT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033674 handle1.Reset();
3675
Matt Menke9fa17d52019-03-25 19:12:263676 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3677 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3678 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3679 TestGroupId("a")));
3680 EXPECT_EQ(0u,
3681 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393682 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033683
Matt Menkef09e64c2019-04-23 22:16:283684 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
3685 NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033686
Matt Menke9fa17d52019-03-25 19:12:263687 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3688 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3689 TestGroupId("a")));
3690 EXPECT_EQ(1u,
3691 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393692 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033693}
3694
3695TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountActiveSockets) {
3696 CreatePool(4, 4);
3697 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3698
3699 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523700 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203701 EXPECT_EQ(
3702 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283703 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3704 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503705 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3706 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013707 ASSERT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033708
Matt Menke9fa17d52019-03-25 19:12:263709 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3710 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3711 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3712 TestGroupId("a")));
3713 EXPECT_EQ(0u,
3714 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393715 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menke9fa17d52019-03-25 19:12:263716 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033717
Matt Menkef09e64c2019-04-23 22:16:283718 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
3719 NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033720
Matt Menke9fa17d52019-03-25 19:12:263721 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3722 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3723 TestGroupId("a")));
3724 EXPECT_EQ(1u,
3725 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393726 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menke9fa17d52019-03-25 19:12:263727 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033728}
3729
3730TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronous) {
3731 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3732 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3733
Matt Menkef09e64c2019-04-23 22:16:283734 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt,
3735 kDefaultMaxSocketsPerGroup, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033736
Matt Menke9fa17d52019-03-25 19:12:263737 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3738 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3739 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3740 TestGroupId("a")));
3741 EXPECT_EQ(0u,
3742 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Raul Tambre8335a6d2019-02-21 16:57:433743 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
Matt Menkec6b3edf72019-03-19 17:00:393744 static_cast<int>(pool_->IdleSocketCountInGroup(TestGroupId("a"))));
[email protected]2c2bef152010-10-13 00:55:033745
Matt Menkef09e64c2019-04-23 22:16:283746 pool_->RequestSockets(TestGroupId("b"), params_, base::nullopt,
3747 kDefaultMaxSocketsPerGroup, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033748
Matt Menke9fa17d52019-03-25 19:12:263749 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
3750 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3751 TestGroupId("b")));
3752 EXPECT_EQ(0u,
3753 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("b")));
Raul Tambre8335a6d2019-02-21 16:57:433754 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
Matt Menkec6b3edf72019-03-19 17:00:393755 static_cast<int>(pool_->IdleSocketCountInGroup(TestGroupId("b"))));
[email protected]2c2bef152010-10-13 00:55:033756}
3757
[email protected]3c819f522010-12-02 02:03:123758TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronousError) {
3759 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3760 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3761
Matt Menkef09e64c2019-04-23 22:16:283762 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt,
3763 kDefaultMaxSocketsPerGroup, NetLogWithSource());
[email protected]3c819f522010-12-02 02:03:123764
Matt Menke9fa17d52019-03-25 19:12:263765 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
[email protected]fd2e53e2011-01-14 20:40:523766
3767 connect_job_factory_->set_job_type(
3768 TestConnectJob::kMockAdditionalErrorStateJob);
Matt Menkef09e64c2019-04-23 22:16:283769 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt,
3770 kDefaultMaxSocketsPerGroup, NetLogWithSource());
[email protected]fd2e53e2011-01-14 20:40:523771
Matt Menke9fa17d52019-03-25 19:12:263772 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
[email protected]3c819f522010-12-02 02:03:123773}
3774
[email protected]8159a1c2012-06-07 00:00:103775TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) {
[email protected]2c2bef152010-10-13 00:55:033776 CreatePool(4, 4);
Lily Chenecebf932018-11-02 17:15:433777 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
[email protected]2c2bef152010-10-13 00:55:033778
Matt Menkef09e64c2019-04-23 22:16:283779 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
3780 NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033781
Matt Menke9fa17d52019-03-25 19:12:263782 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3783 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3784 EXPECT_EQ(2u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3785 TestGroupId("a")));
3786 EXPECT_EQ(2u,
3787 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3788 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393789 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033790
Matt Menkef09e64c2019-04-23 22:16:283791 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
3792 NetLogWithSource());
Matt Menke9fa17d52019-03-25 19:12:263793 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3794 EXPECT_EQ(2u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3795 TestGroupId("a")));
3796 EXPECT_EQ(2u,
3797 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3798 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393799 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033800
3801 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523802 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203803 EXPECT_EQ(
3804 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283805 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3806 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503807 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3808 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:433809
3810 client_socket_factory_.SignalJob(0);
3811 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3812
Matt Menke9fa17d52019-03-25 19:12:263813 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3814 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3815 TestGroupId("a")));
3816 EXPECT_EQ(1u,
3817 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3818 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393819 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033820
3821 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523822 TestCompletionCallback callback2;
Lily Chenecebf932018-11-02 17:15:433823 EXPECT_EQ(
3824 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283825 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3826 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503827 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3828 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:433829 client_socket_factory_.SignalJob(0);
3830 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033831
Matt Menke9fa17d52019-03-25 19:12:263832 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3833 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3834 TestGroupId("a")));
3835 EXPECT_EQ(0u,
3836 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3837 EXPECT_EQ(2, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393838 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]8159a1c2012-06-07 00:00:103839
[email protected]2c2bef152010-10-13 00:55:033840 handle1.Reset();
3841 handle2.Reset();
3842
Matt Menke9fa17d52019-03-25 19:12:263843 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3844 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3845 TestGroupId("a")));
3846 EXPECT_EQ(0u,
3847 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3848 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393849 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033850
Matt Menkef09e64c2019-04-23 22:16:283851 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
3852 NetLogWithSource());
Matt Menke9fa17d52019-03-25 19:12:263853 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3854 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3855 TestGroupId("a")));
3856 EXPECT_EQ(0u,
3857 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3858 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393859 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033860}
3861
3862TEST_F(ClientSocketPoolBaseTest, RequestSocketsDifferentNumSockets) {
3863 CreatePool(4, 4);
3864 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3865
Matt Menkef09e64c2019-04-23 22:16:283866 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 1,
3867 NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033868
Matt Menke9fa17d52019-03-25 19:12:263869 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3870 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3871 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3872 TestGroupId("a")));
3873 EXPECT_EQ(1u,
3874 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393875 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033876
Matt Menkef09e64c2019-04-23 22:16:283877 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
3878 NetLogWithSource());
Matt Menke9fa17d52019-03-25 19:12:263879 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3880 EXPECT_EQ(2u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3881 TestGroupId("a")));
3882 EXPECT_EQ(2u,
3883 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393884 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033885
Matt Menkef09e64c2019-04-23 22:16:283886 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 3,
3887 NetLogWithSource());
Matt Menke9fa17d52019-03-25 19:12:263888 EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3889 EXPECT_EQ(3u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3890 TestGroupId("a")));
3891 EXPECT_EQ(3u,
3892 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393893 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033894
Matt Menkef09e64c2019-04-23 22:16:283895 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 1,
3896 NetLogWithSource());
Matt Menke9fa17d52019-03-25 19:12:263897 EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3898 EXPECT_EQ(3u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3899 TestGroupId("a")));
3900 EXPECT_EQ(3u,
3901 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393902 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033903}
3904
3905TEST_F(ClientSocketPoolBaseTest, PreconnectJobsTakenByNormalRequests) {
3906 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
Lily Chenecebf932018-11-02 17:15:433907 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
[email protected]2c2bef152010-10-13 00:55:033908
Matt Menkef09e64c2019-04-23 22:16:283909 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 1,
3910 NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033911
Matt Menke9fa17d52019-03-25 19:12:263912 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3913 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3914 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3915 TestGroupId("a")));
3916 EXPECT_EQ(1u,
3917 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393918 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033919
3920 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523921 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203922 EXPECT_EQ(
3923 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283924 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3925 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503926 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3927 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033928
Matt Menke9fa17d52019-03-25 19:12:263929 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3930 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3931 TestGroupId("a")));
3932 EXPECT_EQ(0u,
3933 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393934 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033935
Lily Chenecebf932018-11-02 17:15:433936 client_socket_factory_.SignalJobs();
3937 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3938
Matt Menke9fa17d52019-03-25 19:12:263939 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3940 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3941 TestGroupId("a")));
3942 EXPECT_EQ(0u,
3943 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393944 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menke9fa17d52019-03-25 19:12:263945 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033946
[email protected]0dc88b32014-03-26 20:12:283947 // Make sure if a preconnected socket is not fully connected when a request
[email protected]034df0f32013-01-07 23:17:483948 // starts, it has a connect start time.
3949 TestLoadTimingInfoConnectedNotReused(handle1);
[email protected]2c2bef152010-10-13 00:55:033950 handle1.Reset();
3951
Matt Menkec6b3edf72019-03-19 17:00:393952 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033953}
3954
[email protected]034df0f32013-01-07 23:17:483955// Checks that fully connected preconnect jobs have no connect times, and are
3956// marked as reused.
3957TEST_F(ClientSocketPoolBaseTest, ConnectedPreconnectJobsHaveNoConnectTimes) {
3958 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3959 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
Matt Menkef09e64c2019-04-23 22:16:283960 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 1,
3961 NetLogWithSource());
[email protected]034df0f32013-01-07 23:17:483962
Matt Menke9fa17d52019-03-25 19:12:263963 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3964 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3965 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3966 TestGroupId("a")));
3967 EXPECT_EQ(0u,
3968 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393969 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]034df0f32013-01-07 23:17:483970
3971 ClientSocketHandle handle;
3972 TestCompletionCallback callback;
Matt Menkec6b3edf72019-03-19 17:00:393973 EXPECT_EQ(OK, handle.Init(
Matt Menkef09e64c2019-04-23 22:16:283974 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3975 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menkec6b3edf72019-03-19 17:00:393976 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3977 pool_.get(), NetLogWithSource()));
[email protected]034df0f32013-01-07 23:17:483978
3979 // Make sure the idle socket was used.
Matt Menkec6b3edf72019-03-19 17:00:393980 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]034df0f32013-01-07 23:17:483981
3982 TestLoadTimingInfoConnectedReused(handle);
3983 handle.Reset();
3984 TestLoadTimingInfoNotConnected(handle);
3985}
3986
[email protected]dcbe168a2010-12-02 03:14:463987// http://crbug.com/64940 regression test.
3988TEST_F(ClientSocketPoolBaseTest, PreconnectClosesIdleSocketRemovesGroup) {
3989 const int kMaxTotalSockets = 3;
3990 const int kMaxSocketsPerGroup = 2;
3991 CreatePool(kMaxTotalSockets, kMaxSocketsPerGroup);
Lily Chenecebf932018-11-02 17:15:433992 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
[email protected]dcbe168a2010-12-02 03:14:463993
Matt Menkef6edce752019-03-19 17:21:563994 // Note that group id ordering matters here. "a" comes before "b", so
[email protected]dcbe168a2010-12-02 03:14:463995 // CloseOneIdleSocket() will try to close "a"'s idle socket.
3996
3997 // Set up one idle socket in "a".
3998 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523999 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:204000 EXPECT_EQ(
4001 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284002 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4003 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504004 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4005 pool_.get(), NetLogWithSource()));
Matt Menke9fa17d52019-03-25 19:12:264006 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
4007 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4008 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4009 TestGroupId("a")));
4010 EXPECT_EQ(0u,
4011 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394012 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]dcbe168a2010-12-02 03:14:464013
Lily Chenecebf932018-11-02 17:15:434014 client_socket_factory_.SignalJobs();
robpercival214763f2016-07-01 23:27:014015 ASSERT_THAT(callback1.WaitForResult(), IsOk());
Matt Menke9fa17d52019-03-25 19:12:264016 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4017 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4018 TestGroupId("a")));
4019 EXPECT_EQ(0u,
4020 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4021 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434022
[email protected]dcbe168a2010-12-02 03:14:464023 handle1.Reset();
Matt Menkec6b3edf72019-03-19 17:00:394024 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]dcbe168a2010-12-02 03:14:464025
4026 // Set up two active sockets in "b".
4027 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:524028 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:204029 EXPECT_EQ(
4030 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284031 handle1.Init(TestGroupId("b"), params_, base::nullopt, DEFAULT_PRIORITY,
4032 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504033 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4034 pool_.get(), NetLogWithSource()));
tfarina428341112016-09-22 13:38:204035 EXPECT_EQ(
4036 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284037 handle2.Init(TestGroupId("b"), params_, base::nullopt, DEFAULT_PRIORITY,
4038 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504039 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4040 pool_.get(), NetLogWithSource()));
[email protected]dcbe168a2010-12-02 03:14:464041
Matt Menke9fa17d52019-03-25 19:12:264042 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("b")));
4043 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
4044 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4045 TestGroupId("b")));
4046 EXPECT_EQ(0u,
4047 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("b")));
Matt Menkec6b3edf72019-03-19 17:00:394048 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("b")));
Lily Chenecebf932018-11-02 17:15:434049
4050 client_socket_factory_.SignalJobs();
robpercival214763f2016-07-01 23:27:014051 ASSERT_THAT(callback1.WaitForResult(), IsOk());
4052 ASSERT_THAT(callback2.WaitForResult(), IsOk());
Matt Menkec6b3edf72019-03-19 17:00:394053 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("b")));
Matt Menke9fa17d52019-03-25 19:12:264054 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4055 TestGroupId("b")));
4056 EXPECT_EQ(0u,
4057 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("b")));
4058 EXPECT_EQ(2, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("b")));
[email protected]dcbe168a2010-12-02 03:14:464059
4060 // Now we have 1 idle socket in "a" and 2 active sockets in "b". This means
4061 // we've maxed out on sockets, since we set |kMaxTotalSockets| to 3.
4062 // Requesting 2 preconnected sockets for "a" should fail to allocate any more
4063 // sockets for "a", and "b" should still have 2 active sockets.
4064
Matt Menkef09e64c2019-04-23 22:16:284065 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
4066 NetLogWithSource());
Matt Menke9fa17d52019-03-25 19:12:264067 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4068 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4069 TestGroupId("a")));
4070 EXPECT_EQ(0u,
4071 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394072 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menke9fa17d52019-03-25 19:12:264073 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
4074 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
4075 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4076 TestGroupId("b")));
4077 EXPECT_EQ(0u,
4078 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("b")));
Matt Menkec6b3edf72019-03-19 17:00:394079 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("b")));
Matt Menke9fa17d52019-03-25 19:12:264080 EXPECT_EQ(2, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("b")));
[email protected]dcbe168a2010-12-02 03:14:464081
4082 // Now release the 2 active sockets for "b". This will give us 1 idle socket
4083 // in "a" and 2 idle sockets in "b". Requesting 2 preconnected sockets for
4084 // "a" should result in closing 1 for "b".
4085 handle1.Reset();
4086 handle2.Reset();
Matt Menkec6b3edf72019-03-19 17:00:394087 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(TestGroupId("b")));
Matt Menke9fa17d52019-03-25 19:12:264088 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("b")));
[email protected]dcbe168a2010-12-02 03:14:464089
Matt Menkef09e64c2019-04-23 22:16:284090 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
4091 NetLogWithSource());
Matt Menke9fa17d52019-03-25 19:12:264092 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4093 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4094 TestGroupId("a")));
4095 EXPECT_EQ(1u,
4096 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394097 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menke9fa17d52019-03-25 19:12:264098 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
4099 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
4100 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4101 TestGroupId("b")));
4102 EXPECT_EQ(0u,
4103 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("b")));
Matt Menkec6b3edf72019-03-19 17:00:394104 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("b")));
Matt Menke9fa17d52019-03-25 19:12:264105 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("b")));
[email protected]dcbe168a2010-12-02 03:14:464106}
4107
[email protected]b7b8be42011-07-12 12:46:414108TEST_F(ClientSocketPoolBaseTest, PreconnectWithoutBackupJob) {
Matt Menke9fa17d52019-03-25 19:12:264109 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
4110 true /* enable_backup_connect_jobs */);
[email protected]a9fc8fc2011-05-10 02:41:074111
4112 // Make the ConnectJob hang until it times out, shorten the timeout.
4113 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4114 connect_job_factory_->set_timeout_duration(
4115 base::TimeDelta::FromMilliseconds(500));
Matt Menkef09e64c2019-04-23 22:16:284116 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 1,
4117 NetLogWithSource());
Matt Menke9fa17d52019-03-25 19:12:264118 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4119 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4120 TestGroupId("a")));
4121 EXPECT_EQ(1u,
4122 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394123 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]a9fc8fc2011-05-10 02:41:074124
[email protected]b7b8be42011-07-12 12:46:414125 // Verify the backup timer doesn't create a backup job, by making
4126 // the backup job a pending job instead of a waiting job, so it
4127 // *would* complete if it were created.
[email protected]a9fc8fc2011-05-10 02:41:074128 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
skyostil4891b25b2015-06-11 11:43:454129 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
Gabriel Charetteea918012018-05-16 11:53:444130 FROM_HERE, base::RunLoop::QuitCurrentWhenIdleClosureDeprecated(),
[email protected]2da659e2013-05-23 20:51:344131 base::TimeDelta::FromSeconds(1));
fdoray5eeb7642016-06-22 16:11:284132 base::RunLoop().Run();
Matt Menke9fa17d52019-03-25 19:12:264133 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
[email protected]a9fc8fc2011-05-10 02:41:074134}
4135
[email protected]b7b8be42011-07-12 12:46:414136TEST_F(ClientSocketPoolBaseTest, PreconnectWithBackupJob) {
Matt Menke9fa17d52019-03-25 19:12:264137 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
4138 true /* enable_backup_connect_jobs */);
[email protected]a9fc8fc2011-05-10 02:41:074139
4140 // Make the ConnectJob hang forever.
4141 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
Matt Menkef09e64c2019-04-23 22:16:284142 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 1,
4143 NetLogWithSource());
Matt Menke9fa17d52019-03-25 19:12:264144 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4145 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4146 TestGroupId("a")));
4147 EXPECT_EQ(1u,
4148 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394149 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
fdoray5eeb7642016-06-22 16:11:284150 base::RunLoop().RunUntilIdle();
[email protected]a9fc8fc2011-05-10 02:41:074151
4152 // Make the backup job be a pending job, so it completes normally.
4153 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
4154 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:524155 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:504156 EXPECT_EQ(
4157 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284158 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4159 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4160 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
4161 pool_.get(), NetLogWithSource()));
[email protected]b7b8be42011-07-12 12:46:414162 // Timer has started, but the backup connect job shouldn't be created yet.
Matt Menke9fa17d52019-03-25 19:12:264163 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4164 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4165 TestGroupId("a")));
4166 EXPECT_EQ(0u,
4167 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394168 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menke9fa17d52019-03-25 19:12:264169 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
robpercival214763f2016-07-01 23:27:014170 ASSERT_THAT(callback.WaitForResult(), IsOk());
[email protected]a9fc8fc2011-05-10 02:41:074171
4172 // The hung connect job should still be there, but everything else should be
4173 // complete.
Matt Menke9fa17d52019-03-25 19:12:264174 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4175 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4176 TestGroupId("a")));
4177 EXPECT_EQ(1u,
4178 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394179 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menke9fa17d52019-03-25 19:12:264180 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
[email protected]a9fc8fc2011-05-10 02:41:074181}
4182
[email protected]0dc88b32014-03-26 20:12:284183// Tests that a preconnect that starts out with unread data can still be used.
4184// http://crbug.com/334467
4185TEST_F(ClientSocketPoolBaseTest, PreconnectWithUnreadData) {
4186 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4187 connect_job_factory_->set_job_type(TestConnectJob::kMockUnreadDataJob);
4188
Matt Menkef09e64c2019-04-23 22:16:284189 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 1,
4190 NetLogWithSource());
[email protected]0dc88b32014-03-26 20:12:284191
Matt Menke9fa17d52019-03-25 19:12:264192 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
4193 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4194 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4195 TestGroupId("a")));
4196 EXPECT_EQ(0u,
4197 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394198 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]0dc88b32014-03-26 20:12:284199
4200 // Fail future jobs to be sure that handle receives the preconnected socket
4201 // rather than closing it and making a new one.
4202 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
4203 ClientSocketHandle handle;
4204 TestCompletionCallback callback;
Matt Menkec6b3edf72019-03-19 17:00:394205 EXPECT_EQ(OK, handle.Init(
Matt Menkef09e64c2019-04-23 22:16:284206 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4207 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menkec6b3edf72019-03-19 17:00:394208 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
4209 pool_.get(), NetLogWithSource()));
[email protected]0dc88b32014-03-26 20:12:284210
Matt Menke9fa17d52019-03-25 19:12:264211 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
4212 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4213 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4214 TestGroupId("a")));
4215 EXPECT_EQ(0u,
4216 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394217 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menke9fa17d52019-03-25 19:12:264218 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
[email protected]0dc88b32014-03-26 20:12:284219
4220 // Drain the pending read.
Raul Tambre94493c652019-03-11 17:18:354221 EXPECT_EQ(1, handle.socket()->Read(nullptr, 1, CompletionOnceCallback()));
[email protected]0dc88b32014-03-26 20:12:284222
4223 TestLoadTimingInfoConnectedReused(handle);
4224 handle.Reset();
4225
4226 // The socket should be usable now that it's idle again.
Matt Menkec6b3edf72019-03-19 17:00:394227 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]0dc88b32014-03-26 20:12:284228}
4229
Lily Chenecebf932018-11-02 17:15:434230TEST_F(ClientSocketPoolBaseTest, RequestGetsAssignedJob) {
4231 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4232 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4233
4234 ClientSocketHandle handle1;
4235 TestCompletionCallback callback1;
4236 EXPECT_EQ(
4237 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284238 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4239 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504240 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4241 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434242
Matt Menke9fa17d52019-03-25 19:12:264243 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4244 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4245 TestGroupId("a")));
4246 EXPECT_EQ(0u,
4247 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394248 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434249
Matt Menkec6b3edf72019-03-19 17:00:394250 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4251 &handle1));
Lily Chenecebf932018-11-02 17:15:434252}
4253
4254TEST_F(ClientSocketPoolBaseTest, MultipleRequestsGetAssignedJobs) {
4255 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4256 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4257
4258 ClientSocketHandle handle1;
4259 TestCompletionCallback callback1;
4260 EXPECT_EQ(
4261 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284262 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4263 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504264 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4265 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434266
Matt Menke9fa17d52019-03-25 19:12:264267 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4268 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4269 TestGroupId("a")));
4270 EXPECT_EQ(0u,
4271 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394272 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434273
4274 ClientSocketHandle handle2;
4275 TestCompletionCallback callback2;
4276 EXPECT_EQ(
4277 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284278 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4279 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504280 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4281 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434282
Matt Menke9fa17d52019-03-25 19:12:264283 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4284 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4285 TestGroupId("a")));
4286 EXPECT_EQ(0u,
4287 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394288 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434289
Matt Menkec6b3edf72019-03-19 17:00:394290 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4291 &handle1));
4292 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4293 &handle2));
Lily Chenecebf932018-11-02 17:15:434294
4295 // One job completes. The other request should still have its job.
4296 client_socket_factory_.SignalJob(0);
4297 EXPECT_THAT(callback1.WaitForResult(), IsOk());
4298
Matt Menke9fa17d52019-03-25 19:12:264299 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4300 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4301 TestGroupId("a")));
4302 EXPECT_EQ(0u,
4303 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4304 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394305 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434306
Matt Menkec6b3edf72019-03-19 17:00:394307 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4308 &handle2));
Lily Chenecebf932018-11-02 17:15:434309}
4310
4311TEST_F(ClientSocketPoolBaseTest, PreconnectJobGetsAssignedToRequest) {
4312 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4313 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4314
Matt Menkef09e64c2019-04-23 22:16:284315 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 1,
4316 NetLogWithSource());
Lily Chenecebf932018-11-02 17:15:434317
Matt Menke9fa17d52019-03-25 19:12:264318 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
4319 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4320 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4321 TestGroupId("a")));
4322 EXPECT_EQ(1u,
4323 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394324 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434325
4326 ClientSocketHandle handle1;
4327 TestCompletionCallback callback1;
4328 EXPECT_EQ(
4329 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284330 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4331 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504332 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4333 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434334
Matt Menke9fa17d52019-03-25 19:12:264335 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4336 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4337 TestGroupId("a")));
4338 EXPECT_EQ(0u,
4339 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394340 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434341
Matt Menkec6b3edf72019-03-19 17:00:394342 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4343 &handle1));
Lily Chenecebf932018-11-02 17:15:434344}
4345
4346TEST_F(ClientSocketPoolBaseTest, HigherPriorityRequestStealsJob) {
4347 CreatePool(kDefaultMaxSockets, 1);
4348 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4349
4350 ClientSocketHandle handle1;
4351 TestCompletionCallback callback1;
4352 EXPECT_EQ(
4353 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284354 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4355 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504356 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4357 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434358
Matt Menke9fa17d52019-03-25 19:12:264359 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4360 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4361 TestGroupId("a")));
4362 EXPECT_EQ(0u,
4363 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394364 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434365
Matt Menkec6b3edf72019-03-19 17:00:394366 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4367 &handle1));
Lily Chenecebf932018-11-02 17:15:434368
4369 // Insert a higher priority request
4370 ClientSocketHandle handle2;
4371 TestCompletionCallback callback2;
4372 EXPECT_EQ(
4373 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284374 handle2.Init(TestGroupId("a"), params_, base::nullopt, HIGHEST,
4375 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504376 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4377 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434378
Matt Menke9fa17d52019-03-25 19:12:264379 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4380 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4381 TestGroupId("a")));
4382 EXPECT_EQ(0u,
4383 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394384 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434385
4386 // The highest priority request should steal the job from the default priority
4387 // request.
Matt Menkec6b3edf72019-03-19 17:00:394388 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4389 &handle2));
4390 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4391 &handle1));
Lily Chenecebf932018-11-02 17:15:434392}
4393
4394TEST_F(ClientSocketPoolBaseTest, RequestStealsJobFromLowestRequestWithJob) {
4395 CreatePool(3, 3);
4396 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4397
4398 ClientSocketHandle handle_lowest;
4399 TestCompletionCallback callback_lowest;
Matt Menkef09e64c2019-04-23 22:16:284400 EXPECT_EQ(
4401 ERR_IO_PENDING,
4402 handle_lowest.Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
4403 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4404 callback_lowest.callback(),
4405 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4406 NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434407
Matt Menke9fa17d52019-03-25 19:12:264408 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4409 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4410 TestGroupId("a")));
4411 EXPECT_EQ(0u,
4412 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394413 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434414
4415 ClientSocketHandle handle_highest;
4416 TestCompletionCallback callback_highest;
Matt Menkef09e64c2019-04-23 22:16:284417 EXPECT_EQ(
4418 ERR_IO_PENDING,
4419 handle_highest.Init(TestGroupId("a"), params_, base::nullopt, HIGHEST,
4420 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4421 callback_highest.callback(),
4422 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4423 NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434424
Matt Menke9fa17d52019-03-25 19:12:264425 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4426 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4427 TestGroupId("a")));
4428 EXPECT_EQ(0u,
4429 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394430 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434431
4432 ClientSocketHandle handle_low;
4433 TestCompletionCallback callback_low;
4434 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284435 handle_low.Init(
4436 TestGroupId("a"), params_, base::nullopt, LOW, SocketTag(),
4437 ClientSocketPool::RespectLimits::ENABLED,
4438 callback_low.callback(), ClientSocketPool::ProxyAuthCallback(),
4439 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434440
Matt Menke9fa17d52019-03-25 19:12:264441 EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4442 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4443 TestGroupId("a")));
4444 EXPECT_EQ(0u,
4445 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394446 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434447
4448 ClientSocketHandle handle_lowest2;
4449 TestCompletionCallback callback_lowest2;
Matt Menkef09e64c2019-04-23 22:16:284450 EXPECT_EQ(
4451 ERR_IO_PENDING,
4452 handle_lowest2.Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
4453 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4454 callback_lowest2.callback(),
4455 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4456 NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434457
Matt Menke9fa17d52019-03-25 19:12:264458 EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4459 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4460 TestGroupId("a")));
4461 EXPECT_EQ(0u,
4462 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394463 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434464
4465 // The top three requests in the queue should have jobs.
Matt Menkec6b3edf72019-03-19 17:00:394466 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4467 &handle_highest));
4468 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4469 &handle_low));
4470 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4471 &handle_lowest));
4472 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(
4473 TestGroupId("a"), &handle_lowest2));
Lily Chenecebf932018-11-02 17:15:434474
4475 // Add another request with medium priority. It should steal the job from the
4476 // lowest priority request with a job.
4477 ClientSocketHandle handle_medium;
4478 TestCompletionCallback callback_medium;
Matt Menkef09e64c2019-04-23 22:16:284479 EXPECT_EQ(
4480 ERR_IO_PENDING,
4481 handle_medium.Init(TestGroupId("a"), params_, base::nullopt, MEDIUM,
4482 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4483 callback_medium.callback(),
4484 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4485 NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434486
Matt Menke9fa17d52019-03-25 19:12:264487 EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4488 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4489 TestGroupId("a")));
4490 EXPECT_EQ(0u,
4491 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394492 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4493 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4494 &handle_highest));
4495 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4496 &handle_medium));
4497 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4498 &handle_low));
4499 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4500 &handle_lowest));
4501 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(
4502 TestGroupId("a"), &handle_lowest2));
Lily Chenecebf932018-11-02 17:15:434503}
4504
4505TEST_F(ClientSocketPoolBaseTest, ReprioritizeRequestStealsJob) {
4506 CreatePool(kDefaultMaxSockets, 1);
4507 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4508
4509 ClientSocketHandle handle1;
4510 TestCompletionCallback callback1;
4511 EXPECT_EQ(
4512 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284513 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4514 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504515 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4516 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434517
Matt Menke9fa17d52019-03-25 19:12:264518 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4519 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4520 TestGroupId("a")));
4521 EXPECT_EQ(0u,
4522 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394523 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434524
4525 ClientSocketHandle handle2;
4526 TestCompletionCallback callback2;
4527 EXPECT_EQ(
4528 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284529 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4530 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504531 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4532 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434533
Matt Menke9fa17d52019-03-25 19:12:264534 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4535 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4536 TestGroupId("a")));
4537 EXPECT_EQ(0u,
4538 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394539 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434540
4541 // The second request doesn't get a job because we are at the limit.
Matt Menkec6b3edf72019-03-19 17:00:394542 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4543 &handle1));
4544 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4545 &handle2));
Lily Chenecebf932018-11-02 17:15:434546
4547 // Reprioritizing the second request places it above the first, and it steals
4548 // the job from the first request.
Matt Menkec6b3edf72019-03-19 17:00:394549 pool_->SetPriority(TestGroupId("a"), &handle2, HIGHEST);
4550 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4551 &handle2));
4552 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4553 &handle1));
Lily Chenecebf932018-11-02 17:15:434554}
4555
4556TEST_F(ClientSocketPoolBaseTest, CancelRequestReassignsJob) {
4557 CreatePool(kDefaultMaxSockets, 1);
4558 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4559
4560 ClientSocketHandle handle1;
4561 TestCompletionCallback callback1;
4562 EXPECT_EQ(
4563 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284564 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4565 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504566 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4567 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434568
Matt Menke9fa17d52019-03-25 19:12:264569 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4570 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4571 TestGroupId("a")));
4572 EXPECT_EQ(0u,
4573 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394574 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434575
Matt Menkec6b3edf72019-03-19 17:00:394576 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4577 &handle1));
Lily Chenecebf932018-11-02 17:15:434578
4579 ClientSocketHandle handle2;
4580 TestCompletionCallback callback2;
4581 EXPECT_EQ(
4582 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284583 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4584 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504585 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4586 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434587
Matt Menke9fa17d52019-03-25 19:12:264588 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4589 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4590 TestGroupId("a")));
4591 EXPECT_EQ(0u,
4592 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394593 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434594
4595 // The second request doesn't get a job because we are the limit.
Matt Menkec6b3edf72019-03-19 17:00:394596 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4597 &handle1));
4598 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4599 &handle2));
Lily Chenecebf932018-11-02 17:15:434600
4601 // The second request should get a job upon cancelling the first request.
4602 handle1.Reset();
Matt Menke9fa17d52019-03-25 19:12:264603 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4604 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4605 TestGroupId("a")));
4606 EXPECT_EQ(0u,
4607 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394608 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434609
Matt Menkec6b3edf72019-03-19 17:00:394610 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4611 &handle2));
Lily Chenecebf932018-11-02 17:15:434612}
4613
4614TEST_F(ClientSocketPoolBaseTest, JobCompletionReassignsJob) {
4615 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4616 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4617
4618 ClientSocketHandle handle1;
4619 TestCompletionCallback callback1;
4620 EXPECT_EQ(
4621 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284622 handle1.Init(TestGroupId("a"), params_, base::nullopt, HIGHEST,
4623 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504624 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4625 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434626
Matt Menke9fa17d52019-03-25 19:12:264627 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4628 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4629 TestGroupId("a")));
4630 EXPECT_EQ(0u,
4631 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394632 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434633
4634 ClientSocketHandle handle2;
4635 TestCompletionCallback callback2;
4636 EXPECT_EQ(
4637 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284638 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4639 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504640 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4641 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434642
Matt Menke9fa17d52019-03-25 19:12:264643 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4644 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4645 TestGroupId("a")));
4646 EXPECT_EQ(0u,
4647 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394648 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434649
Matt Menkec6b3edf72019-03-19 17:00:394650 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4651 &handle1));
4652 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4653 &handle2));
Lily Chenecebf932018-11-02 17:15:434654
4655 // The lower-priority job completes first. The higher-priority request should
4656 // get the socket, and the lower-priority request should get the remaining
4657 // job.
4658 client_socket_factory_.SignalJob(1);
4659 EXPECT_THAT(callback1.WaitForResult(), IsOk());
Matt Menke9fa17d52019-03-25 19:12:264660 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4661 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4662 TestGroupId("a")));
4663 EXPECT_EQ(0u,
4664 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4665 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394666 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434667 EXPECT_TRUE(handle1.socket());
Matt Menkec6b3edf72019-03-19 17:00:394668 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4669 &handle2));
Lily Chenecebf932018-11-02 17:15:434670}
4671
[email protected]043b68c82013-08-22 23:41:524672class MockLayeredPool : public HigherLayeredPool {
[email protected]58e562f2013-04-22 17:32:204673 public:
Matt Menke9fa17d52019-03-25 19:12:264674 MockLayeredPool(TransportClientSocketPool* pool,
Matt Menkec6b3edf72019-03-19 17:00:394675 const ClientSocketPool::GroupId& group_id)
4676 : pool_(pool), group_id_(group_id), can_release_connection_(true) {
[email protected]043b68c82013-08-22 23:41:524677 pool_->AddHigherLayeredPool(this);
[email protected]58e562f2013-04-22 17:32:204678 }
4679
Daniel Cheng4496d0822018-04-26 21:52:154680 ~MockLayeredPool() override { pool_->RemoveHigherLayeredPool(this); }
[email protected]58e562f2013-04-22 17:32:204681
Matt Menke9fa17d52019-03-25 19:12:264682 int RequestSocket(TransportClientSocketPool* pool) {
Matt Menke28ac03e2019-02-25 22:25:504683 return handle_.Init(
Matt Menke870e19ab2019-04-23 16:23:034684 group_id_, ClientSocketPool::SocketParams::CreateForHttpForTesting(),
Matt Menkef09e64c2019-04-23 22:16:284685 base::nullopt, DEFAULT_PRIORITY, SocketTag(),
4686 ClientSocketPool::RespectLimits::ENABLED, callback_.callback(),
4687 ClientSocketPool::ProxyAuthCallback(), pool, NetLogWithSource());
[email protected]58e562f2013-04-22 17:32:204688 }
4689
Matt Menke9fa17d52019-03-25 19:12:264690 int RequestSocketWithoutLimits(TransportClientSocketPool* pool) {
Matt Menke28ac03e2019-02-25 22:25:504691 return handle_.Init(
Matt Menke870e19ab2019-04-23 16:23:034692 group_id_, ClientSocketPool::SocketParams::CreateForHttpForTesting(),
Matt Menkef09e64c2019-04-23 22:16:284693 base::nullopt, MAXIMUM_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:504694 ClientSocketPool::RespectLimits::DISABLED, callback_.callback(),
4695 ClientSocketPool::ProxyAuthCallback(), pool, NetLogWithSource());
[email protected]58e562f2013-04-22 17:32:204696 }
4697
4698 bool ReleaseOneConnection() {
4699 if (!handle_.is_initialized() || !can_release_connection_) {
4700 return false;
4701 }
4702 handle_.socket()->Disconnect();
4703 handle_.Reset();
4704 return true;
4705 }
4706
4707 void set_can_release_connection(bool can_release_connection) {
4708 can_release_connection_ = can_release_connection;
4709 }
4710
4711 MOCK_METHOD0(CloseOneIdleConnection, bool());
4712
4713 private:
Matt Menke9fa17d52019-03-25 19:12:264714 TransportClientSocketPool* const pool_;
[email protected]58e562f2013-04-22 17:32:204715 ClientSocketHandle handle_;
4716 TestCompletionCallback callback_;
Matt Menkec6b3edf72019-03-19 17:00:394717 const ClientSocketPool::GroupId group_id_;
[email protected]58e562f2013-04-22 17:32:204718 bool can_release_connection_;
4719};
4720
[email protected]58e562f2013-04-22 17:32:204721// Tests the basic case of closing an idle socket in a higher layered pool when
4722// a new request is issued and the lower layer pool is stalled.
4723TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsHeldByLayeredPoolWhenNeeded) {
4724 CreatePool(1, 1);
4725 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4726
Matt Menkec6b3edf72019-03-19 17:00:394727 MockLayeredPool mock_layered_pool(pool_.get(), TestGroupId("foo"));
robpercival214763f2016-07-01 23:27:014728 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:204729 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4730 .WillOnce(Invoke(&mock_layered_pool,
4731 &MockLayeredPool::ReleaseOneConnection));
4732 ClientSocketHandle handle;
4733 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:504734 EXPECT_EQ(
4735 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284736 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4737 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4738 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
4739 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:014740 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204741}
4742
Matt Menke833678642019-03-05 22:05:514743// Tests the case that trying to close an idle socket in a higher layered pool
4744// fails.
4745TEST_F(ClientSocketPoolBaseTest,
4746 CloseIdleSocketsHeldByLayeredPoolWhenNeededFails) {
4747 CreatePool(1, 1);
4748 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4749
Matt Menkec6b3edf72019-03-19 17:00:394750 MockLayeredPool mock_layered_pool(pool_.get(), TestGroupId("foo"));
Matt Menke833678642019-03-05 22:05:514751 mock_layered_pool.set_can_release_connection(false);
4752 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
4753 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4754 .WillOnce(Invoke(&mock_layered_pool,
4755 &MockLayeredPool::ReleaseOneConnection));
4756 ClientSocketHandle handle;
4757 TestCompletionCallback callback;
4758 EXPECT_EQ(
4759 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284760 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4761 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4762 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
4763 pool_.get(), NetLogWithSource()));
Matt Menke833678642019-03-05 22:05:514764 base::RunLoop().RunUntilIdle();
4765 EXPECT_FALSE(callback.have_result());
4766}
4767
[email protected]58e562f2013-04-22 17:32:204768// Same as above, but the idle socket is in the same group as the stalled
4769// socket, and closes the only other request in its group when closing requests
4770// in higher layered pools. This generally shouldn't happen, but it may be
4771// possible if a higher level pool issues a request and the request is
4772// subsequently cancelled. Even if it's not possible, best not to crash.
4773TEST_F(ClientSocketPoolBaseTest,
4774 CloseIdleSocketsHeldByLayeredPoolWhenNeededSameGroup) {
4775 CreatePool(2, 2);
4776 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4777
4778 // Need a socket in another group for the pool to be stalled (If a group
4779 // has the maximum number of connections already, it's not stalled).
4780 ClientSocketHandle handle1;
4781 TestCompletionCallback callback1;
Matt Menkef09e64c2019-04-23 22:16:284782 EXPECT_EQ(OK, handle1.Init(TestGroupId("group1"), params_, base::nullopt,
4783 DEFAULT_PRIORITY, SocketTag(),
4784 ClientSocketPool::RespectLimits::ENABLED,
4785 callback1.callback(),
4786 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4787 NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:204788
Matt Menkec6b3edf72019-03-19 17:00:394789 MockLayeredPool mock_layered_pool(pool_.get(), TestGroupId("group2"));
robpercival214763f2016-07-01 23:27:014790 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:204791 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4792 .WillOnce(Invoke(&mock_layered_pool,
4793 &MockLayeredPool::ReleaseOneConnection));
4794 ClientSocketHandle handle;
4795 TestCompletionCallback callback2;
Matt Menkef09e64c2019-04-23 22:16:284796 EXPECT_EQ(ERR_IO_PENDING,
4797 handle.Init(
4798 TestGroupId("group2"), params_, base::nullopt, DEFAULT_PRIORITY,
4799 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4800 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4801 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:014802 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204803}
4804
4805// Tests the case when an idle socket can be closed when a new request is
4806// issued, and the new request belongs to a group that was previously stalled.
4807TEST_F(ClientSocketPoolBaseTest,
4808 CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded) {
4809 CreatePool(2, 2);
4810 std::list<TestConnectJob::JobType> job_types;
4811 job_types.push_back(TestConnectJob::kMockJob);
4812 job_types.push_back(TestConnectJob::kMockJob);
4813 job_types.push_back(TestConnectJob::kMockJob);
4814 job_types.push_back(TestConnectJob::kMockJob);
4815 connect_job_factory_->set_job_types(&job_types);
4816
4817 ClientSocketHandle handle1;
4818 TestCompletionCallback callback1;
Matt Menkef09e64c2019-04-23 22:16:284819 EXPECT_EQ(OK, handle1.Init(TestGroupId("group1"), params_, base::nullopt,
4820 DEFAULT_PRIORITY, SocketTag(),
4821 ClientSocketPool::RespectLimits::ENABLED,
4822 callback1.callback(),
4823 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4824 NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:204825
Matt Menkec6b3edf72019-03-19 17:00:394826 MockLayeredPool mock_layered_pool(pool_.get(), TestGroupId("group2"));
robpercival214763f2016-07-01 23:27:014827 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:204828 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4829 .WillRepeatedly(Invoke(&mock_layered_pool,
4830 &MockLayeredPool::ReleaseOneConnection));
4831 mock_layered_pool.set_can_release_connection(false);
4832
4833 // The third request is made when the socket pool is in a stalled state.
4834 ClientSocketHandle handle3;
4835 TestCompletionCallback callback3;
Matt Menkef09e64c2019-04-23 22:16:284836 EXPECT_EQ(ERR_IO_PENDING,
4837 handle3.Init(
4838 TestGroupId("group3"), params_, base::nullopt, DEFAULT_PRIORITY,
4839 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4840 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
4841 pool_.get(), NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:204842
4843 base::RunLoop().RunUntilIdle();
4844 EXPECT_FALSE(callback3.have_result());
4845
4846 // The fourth request is made when the pool is no longer stalled. The third
4847 // request should be serviced first, since it was issued first and has the
4848 // same priority.
4849 mock_layered_pool.set_can_release_connection(true);
4850 ClientSocketHandle handle4;
4851 TestCompletionCallback callback4;
Matt Menkef09e64c2019-04-23 22:16:284852 EXPECT_EQ(ERR_IO_PENDING,
4853 handle4.Init(
4854 TestGroupId("group3"), params_, base::nullopt, DEFAULT_PRIORITY,
4855 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4856 callback4.callback(), ClientSocketPool::ProxyAuthCallback(),
4857 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:014858 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204859 EXPECT_FALSE(callback4.have_result());
4860
4861 // Closing a handle should free up another socket slot.
4862 handle1.Reset();
robpercival214763f2016-07-01 23:27:014863 EXPECT_THAT(callback4.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204864}
4865
4866// Tests the case when an idle socket can be closed when a new request is
4867// issued, and the new request belongs to a group that was previously stalled.
4868//
4869// The two differences from the above test are that the stalled requests are not
4870// in the same group as the layered pool's request, and the the fourth request
4871// has a higher priority than the third one, so gets a socket first.
4872TEST_F(ClientSocketPoolBaseTest,
4873 CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded2) {
4874 CreatePool(2, 2);
4875 std::list<TestConnectJob::JobType> job_types;
4876 job_types.push_back(TestConnectJob::kMockJob);
4877 job_types.push_back(TestConnectJob::kMockJob);
4878 job_types.push_back(TestConnectJob::kMockJob);
4879 job_types.push_back(TestConnectJob::kMockJob);
4880 connect_job_factory_->set_job_types(&job_types);
4881
4882 ClientSocketHandle handle1;
4883 TestCompletionCallback callback1;
Matt Menkef09e64c2019-04-23 22:16:284884 EXPECT_EQ(OK, handle1.Init(TestGroupId("group1"), params_, base::nullopt,
4885 DEFAULT_PRIORITY, SocketTag(),
4886 ClientSocketPool::RespectLimits::ENABLED,
4887 callback1.callback(),
4888 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4889 NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:204890
Matt Menkec6b3edf72019-03-19 17:00:394891 MockLayeredPool mock_layered_pool(pool_.get(), TestGroupId("group2"));
robpercival214763f2016-07-01 23:27:014892 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:204893 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4894 .WillRepeatedly(Invoke(&mock_layered_pool,
4895 &MockLayeredPool::ReleaseOneConnection));
4896 mock_layered_pool.set_can_release_connection(false);
4897
4898 // The third request is made when the socket pool is in a stalled state.
4899 ClientSocketHandle handle3;
4900 TestCompletionCallback callback3;
tfarina428341112016-09-22 13:38:204901 EXPECT_EQ(
4902 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284903 handle3.Init(TestGroupId("group3"), params_, base::nullopt, MEDIUM,
4904 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504905 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
4906 pool_.get(), NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:204907
4908 base::RunLoop().RunUntilIdle();
4909 EXPECT_FALSE(callback3.have_result());
4910
4911 // The fourth request is made when the pool is no longer stalled. This
4912 // request has a higher priority than the third request, so is serviced first.
4913 mock_layered_pool.set_can_release_connection(true);
4914 ClientSocketHandle handle4;
4915 TestCompletionCallback callback4;
tfarina428341112016-09-22 13:38:204916 EXPECT_EQ(
4917 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284918 handle4.Init(TestGroupId("group3"), params_, base::nullopt, HIGHEST,
4919 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504920 callback4.callback(), ClientSocketPool::ProxyAuthCallback(),
4921 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:014922 EXPECT_THAT(callback4.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204923 EXPECT_FALSE(callback3.have_result());
4924
4925 // Closing a handle should free up another socket slot.
4926 handle1.Reset();
robpercival214763f2016-07-01 23:27:014927 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204928}
4929
4930TEST_F(ClientSocketPoolBaseTest,
4931 CloseMultipleIdleSocketsHeldByLayeredPoolWhenNeeded) {
4932 CreatePool(1, 1);
4933 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4934
Matt Menkec6b3edf72019-03-19 17:00:394935 MockLayeredPool mock_layered_pool1(pool_.get(), TestGroupId("foo"));
robpercival214763f2016-07-01 23:27:014936 EXPECT_THAT(mock_layered_pool1.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:204937 EXPECT_CALL(mock_layered_pool1, CloseOneIdleConnection())
4938 .WillRepeatedly(Invoke(&mock_layered_pool1,
4939 &MockLayeredPool::ReleaseOneConnection));
Matt Menkec6b3edf72019-03-19 17:00:394940 MockLayeredPool mock_layered_pool2(pool_.get(), TestGroupId("bar"));
robpercival214763f2016-07-01 23:27:014941 EXPECT_THAT(mock_layered_pool2.RequestSocketWithoutLimits(pool_.get()),
4942 IsOk());
[email protected]58e562f2013-04-22 17:32:204943 EXPECT_CALL(mock_layered_pool2, CloseOneIdleConnection())
4944 .WillRepeatedly(Invoke(&mock_layered_pool2,
4945 &MockLayeredPool::ReleaseOneConnection));
4946 ClientSocketHandle handle;
4947 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:504948 EXPECT_EQ(
4949 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284950 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4951 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4952 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
4953 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:014954 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204955}
4956
[email protected]b021ece62013-06-11 11:06:334957// Test that when a socket pool and group are at their limits, a request
mmenked3641e12016-01-28 16:06:154958// with RespectLimits::DISABLED triggers creation of a new socket, and gets the
4959// socket instead of a request with the same priority that was issued earlier,
4960// but has RespectLimits::ENABLED.
[email protected]b021ece62013-06-11 11:06:334961TEST_F(ClientSocketPoolBaseTest, IgnoreLimits) {
[email protected]b021ece62013-06-11 11:06:334962 CreatePool(1, 1);
4963
4964 // Issue a request to reach the socket pool limit.
Matt Menkec6b3edf72019-03-19 17:00:394965 EXPECT_EQ(OK, StartRequestWithIgnoreLimits(
4966 TestGroupId("a"), MAXIMUM_PRIORITY,
4967 ClientSocketPool::RespectLimits::ENABLED));
Matt Menke9fa17d52019-03-25 19:12:264968 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]b021ece62013-06-11 11:06:334969
4970 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
4971
mmenked3641e12016-01-28 16:06:154972 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
Matt Menkec6b3edf72019-03-19 17:00:394973 TestGroupId("a"), MAXIMUM_PRIORITY,
mmenked3641e12016-01-28 16:06:154974 ClientSocketPool::RespectLimits::ENABLED));
Matt Menke9fa17d52019-03-25 19:12:264975 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]b021ece62013-06-11 11:06:334976
mmenked3641e12016-01-28 16:06:154977 // Issue a request that ignores the limits, so a new ConnectJob is
4978 // created.
4979 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
Matt Menkec6b3edf72019-03-19 17:00:394980 TestGroupId("a"), MAXIMUM_PRIORITY,
mmenked3641e12016-01-28 16:06:154981 ClientSocketPool::RespectLimits::DISABLED));
Matt Menke9fa17d52019-03-25 19:12:264982 ASSERT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]b021ece62013-06-11 11:06:334983
robpercival214763f2016-07-01 23:27:014984 EXPECT_THAT(request(2)->WaitForResult(), IsOk());
[email protected]b021ece62013-06-11 11:06:334985 EXPECT_FALSE(request(1)->have_result());
4986}
4987
[email protected]c55fabd2013-11-04 23:26:564988// Test that when a socket pool and group are at their limits, a ConnectJob
mmenked3641e12016-01-28 16:06:154989// issued for a request with RespectLimits::DISABLED is not cancelled when a
4990// request with RespectLimits::ENABLED issued to the same group is cancelled.
[email protected]c55fabd2013-11-04 23:26:564991TEST_F(ClientSocketPoolBaseTest, IgnoreLimitsCancelOtherJob) {
[email protected]c55fabd2013-11-04 23:26:564992 CreatePool(1, 1);
4993
4994 // Issue a request to reach the socket pool limit.
Matt Menkec6b3edf72019-03-19 17:00:394995 EXPECT_EQ(OK, StartRequestWithIgnoreLimits(
4996 TestGroupId("a"), MAXIMUM_PRIORITY,
4997 ClientSocketPool::RespectLimits::ENABLED));
Matt Menke9fa17d52019-03-25 19:12:264998 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]c55fabd2013-11-04 23:26:564999
5000 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
5001
mmenked3641e12016-01-28 16:06:155002 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
Matt Menkec6b3edf72019-03-19 17:00:395003 TestGroupId("a"), MAXIMUM_PRIORITY,
mmenked3641e12016-01-28 16:06:155004 ClientSocketPool::RespectLimits::ENABLED));
Matt Menke9fa17d52019-03-25 19:12:265005 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]c55fabd2013-11-04 23:26:565006
mmenked3641e12016-01-28 16:06:155007 // Issue a request with RespectLimits::DISABLED, so a new ConnectJob is
5008 // created.
5009 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
Matt Menkec6b3edf72019-03-19 17:00:395010 TestGroupId("a"), MAXIMUM_PRIORITY,
mmenked3641e12016-01-28 16:06:155011 ClientSocketPool::RespectLimits::DISABLED));
Matt Menke9fa17d52019-03-25 19:12:265012 ASSERT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]b021ece62013-06-11 11:06:335013
mmenked3641e12016-01-28 16:06:155014 // Cancel the pending request with RespectLimits::ENABLED. The ConnectJob
[email protected]b021ece62013-06-11 11:06:335015 // should not be cancelled.
5016 request(1)->handle()->Reset();
Matt Menke9fa17d52019-03-25 19:12:265017 ASSERT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]b021ece62013-06-11 11:06:335018
robpercival214763f2016-07-01 23:27:015019 EXPECT_THAT(request(2)->WaitForResult(), IsOk());
[email protected]b021ece62013-06-11 11:06:335020 EXPECT_FALSE(request(1)->have_result());
5021}
5022
Matt Menkeb57663b32019-03-01 17:17:105023TEST_F(ClientSocketPoolBaseTest, ProxyAuthNoAuthCallback) {
5024 CreatePool(1, 1);
5025
5026 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5027
5028 ClientSocketHandle handle;
5029 TestCompletionCallback callback;
5030 EXPECT_EQ(
5031 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:285032 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
5033 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5034 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5035 pool_.get(), NetLogWithSource()));
Matt Menkeb57663b32019-03-01 17:17:105036
Matt Menke9fa17d52019-03-25 19:12:265037 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105038
5039 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_PROXY_AUTH_REQUESTED));
5040 EXPECT_FALSE(handle.is_initialized());
5041 EXPECT_FALSE(handle.socket());
5042
5043 // The group should now be empty, and thus be deleted.
Matt Menke9fa17d52019-03-25 19:12:265044 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105045}
5046
5047class TestAuthHelper {
5048 public:
5049 TestAuthHelper() = default;
5050 ~TestAuthHelper() = default;
5051
Matt Menkec6b3edf72019-03-19 17:00:395052 void InitHandle(
Matt Menke84d11e562019-03-27 00:11:195053 scoped_refptr<ClientSocketPool::SocketParams> params,
Matt Menke9fa17d52019-03-25 19:12:265054 TransportClientSocketPool* pool,
Matt Menkec6b3edf72019-03-19 17:00:395055 RequestPriority priority = DEFAULT_PRIORITY,
5056 ClientSocketPool::RespectLimits respect_limits =
5057 ClientSocketPool::RespectLimits::ENABLED,
5058 const ClientSocketPool::GroupId& group_id_in = TestGroupId("a")) {
Matt Menkeb57663b32019-03-01 17:17:105059 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:285060 handle_.Init(group_id_in, params, base::nullopt, priority,
5061 SocketTag(), respect_limits, callback_.callback(),
Matt Menkeb57663b32019-03-01 17:17:105062 base::BindRepeating(&TestAuthHelper::AuthCallback,
5063 base::Unretained(this)),
5064 pool, NetLogWithSource()));
5065 }
5066
5067 void WaitForAuth() {
5068 run_loop_ = std::make_unique<base::RunLoop>();
5069 run_loop_->Run();
5070 run_loop_.reset();
5071 }
5072
5073 void WaitForAuthAndRestartSync() {
5074 restart_sync_ = true;
5075 WaitForAuth();
5076 restart_sync_ = false;
5077 }
5078
5079 void WaitForAuthAndResetHandleSync() {
5080 reset_handle_sync_ = true;
5081 WaitForAuth();
5082 reset_handle_sync_ = false;
5083 }
5084
5085 void RestartWithAuth() {
5086 DCHECK(restart_with_auth_callback_);
5087 std::move(restart_with_auth_callback_).Run();
5088 }
5089
5090 int WaitForResult() {
5091 int result = callback_.WaitForResult();
5092 // There shouldn't be any callback waiting to be invoked once the request is
5093 // complete.
5094 EXPECT_FALSE(restart_with_auth_callback_);
5095 // The socket should only be initialized on success.
5096 EXPECT_EQ(result == OK, handle_.is_initialized());
5097 EXPECT_EQ(result == OK, handle_.socket() != nullptr);
5098 return result;
5099 }
5100
5101 ClientSocketHandle* handle() { return &handle_; }
5102 int auth_count() const { return auth_count_; }
5103 int have_result() const { return callback_.have_result(); }
5104
5105 private:
5106 void AuthCallback(const HttpResponseInfo& response,
5107 HttpAuthController* auth_controller,
5108 base::OnceClosure restart_with_auth_callback) {
5109 EXPECT_FALSE(restart_with_auth_callback_);
5110 EXPECT_TRUE(restart_with_auth_callback);
5111
5112 // Once there's a result, this method shouldn't be invoked again.
5113 EXPECT_FALSE(callback_.have_result());
5114
5115 ++auth_count_;
5116 run_loop_->Quit();
5117 if (restart_sync_) {
5118 std::move(restart_with_auth_callback).Run();
5119 return;
5120 }
5121
5122 restart_with_auth_callback_ = std::move(restart_with_auth_callback);
5123
5124 if (reset_handle_sync_) {
5125 handle_.Reset();
5126 return;
5127 }
5128 }
5129
5130 std::unique_ptr<base::RunLoop> run_loop_;
5131 base::OnceClosure restart_with_auth_callback_;
5132
5133 bool restart_sync_ = false;
5134 bool reset_handle_sync_ = false;
5135
5136 ClientSocketHandle handle_;
5137 int auth_count_ = 0;
5138 TestCompletionCallback callback_;
5139
5140 DISALLOW_COPY_AND_ASSIGN(TestAuthHelper);
5141};
5142
5143TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnce) {
5144 CreatePool(1, 1);
5145 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5146
5147 TestAuthHelper auth_helper;
5148 auth_helper.InitHandle(params_, pool_.get());
Matt Menke9fa17d52019-03-25 19:12:265149 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menke4b69f932019-03-04 16:20:015150 EXPECT_EQ(LOAD_STATE_CONNECTING,
Matt Menkec6b3edf72019-03-19 17:00:395151 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:105152
5153 auth_helper.WaitForAuth();
Matt Menke9fa17d52019-03-25 19:12:265154 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menke4b69f932019-03-04 16:20:015155 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
Matt Menkec6b3edf72019-03-19 17:00:395156 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:105157
5158 auth_helper.RestartWithAuth();
Matt Menke9fa17d52019-03-25 19:12:265159 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menke4b69f932019-03-04 16:20:015160 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
Matt Menkec6b3edf72019-03-19 17:00:395161 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:105162
5163 EXPECT_THAT(auth_helper.WaitForResult(), IsOk());
5164 EXPECT_EQ(1, auth_helper.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265165 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5166 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:395167 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105168 EXPECT_EQ(0, pool_->IdleSocketCount());
5169}
5170
5171TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceSync) {
5172 CreatePool(1, 1);
5173 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5174
5175 TestAuthHelper auth_helper;
5176 auth_helper.InitHandle(params_, pool_.get());
Matt Menke9fa17d52019-03-25 19:12:265177 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menke4b69f932019-03-04 16:20:015178 EXPECT_EQ(LOAD_STATE_CONNECTING,
Matt Menkec6b3edf72019-03-19 17:00:395179 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:105180
5181 auth_helper.WaitForAuthAndRestartSync();
Matt Menke9fa17d52019-03-25 19:12:265182 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menke4b69f932019-03-04 16:20:015183 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
Matt Menkec6b3edf72019-03-19 17:00:395184 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:105185
5186 EXPECT_THAT(auth_helper.WaitForResult(), IsOk());
5187 EXPECT_EQ(1, auth_helper.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265188 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5189 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:395190 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105191 EXPECT_EQ(0, pool_->IdleSocketCount());
5192}
5193
5194TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceFails) {
5195 CreatePool(1, 1);
5196 connect_job_factory_->set_job_type(
5197 TestConnectJob::kMockAuthChallengeOnceFailingJob);
5198
5199 TestAuthHelper auth_helper;
5200 auth_helper.InitHandle(params_, pool_.get());
Matt Menke9fa17d52019-03-25 19:12:265201 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105202
5203 auth_helper.WaitForAuth();
5204 auth_helper.RestartWithAuth();
5205 EXPECT_THAT(auth_helper.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
5206
5207 EXPECT_EQ(1, auth_helper.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265208 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105209 EXPECT_EQ(0, pool_->IdleSocketCount());
5210}
5211
5212TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceSyncFails) {
5213 CreatePool(1, 1);
5214 connect_job_factory_->set_job_type(
5215 TestConnectJob::kMockAuthChallengeOnceFailingJob);
5216
5217 TestAuthHelper auth_helper;
5218 auth_helper.InitHandle(params_, pool_.get());
Matt Menke9fa17d52019-03-25 19:12:265219 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105220
5221 auth_helper.WaitForAuthAndRestartSync();
5222 EXPECT_THAT(auth_helper.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
5223
5224 EXPECT_EQ(1, auth_helper.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265225 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105226 EXPECT_EQ(0, pool_->IdleSocketCount());
5227}
5228
5229TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceDeleteHandle) {
5230 CreatePool(1, 1);
5231 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5232
5233 TestAuthHelper auth_helper;
5234 auth_helper.InitHandle(params_, pool_.get());
Matt Menke9fa17d52019-03-25 19:12:265235 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105236
5237 auth_helper.WaitForAuth();
Matt Menke9fa17d52019-03-25 19:12:265238 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105239
5240 auth_helper.handle()->Reset();
5241
5242 EXPECT_EQ(1, auth_helper.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265243 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105244 EXPECT_EQ(0, pool_->IdleSocketCount());
5245 EXPECT_FALSE(auth_helper.handle()->is_initialized());
5246 EXPECT_FALSE(auth_helper.handle()->socket());
5247}
5248
5249TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceDeleteHandleSync) {
5250 CreatePool(1, 1);
5251 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5252
5253 TestAuthHelper auth_helper;
5254 auth_helper.InitHandle(params_, pool_.get());
Matt Menke9fa17d52019-03-25 19:12:265255 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105256
5257 auth_helper.WaitForAuthAndResetHandleSync();
5258 EXPECT_EQ(1, auth_helper.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265259 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105260 EXPECT_EQ(0, pool_->IdleSocketCount());
5261 EXPECT_FALSE(auth_helper.handle()->is_initialized());
5262 EXPECT_FALSE(auth_helper.handle()->socket());
5263}
5264
5265TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceFlushWithError) {
5266 CreatePool(1, 1);
5267 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5268
5269 TestAuthHelper auth_helper;
5270 auth_helper.InitHandle(params_, pool_.get());
Matt Menke9fa17d52019-03-25 19:12:265271 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105272
5273 auth_helper.WaitForAuth();
5274
5275 pool_->FlushWithError(ERR_FAILED);
5276 base::RunLoop().RunUntilIdle();
5277
5278 // When flushing the socket pool, bound sockets should delay returning the
5279 // error until completion.
5280 EXPECT_FALSE(auth_helper.have_result());
Matt Menke9fa17d52019-03-25 19:12:265281 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105282 EXPECT_EQ(0, pool_->IdleSocketCount());
5283
5284 auth_helper.RestartWithAuth();
5285 // The callback should be called asynchronously.
5286 EXPECT_FALSE(auth_helper.have_result());
5287
5288 EXPECT_THAT(auth_helper.WaitForResult(), IsError(ERR_FAILED));
Matt Menke9fa17d52019-03-25 19:12:265289 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105290 EXPECT_EQ(0, pool_->IdleSocketCount());
5291}
5292
5293TEST_F(ClientSocketPoolBaseTest, ProxyAuthTwice) {
5294 CreatePool(1, 1);
5295 connect_job_factory_->set_job_type(
5296 TestConnectJob::kMockAuthChallengeTwiceJob);
5297
5298 TestAuthHelper auth_helper;
5299 auth_helper.InitHandle(params_, pool_.get());
Matt Menke9fa17d52019-03-25 19:12:265300 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menke4b69f932019-03-04 16:20:015301 EXPECT_EQ(LOAD_STATE_CONNECTING,
Matt Menkec6b3edf72019-03-19 17:00:395302 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:105303
5304 auth_helper.WaitForAuth();
5305 auth_helper.RestartWithAuth();
Matt Menke9fa17d52019-03-25 19:12:265306 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105307 EXPECT_EQ(1, auth_helper.auth_count());
Matt Menke4b69f932019-03-04 16:20:015308 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
Matt Menkec6b3edf72019-03-19 17:00:395309 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:105310
5311 auth_helper.WaitForAuth();
Matt Menke9fa17d52019-03-25 19:12:265312 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menke4b69f932019-03-04 16:20:015313 EXPECT_EQ(2, auth_helper.auth_count());
5314 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
Matt Menkec6b3edf72019-03-19 17:00:395315 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
Matt Menke4b69f932019-03-04 16:20:015316
Matt Menkeb57663b32019-03-01 17:17:105317 auth_helper.RestartWithAuth();
Matt Menke9fa17d52019-03-25 19:12:265318 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105319 EXPECT_EQ(2, auth_helper.auth_count());
Matt Menke4b69f932019-03-04 16:20:015320 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
Matt Menkec6b3edf72019-03-19 17:00:395321 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:105322
5323 EXPECT_THAT(auth_helper.WaitForResult(), IsOk());
5324 EXPECT_EQ(2, auth_helper.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265325 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5326 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:395327 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105328 EXPECT_EQ(0, pool_->IdleSocketCount());
5329}
5330
5331TEST_F(ClientSocketPoolBaseTest, ProxyAuthTwiceFails) {
5332 CreatePool(1, 1);
5333 connect_job_factory_->set_job_type(
5334 TestConnectJob::kMockAuthChallengeTwiceFailingJob);
5335
5336 TestAuthHelper auth_helper;
5337 auth_helper.InitHandle(params_, pool_.get());
Matt Menke9fa17d52019-03-25 19:12:265338 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105339
5340 auth_helper.WaitForAuth();
5341 auth_helper.RestartWithAuth();
Matt Menke9fa17d52019-03-25 19:12:265342 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105343 EXPECT_EQ(1, auth_helper.auth_count());
5344
5345 auth_helper.WaitForAuth();
5346 auth_helper.RestartWithAuth();
Matt Menke9fa17d52019-03-25 19:12:265347 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105348 EXPECT_EQ(2, auth_helper.auth_count());
5349
5350 EXPECT_THAT(auth_helper.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
5351 EXPECT_EQ(2, auth_helper.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265352 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105353 EXPECT_EQ(0, pool_->IdleSocketCount());
5354}
5355
5356// Makes sure that when a bound request is destroyed, a new ConnectJob is
5357// created, if needed.
5358TEST_F(ClientSocketPoolBaseTest,
5359 ProxyAuthCreateNewConnectJobOnDestroyBoundRequest) {
5360 CreatePool(1 /* max_sockets */, 1 /* max_sockets_per_group */);
5361 connect_job_factory_->set_job_type(
5362 TestConnectJob::kMockAuthChallengeOnceFailingJob);
5363
5364 // First request creates a ConnectJob.
5365 TestAuthHelper auth_helper1;
5366 auth_helper1.InitHandle(params_, pool_.get());
Matt Menke9fa17d52019-03-25 19:12:265367 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105368
5369 // A second request come in, but no new ConnectJob is needed, since the limit
5370 // has been reached.
5371 TestAuthHelper auth_helper2;
5372 auth_helper2.InitHandle(params_, pool_.get());
Matt Menke9fa17d52019-03-25 19:12:265373 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105374
5375 // Run until the auth callback for the first request is invoked.
5376 auth_helper1.WaitForAuth();
5377 EXPECT_EQ(0, auth_helper2.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265378 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5379 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:395380 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105381
5382 // Make connect jobs succeed, then cancel the first request, which should
5383 // destroy the bound ConnectJob, and cause a new ConnectJob to start.
5384 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
5385 auth_helper1.handle()->Reset();
5386 EXPECT_EQ(0, auth_helper2.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265387 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105388
5389 // The second ConnectJob should succeed.
5390 EXPECT_THAT(auth_helper2.WaitForResult(), IsOk());
5391 EXPECT_EQ(0, auth_helper2.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265392 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105393}
5394
5395// Makes sure that when a bound request is destroyed, a new ConnectJob is
5396// created for another group, if needed.
5397TEST_F(ClientSocketPoolBaseTest,
5398 ProxyAuthCreateNewConnectJobOnDestroyBoundRequestDifferentGroups) {
5399 CreatePool(1 /* max_sockets */, 1 /* max_sockets_per_group */);
5400 connect_job_factory_->set_job_type(
5401 TestConnectJob::kMockAuthChallengeOnceFailingJob);
5402
5403 // First request creates a ConnectJob.
5404 TestAuthHelper auth_helper1;
5405 auth_helper1.InitHandle(params_, pool_.get(), DEFAULT_PRIORITY);
Matt Menke9fa17d52019-03-25 19:12:265406 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105407
5408 // A second request come in, but no new ConnectJob is needed, since the limit
5409 // has been reached.
5410 TestAuthHelper auth_helper2;
5411 auth_helper2.InitHandle(params_, pool_.get(), DEFAULT_PRIORITY,
Matt Menkec6b3edf72019-03-19 17:00:395412 ClientSocketPool::RespectLimits::ENABLED,
5413 TestGroupId("b"));
Matt Menke9fa17d52019-03-25 19:12:265414 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5415 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
Matt Menkeb57663b32019-03-01 17:17:105416
5417 // Run until the auth callback for the first request is invoked.
5418 auth_helper1.WaitForAuth();
5419 EXPECT_EQ(0, auth_helper2.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265420 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5421 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:395422 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menke9fa17d52019-03-25 19:12:265423 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
5424 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("b")));
Matt Menkec6b3edf72019-03-19 17:00:395425 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("b")));
Matt Menkeb57663b32019-03-01 17:17:105426
5427 // Make connect jobs succeed, then cancel the first request, which should
5428 // destroy the bound ConnectJob, and cause a new ConnectJob to start for the
5429 // other group.
5430 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
5431 auth_helper1.handle()->Reset();
5432 EXPECT_EQ(0, auth_helper2.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265433 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
5434 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
Matt Menkeb57663b32019-03-01 17:17:105435
5436 // The second ConnectJob should succeed.
5437 EXPECT_THAT(auth_helper2.WaitForResult(), IsOk());
5438 EXPECT_EQ(0, auth_helper2.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265439 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
5440 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
Matt Menkeb57663b32019-03-01 17:17:105441}
5442
5443// Test that once an auth challenge is bound, that's the request that gets all
5444// subsequent calls and the socket itself.
5445TEST_F(ClientSocketPoolBaseTest, ProxyAuthStaysBound) {
5446 CreatePool(1, 1);
5447 connect_job_factory_->set_job_type(
5448 TestConnectJob::kMockAuthChallengeTwiceJob);
5449
5450 // First request creates a ConnectJob.
5451 TestAuthHelper auth_helper1;
5452 auth_helper1.InitHandle(params_, pool_.get(), LOWEST);
Matt Menke9fa17d52019-03-25 19:12:265453 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105454
5455 // A second, higher priority request is made.
5456 TestAuthHelper auth_helper2;
5457 auth_helper2.InitHandle(params_, pool_.get(), LOW);
Matt Menke9fa17d52019-03-25 19:12:265458 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105459
5460 // Run until the auth callback for the second request is invoked.
5461 auth_helper2.WaitForAuth();
5462 EXPECT_EQ(0, auth_helper1.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265463 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5464 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:395465 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105466
5467 // Start a higher priority job. It shouldn't be able to steal |auth_helper2|'s
5468 // ConnectJob.
5469 TestAuthHelper auth_helper3;
5470 auth_helper3.InitHandle(params_, pool_.get(), HIGHEST);
Matt Menke9fa17d52019-03-25 19:12:265471 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105472
5473 // Start a higher job that ignores limits, creating a hanging socket. It
5474 // shouldn't be able to steal |auth_helper2|'s ConnectJob.
5475 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
5476 TestAuthHelper auth_helper4;
5477 auth_helper4.InitHandle(params_, pool_.get(), HIGHEST,
5478 ClientSocketPool::RespectLimits::DISABLED);
Matt Menke9fa17d52019-03-25 19:12:265479 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105480
5481 // Restart with auth, and |auth_helper2|'s auth method should be invoked
5482 // again.
5483 auth_helper2.RestartWithAuth();
5484 auth_helper2.WaitForAuth();
5485 EXPECT_EQ(0, auth_helper1.auth_count());
5486 EXPECT_FALSE(auth_helper1.have_result());
5487 EXPECT_EQ(2, auth_helper2.auth_count());
5488 EXPECT_FALSE(auth_helper2.have_result());
5489 EXPECT_EQ(0, auth_helper3.auth_count());
5490 EXPECT_FALSE(auth_helper3.have_result());
5491 EXPECT_EQ(0, auth_helper4.auth_count());
5492 EXPECT_FALSE(auth_helper4.have_result());
5493
5494 // Advance auth again, and |auth_helper2| should get the socket.
5495 auth_helper2.RestartWithAuth();
5496 EXPECT_THAT(auth_helper2.WaitForResult(), IsOk());
5497 // The hung ConnectJob for the RespectLimits::DISABLED request is still in the
5498 // socket pool.
Matt Menke9fa17d52019-03-25 19:12:265499 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5500 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105501 EXPECT_EQ(0, auth_helper1.auth_count());
5502 EXPECT_FALSE(auth_helper1.have_result());
5503 EXPECT_EQ(0, auth_helper3.auth_count());
5504 EXPECT_FALSE(auth_helper3.have_result());
5505 EXPECT_EQ(0, auth_helper4.auth_count());
5506 EXPECT_FALSE(auth_helper4.have_result());
5507
5508 // If the socket is returned to the socket pool, the RespectLimits::DISABLED
5509 // socket request should be able to claim it.
5510 auth_helper2.handle()->Reset();
5511 EXPECT_THAT(auth_helper4.WaitForResult(), IsOk());
5512 EXPECT_EQ(0, auth_helper1.auth_count());
5513 EXPECT_FALSE(auth_helper1.have_result());
5514 EXPECT_EQ(0, auth_helper3.auth_count());
5515 EXPECT_FALSE(auth_helper3.have_result());
5516 EXPECT_EQ(0, auth_helper4.auth_count());
5517}
5518
Matt Menkebf3c767d2019-04-15 23:28:245519TEST_F(ClientSocketPoolBaseTest, RefreshGroupCreatesNewConnectJobs) {
5520 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
5521 const ClientSocketPool::GroupId kGroupId = TestGroupId("a");
5522
5523 // First job will be waiting until it gets aborted.
5524 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
5525
5526 ClientSocketHandle handle;
5527 TestCompletionCallback callback;
5528 EXPECT_THAT(
Matt Menkef09e64c2019-04-23 22:16:285529 handle.Init(kGroupId, params_, base::nullopt, DEFAULT_PRIORITY,
5530 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5531 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5532 pool_.get(), NetLogWithSource()),
Matt Menkebf3c767d2019-04-15 23:28:245533 IsError(ERR_IO_PENDING));
5534
5535 // Switch connect job types, so creating a new ConnectJob will result in
5536 // success.
5537 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
5538
5539 pool_->RefreshGroupForTesting(kGroupId);
5540 EXPECT_EQ(OK, callback.WaitForResult());
5541 ASSERT_TRUE(handle.socket());
5542 EXPECT_EQ(0, pool_->IdleSocketCount());
5543 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId));
5544 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(kGroupId));
5545 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(kGroupId));
5546 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId));
5547}
5548
5549TEST_F(ClientSocketPoolBaseTest, RefreshGroupClosesIdleConnectJobs) {
5550 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
5551 const ClientSocketPool::GroupId kGroupId = TestGroupId("a");
5552
Matt Menkef09e64c2019-04-23 22:16:285553 pool_->RequestSockets(kGroupId, params_, base::nullopt, 2,
5554 NetLogWithSource());
Matt Menkebf3c767d2019-04-15 23:28:245555 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId));
5556 EXPECT_EQ(2, pool_->IdleSocketCount());
5557 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(kGroupId));
5558
5559 pool_->RefreshGroupForTesting(kGroupId);
5560 EXPECT_EQ(0, pool_->IdleSocketCount());
5561 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupId));
5562}
5563
5564TEST_F(ClientSocketPoolBaseTest,
5565 RefreshGroupDoesNotCloseIdleConnectJobsInOtherGroup) {
5566 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
5567 const ClientSocketPool::GroupId kGroupId = TestGroupId("a");
5568 const ClientSocketPool::GroupId kOtherGroupId = TestGroupId("b");
5569
Matt Menkef09e64c2019-04-23 22:16:285570 pool_->RequestSockets(kOtherGroupId, params_, base::nullopt, 2,
5571 NetLogWithSource());
Matt Menkebf3c767d2019-04-15 23:28:245572 ASSERT_TRUE(pool_->HasGroupForTesting(kOtherGroupId));
5573 EXPECT_EQ(2, pool_->IdleSocketCount());
5574 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(kOtherGroupId));
5575
5576 pool_->RefreshGroupForTesting(kGroupId);
5577 ASSERT_TRUE(pool_->HasGroupForTesting(kOtherGroupId));
5578 EXPECT_EQ(2, pool_->IdleSocketCount());
5579 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(kOtherGroupId));
5580}
5581
5582TEST_F(ClientSocketPoolBaseTest, RefreshGroupPreventsSocketReuse) {
5583 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
5584 const ClientSocketPool::GroupId kGroupId = TestGroupId("a");
5585
5586 ClientSocketHandle handle;
5587 TestCompletionCallback callback;
5588 EXPECT_THAT(
Matt Menkef09e64c2019-04-23 22:16:285589 handle.Init(kGroupId, params_, base::nullopt, DEFAULT_PRIORITY,
5590 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5591 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5592 pool_.get(), NetLogWithSource()),
Matt Menkebf3c767d2019-04-15 23:28:245593 IsOk());
5594 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId));
5595 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId));
5596
5597 pool_->RefreshGroupForTesting(kGroupId);
5598
5599 handle.Reset();
5600 EXPECT_EQ(0, pool_->IdleSocketCount());
5601 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupId));
5602}
5603
5604TEST_F(ClientSocketPoolBaseTest,
5605 RefreshGroupDoesNotPreventSocketReuseInOtherGroup) {
5606 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
5607 const ClientSocketPool::GroupId kGroupId = TestGroupId("a");
5608 const ClientSocketPool::GroupId kOtherGroupId = TestGroupId("b");
5609
5610 ClientSocketHandle handle;
5611 TestCompletionCallback callback;
5612 EXPECT_THAT(
Matt Menkef09e64c2019-04-23 22:16:285613 handle.Init(kOtherGroupId, params_, base::nullopt, DEFAULT_PRIORITY,
5614 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5615 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5616 pool_.get(), NetLogWithSource()),
Matt Menkebf3c767d2019-04-15 23:28:245617 IsOk());
5618 ASSERT_TRUE(pool_->HasGroupForTesting(kOtherGroupId));
5619 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kOtherGroupId));
5620
5621 pool_->RefreshGroupForTesting(kGroupId);
5622
5623 handle.Reset();
5624 EXPECT_EQ(1, pool_->IdleSocketCount());
5625 ASSERT_TRUE(pool_->HasGroupForTesting(kOtherGroupId));
5626 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(kOtherGroupId));
5627}
5628
5629TEST_F(ClientSocketPoolBaseTest, RefreshGroupReplacesBoundConnectJobOnConnect) {
5630 CreatePool(1, 1);
5631 const ClientSocketPool::GroupId kGroupId = TestGroupId("a");
5632 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5633
5634 TestAuthHelper auth_helper;
5635 auth_helper.InitHandle(params_, pool_.get(), DEFAULT_PRIORITY,
5636 ClientSocketPool::RespectLimits::ENABLED, kGroupId);
5637 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(kGroupId));
5638
5639 auth_helper.WaitForAuth();
5640
5641 // This should update the generation, but not cancel the old ConnectJob - it's
5642 // not safe to do anything while waiting on the original ConnectJob.
5643 pool_->RefreshGroupForTesting(kGroupId);
5644
5645 // Providing auth credentials and restarting the request with them will cause
5646 // the ConnectJob to complete successfully, but the result will be discarded
5647 // because of the generation mismatch.
5648 auth_helper.RestartWithAuth();
5649
5650 // Despite using ConnectJobs that simulate a single challenge, a second
5651 // challenge will be seen, due to using a new ConnectJob.
5652 auth_helper.WaitForAuth();
5653 auth_helper.RestartWithAuth();
5654
5655 EXPECT_THAT(auth_helper.WaitForResult(), IsOk());
5656 EXPECT_TRUE(auth_helper.handle()->socket());
5657 EXPECT_EQ(2, auth_helper.auth_count());
5658
5659 // When released, the socket will be returned to the socket pool, and
5660 // available for reuse.
5661 auth_helper.handle()->Reset();
5662 EXPECT_EQ(1, pool_->IdleSocketCount());
5663 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId));
5664 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(kGroupId));
5665}
5666
[email protected]f6d1d6eb2009-06-24 20:16:095667} // namespace
5668
5669} // namespace net