blob: 250d33a98d1e64feef042d175a0f4a5f6b6c6e2a [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"
Hans Wennborg0924470b2020-04-27 21:08:0514#include "base/check_op.h"
skyostil4891b25b2015-06-11 11:43:4515#include "base/location.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"
Hans Wennborg0924470b2020-04-27 21:08:0518#include "base/notreached.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"
Matt Menke166443c2019-05-24 18:45:5925#include "base/test/scoped_feature_list.h"
[email protected]f214f8792011-01-01 02:17:0826#include "base/threading/platform_thread.h"
gabf767595f2016-05-11 18:50:3527#include "base/threading/thread_task_runner_handle.h"
[email protected]f3a1c642011-07-12 19:15:0328#include "base/values.h"
Matt Menke166443c2019-05-24 18:45:5929#include "net/base/features.h"
[email protected]034df0f32013-01-07 23:17:4830#include "net/base/load_timing_info.h"
[email protected]b258e0792013-01-12 07:11:5931#include "net/base/load_timing_info_test_util.h"
[email protected]d8eb84242010-09-25 02:25:0632#include "net/base/net_errors.h"
Matt Menke166443c2019-05-24 18:45:5933#include "net/base/network_isolation_key.h"
Matt Menkebdf777802019-04-22 19:38:5934#include "net/base/privacy_mode.h"
Matt Menkeaafff542019-04-22 22:09:3635#include "net/base/proxy_server.h"
[email protected]ac790b42009-12-02 04:31:3136#include "net/base/request_priority.h"
[email protected]f6d1d6eb2009-06-24 20:16:0937#include "net/base/test_completion_callback.h"
dalykedd30d982019-12-16 15:31:1038#include "net/dns/public/resolve_error_info.h"
[email protected]277d5942010-08-11 21:02:3539#include "net/http/http_response_headers.h"
Matt Menke39b7c5a2019-04-10 19:47:5140#include "net/http/http_response_info.h"
eroman87c53d62015-04-02 06:51:0741#include "net/log/net_log.h"
mikecirone8b85c432016-09-08 19:11:0042#include "net/log/net_log_event_type.h"
mikecironef22f9812016-10-04 03:40:1943#include "net/log/net_log_source.h"
mikecirone8b85c432016-09-08 19:11:0044#include "net/log/net_log_source_type.h"
mmenke16a7cbdd2015-04-24 23:00:5645#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4646#include "net/log/test_net_log_util.h"
[email protected]f6d1d6eb2009-06-24 20:16:0947#include "net/socket/client_socket_factory.h"
48#include "net/socket/client_socket_handle.h"
tfarina5dd13c22016-11-16 12:08:2649#include "net/socket/datagram_client_socket.h"
tbansalca83c002016-04-28 20:56:2850#include "net/socket/socket_performance_watcher.h"
Paul Jensen8d6f87ec2018-01-13 00:46:5451#include "net/socket/socket_tag.h"
[email protected]75439d3b2009-07-23 22:11:1752#include "net/socket/socket_test_util.h"
[email protected]18ccfdb2013-08-15 00:13:4453#include "net/socket/ssl_client_socket.h"
[email protected]3268023f2011-05-05 00:08:1054#include "net/socket/stream_socket.h"
Matt Menke9fa17d52019-03-25 19:12:2655#include "net/socket/transport_connect_job.h"
Matt Menke39b7c5a2019-04-10 19:47:5156#include "net/ssl/ssl_cert_request_info.h"
robpercival214763f2016-07-01 23:27:0157#include "net/test/gtest_util.h"
Gabriel Charettec7108742019-08-23 03:31:4058#include "net/test/test_with_task_environment.h"
Matt Menkef09e64c2019-04-23 22:16:2859#include "net/traffic_annotation/network_traffic_annotation.h"
Ramin Halavati0a08cc82018-02-06 07:46:3860#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
[email protected]51fdc7c2012-04-10 19:19:4861#include "testing/gmock/include/gmock/gmock.h"
[email protected]f6d1d6eb2009-06-24 20:16:0962#include "testing/gtest/include/gtest/gtest.h"
63
robpercival214763f2016-07-01 23:27:0164using net::test::IsError;
65using net::test::IsOk;
66
[email protected]51fdc7c2012-04-10 19:19:4867using ::testing::Invoke;
68using ::testing::Return;
69
[email protected]f6d1d6eb2009-06-24 20:16:0970namespace net {
71
72namespace {
73
[email protected]211d21722009-07-22 15:48:5374const int kDefaultMaxSockets = 4;
[email protected]c9d6a1d2009-07-14 16:15:2075const int kDefaultMaxSocketsPerGroup = 2;
Tarun Bansala7635092019-02-20 10:00:5976constexpr base::TimeDelta kUnusedIdleSocketTimeout =
77 base::TimeDelta::FromSeconds(10);
[email protected]0b7648c2009-07-06 20:14:0178
Matt Menkebdf777802019-04-22 19:38:5979ClientSocketPool::GroupId TestGroupId(
80 const std::string& host,
81 int port = 80,
82 ClientSocketPool::SocketType socket_type =
83 ClientSocketPool::SocketType::kHttp,
Matt Menke166443c2019-05-24 18:45:5984 PrivacyMode privacy_mode = PrivacyMode::PRIVACY_MODE_DISABLED,
85 NetworkIsolationKey network_isolation_key = NetworkIsolationKey()) {
dalyk5f48a132019-10-14 15:20:1986 bool disable_secure_dns = false;
Matt Menkec6b3edf72019-03-19 17:00:3987 return ClientSocketPool::GroupId(HostPortPair(host, port), socket_type,
dalyk5f48a132019-10-14 15:20:1988 privacy_mode, network_isolation_key,
89 disable_secure_dns);
Matt Menkec6b3edf72019-03-19 17:00:3990}
91
[email protected]034df0f32013-01-07 23:17:4892// Make sure |handle| sets load times correctly when it has been assigned a
93// reused socket.
94void TestLoadTimingInfoConnectedReused(const ClientSocketHandle& handle) {
95 LoadTimingInfo load_timing_info;
96 // Only pass true in as |is_reused|, as in general, HttpStream types should
97 // have stricter concepts of reuse than socket pools.
98 EXPECT_TRUE(handle.GetLoadTimingInfo(true, &load_timing_info));
99
100 EXPECT_EQ(true, load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19101 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]034df0f32013-01-07 23:17:48102
[email protected]b258e0792013-01-12 07:11:59103 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
104 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:48105}
106
107// Make sure |handle| sets load times correctly when it has been assigned a
[email protected]b021ece62013-06-11 11:06:33108// fresh socket. Also runs TestLoadTimingInfoConnectedReused, since the owner
[email protected]034df0f32013-01-07 23:17:48109// of a connection where |is_reused| is false may consider the connection
110// reused.
111void TestLoadTimingInfoConnectedNotReused(const ClientSocketHandle& handle) {
112 EXPECT_FALSE(handle.is_reused());
113
114 LoadTimingInfo load_timing_info;
115 EXPECT_TRUE(handle.GetLoadTimingInfo(false, &load_timing_info));
116
117 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19118 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]034df0f32013-01-07 23:17:48119
[email protected]b258e0792013-01-12 07:11:59120 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
121 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
122 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:48123
124 TestLoadTimingInfoConnectedReused(handle);
125}
126
127// Make sure |handle| sets load times correctly, in the case that it does not
128// currently have a socket.
129void TestLoadTimingInfoNotConnected(const ClientSocketHandle& handle) {
130 // Should only be set to true once a socket is assigned, if at all.
131 EXPECT_FALSE(handle.is_reused());
132
133 LoadTimingInfo load_timing_info;
134 EXPECT_FALSE(handle.GetLoadTimingInfo(false, &load_timing_info));
135
136 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19137 EXPECT_EQ(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]034df0f32013-01-07 23:17:48138
[email protected]b258e0792013-01-12 07:11:59139 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
140 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:48141}
142
[email protected]3268023f2011-05-05 00:08:10143class MockClientSocket : public StreamSocket {
[email protected]f6d1d6eb2009-06-24 20:16:09144 public:
[email protected]034df0f32013-01-07 23:17:48145 explicit MockClientSocket(net::NetLog* net_log)
146 : connected_(false),
[email protected]0dc88b32014-03-26 20:12:28147 has_unread_data_(false),
tfarina428341112016-09-22 13:38:20148 net_log_(NetLogWithSource::Make(net_log, NetLogSourceType::SOCKET)),
Charlie Harrison3e4c0622018-05-13 15:44:30149 was_used_to_convey_data_(false) {}
[email protected]f6d1d6eb2009-06-24 20:16:09150
[email protected]0dc88b32014-03-26 20:12:28151 // Sets whether the socket has unread data. If true, the next call to Read()
152 // will return 1 byte and IsConnectedAndIdle() will return false.
153 void set_has_unread_data(bool has_unread_data) {
154 has_unread_data_ = has_unread_data;
155 }
156
[email protected]3f55aa12011-12-07 02:03:33157 // Socket implementation.
dchengb03027d2014-10-21 12:00:20158 int Read(IOBuffer* /* buf */,
159 int len,
Brad Lassey3a814172018-04-26 03:30:21160 CompletionOnceCallback /* callback */) override {
[email protected]0dc88b32014-03-26 20:12:28161 if (has_unread_data_ && len > 0) {
162 has_unread_data_ = false;
163 was_used_to_convey_data_ = true;
164 return 1;
165 }
[email protected]e86df8dc2013-03-30 13:18:28166 return ERR_UNEXPECTED;
[email protected]3f55aa12011-12-07 02:03:33167 }
[email protected]ab838892009-06-30 18:49:05168
[email protected]a2b2cfc2017-12-06 09:06:08169 int Write(
170 IOBuffer* /* buf */,
171 int len,
Brad Lassey3a814172018-04-26 03:30:21172 CompletionOnceCallback /* callback */,
[email protected]a2b2cfc2017-12-06 09:06:08173 const NetworkTrafficAnnotationTag& /*traffic_annotation*/) override {
[email protected]0f873e82010-09-02 16:09:01174 was_used_to_convey_data_ = true;
175 return len;
[email protected]ab838892009-06-30 18:49:05176 }
Avi Drissman13fc8932015-12-20 04:40:46177 int SetReceiveBufferSize(int32_t size) override { return OK; }
178 int SetSendBufferSize(int32_t size) override { return OK; }
[email protected]ab838892009-06-30 18:49:05179
[email protected]dbf036f2011-12-06 23:33:24180 // StreamSocket implementation.
Brad Lassey3a814172018-04-26 03:30:21181 int Connect(CompletionOnceCallback callback) override {
[email protected]dbf036f2011-12-06 23:33:24182 connected_ = true;
183 return OK;
184 }
[email protected]f6d1d6eb2009-06-24 20:16:09185
dchengb03027d2014-10-21 12:00:20186 void Disconnect() override { connected_ = false; }
187 bool IsConnected() const override { return connected_; }
188 bool IsConnectedAndIdle() const override {
[email protected]0dc88b32014-03-26 20:12:28189 return connected_ && !has_unread_data_;
190 }
[email protected]0b7648c2009-07-06 20:14:01191
dchengb03027d2014-10-21 12:00:20192 int GetPeerAddress(IPEndPoint* /* address */) const override {
[email protected]9f864b32010-01-20 15:01:16193 return ERR_UNEXPECTED;
[email protected]f6d1d6eb2009-06-24 20:16:09194 }
[email protected]f6d1d6eb2009-06-24 20:16:09195
dchengb03027d2014-10-21 12:00:20196 int GetLocalAddress(IPEndPoint* /* address */) const override {
[email protected]e7f74da2011-04-19 23:49:35197 return ERR_UNEXPECTED;
198 }
199
tfarina428341112016-09-22 13:38:20200 const NetLogWithSource& NetLog() const override { return net_log_; }
[email protected]a2006ece2010-04-23 16:44:02201
dchengb03027d2014-10-21 12:00:20202 bool WasEverUsed() const override { return was_used_to_convey_data_; }
tfarina2846404c2016-12-25 14:31:37203 bool WasAlpnNegotiated() const override { return false; }
dchengb03027d2014-10-21 12:00:20204 NextProto GetNegotiatedProtocol() const override { return kProtoUnknown; }
205 bool GetSSLInfo(SSLInfo* ssl_info) override { return false; }
ttuttle23fdb7b2015-05-15 01:28:03206 void GetConnectionAttempts(ConnectionAttempts* out) const override {
207 out->clear();
208 }
209 void ClearConnectionAttempts() override {}
210 void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
tbansalf82cc8e2015-10-14 20:05:49211 int64_t GetTotalReceivedBytes() const override {
212 NOTIMPLEMENTED();
213 return 0;
214 }
Paul Jensen0f49dec2017-12-12 23:39:58215 void ApplySocketTag(const SocketTag& tag) override {}
[email protected]9b5614a2010-08-25 20:29:45216
[email protected]f6d1d6eb2009-06-24 20:16:09217 private:
218 bool connected_;
[email protected]0dc88b32014-03-26 20:12:28219 bool has_unread_data_;
tfarina428341112016-09-22 13:38:20220 NetLogWithSource net_log_;
[email protected]0f873e82010-09-02 16:09:01221 bool was_used_to_convey_data_;
[email protected]f6d1d6eb2009-06-24 20:16:09222
[email protected]ab838892009-06-30 18:49:05223 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
[email protected]f6d1d6eb2009-06-24 20:16:09224};
225
[email protected]5fc08e32009-07-15 17:09:57226class TestConnectJob;
227
[email protected]f6d1d6eb2009-06-24 20:16:09228class MockClientSocketFactory : public ClientSocketFactory {
229 public:
[email protected]ab838892009-06-30 18:49:05230 MockClientSocketFactory() : allocation_count_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:09231
danakj655b66c2016-04-16 00:51:38232 std::unique_ptr<DatagramClientSocket> CreateDatagramClientSocket(
[email protected]5370c012011-06-29 03:47:04233 DatagramSocket::BindType bind_type,
[email protected]98b0e582011-06-22 14:31:41234 NetLog* net_log,
mikecironef22f9812016-10-04 03:40:19235 const NetLogSource& source) override {
[email protected]98b0e582011-06-22 14:31:41236 NOTREACHED();
David Benjamin24725be2019-07-24 20:57:18237 return nullptr;
[email protected]98b0e582011-06-22 14:31:41238 }
239
Helen Lid5bb9222018-04-12 15:33:09240 std::unique_ptr<TransportClientSocket> CreateTransportClientSocket(
[email protected]0a0b7682010-08-25 17:08:07241 const AddressList& addresses,
danakj655b66c2016-04-16 00:51:38242 std::unique_ptr<
243 SocketPerformanceWatcher> /* socket_performance_watcher */,
[email protected]0a0b7682010-08-25 17:08:07244 NetLog* /* net_log */,
mikecironef22f9812016-10-04 03:40:19245 const NetLogSource& /*source*/) override {
[email protected]f6d1d6eb2009-06-24 20:16:09246 allocation_count_++;
Helen Lid5bb9222018-04-12 15:33:09247 return nullptr;
[email protected]f6d1d6eb2009-06-24 20:16:09248 }
249
danakj655b66c2016-04-16 00:51:38250 std::unique_ptr<SSLClientSocket> CreateSSLClientSocket(
David Benjamin24725be2019-07-24 20:57:18251 SSLClientContext* context,
Matt Menke841fc412019-03-05 23:20:12252 std::unique_ptr<StreamSocket> stream_socket,
[email protected]4f4de7e62010-11-12 19:55:27253 const HostPortPair& host_and_port,
David Benjamin24725be2019-07-24 20:57:18254 const SSLConfig& ssl_config) override {
[email protected]f6d1d6eb2009-06-24 20:16:09255 NOTIMPLEMENTED();
David Benjamin24725be2019-07-24 20:57:18256 return nullptr;
[email protected]f6d1d6eb2009-06-24 20:16:09257 }
Matt Menkefd956922019-02-04 23:44:03258
Matt Menke52cd95a2019-02-08 06:16:27259 std::unique_ptr<ProxyClientSocket> CreateProxyClientSocket(
260 std::unique_ptr<StreamSocket> stream_socket,
261 const std::string& user_agent,
262 const HostPortPair& endpoint,
263 const ProxyServer& proxy_server,
264 HttpAuthController* http_auth_controller,
265 bool tunnel,
266 bool using_spdy,
267 NextProto negotiated_protocol,
268 ProxyDelegate* proxy_delegate,
Matt Menke52cd95a2019-02-08 06:16:27269 const NetworkTrafficAnnotationTag& traffic_annotation) override {
270 NOTIMPLEMENTED();
271 return nullptr;
272 }
273
[email protected]5fc08e32009-07-15 17:09:57274 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
[email protected]03b7c8c2013-07-20 04:38:55275
[email protected]5fc08e32009-07-15 17:09:57276 void SignalJobs();
277
[email protected]03b7c8c2013-07-20 04:38:55278 void SignalJob(size_t job);
279
280 void SetJobLoadState(size_t job, LoadState load_state);
281
Matt Menke141b87f22019-01-30 02:43:03282 // Sets the HasConnectionEstablished value of the specified job to true,
283 // without invoking the callback.
284 void SetJobHasEstablishedConnection(size_t job);
285
[email protected]f6d1d6eb2009-06-24 20:16:09286 int allocation_count() const { return allocation_count_; }
287
[email protected]f6d1d6eb2009-06-24 20:16:09288 private:
289 int allocation_count_;
[email protected]5fc08e32009-07-15 17:09:57290 std::vector<TestConnectJob*> waiting_jobs_;
[email protected]f6d1d6eb2009-06-24 20:16:09291};
292
[email protected]ab838892009-06-30 18:49:05293class TestConnectJob : public ConnectJob {
294 public:
295 enum JobType {
296 kMockJob,
297 kMockFailingJob,
298 kMockPendingJob,
299 kMockPendingFailingJob,
[email protected]5fc08e32009-07-15 17:09:57300 kMockWaitingJob,
Matt Menkeb57663b32019-03-01 17:17:10301
302 // Certificate errors return a socket in addition to an error code.
303 kMockCertErrorJob,
304 kMockPendingCertErrorJob,
305
[email protected]e60e47a2010-07-14 03:37:18306 kMockAdditionalErrorStateJob,
307 kMockPendingAdditionalErrorStateJob,
[email protected]0dc88b32014-03-26 20:12:28308 kMockUnreadDataJob,
Matt Menkeb57663b32019-03-01 17:17:10309
310 kMockAuthChallengeOnceJob,
311 kMockAuthChallengeTwiceJob,
312 kMockAuthChallengeOnceFailingJob,
313 kMockAuthChallengeTwiceFailingJob,
[email protected]ab838892009-06-30 18:49:05314 };
315
[email protected]994d4932010-07-12 17:55:13316 // The kMockPendingJob uses a slight delay before allowing the connect
317 // to complete.
318 static const int kPendingConnectDelay = 2;
319
[email protected]ab838892009-06-30 18:49:05320 TestConnectJob(JobType job_type,
Matt Menke16f5c2e52019-03-25 21:50:40321 RequestPriority request_priority,
322 SocketTag socket_tag,
[email protected]974ebd62009-08-03 23:14:34323 base::TimeDelta timeout_duration,
Matt Menkea6f99ad2019-03-08 02:26:43324 const CommonConnectJobParams* common_connect_job_params,
[email protected]ab838892009-06-30 18:49:05325 ConnectJob::Delegate* delegate,
Matt Menkea6f99ad2019-03-08 02:26:43326 MockClientSocketFactory* client_socket_factory)
Matt Menke16f5c2e52019-03-25 21:50:40327 : ConnectJob(request_priority,
328 socket_tag,
Matt Menke1a6c92d2019-02-23 00:25:38329 timeout_duration,
Matt Menkea6f99ad2019-03-08 02:26:43330 common_connect_job_params,
Matt Menke1a6c92d2019-02-23 00:25:38331 delegate,
332 nullptr /* net_log */,
333 NetLogSourceType::TRANSPORT_CONNECT_JOB,
334 NetLogEventType::TRANSPORT_CONNECT_JOB_CONNECT),
[email protected]2ab05b52009-07-01 23:57:58335 job_type_(job_type),
[email protected]ab838892009-06-30 18:49:05336 client_socket_factory_(client_socket_factory),
[email protected]e60e47a2010-07-14 03:37:18337 load_state_(LOAD_STATE_IDLE),
Matt Menke141b87f22019-01-30 02:43:03338 has_established_connection_(false),
Jeremy Romand54000b22019-07-08 18:40:16339 store_additional_error_state_(false) {}
[email protected]ab838892009-06-30 18:49:05340
[email protected]974ebd62009-08-03 23:14:34341 void Signal() {
[email protected]e772db3f2010-07-12 18:11:13342 DoConnect(waiting_success_, true /* async */, false /* recoverable */);
[email protected]974ebd62009-08-03 23:14:34343 }
344
[email protected]03b7c8c2013-07-20 04:38:55345 void set_load_state(LoadState load_state) { load_state_ = load_state; }
346
Matt Menke141b87f22019-01-30 02:43:03347 void set_has_established_connection() {
348 DCHECK(!has_established_connection_);
349 has_established_connection_ = true;
350 }
351
[email protected]03b7c8c2013-07-20 04:38:55352 // From ConnectJob:
353
dchengb03027d2014-10-21 12:00:20354 LoadState GetLoadState() const override { return load_state_; }
[email protected]46451352009-09-01 14:54:21355
Matt Menke141b87f22019-01-30 02:43:03356 bool HasEstablishedConnection() const override {
357 return has_established_connection_;
358 }
359
dalykedd30d982019-12-16 15:31:10360 ResolveErrorInfo GetResolveErrorInfo() const override {
361 return ResolveErrorInfo(OK);
362 }
363
Matt Menke6f84d1f12019-04-11 19:26:47364 bool IsSSLError() const override { return store_additional_error_state_; }
365
366 scoped_refptr<SSLCertRequestInfo> GetCertRequestInfo() override {
367 if (store_additional_error_state_)
368 return base::MakeRefCounted<SSLCertRequestInfo>();
369 return nullptr;
[email protected]e60e47a2010-07-14 03:37:18370 }
371
[email protected]974ebd62009-08-03 23:14:34372 private:
[email protected]03b7c8c2013-07-20 04:38:55373 // From ConnectJob:
[email protected]ab838892009-06-30 18:49:05374
dchengb03027d2014-10-21 12:00:20375 int ConnectInternal() override {
[email protected]ab838892009-06-30 18:49:05376 AddressList ignored;
Raul Tambre94493c652019-03-11 17:18:35377 client_socket_factory_->CreateTransportClientSocket(
378 ignored, nullptr, nullptr, NetLogSource());
[email protected]ab838892009-06-30 18:49:05379 switch (job_type_) {
380 case kMockJob:
[email protected]e772db3f2010-07-12 18:11:13381 return DoConnect(true /* successful */, false /* sync */,
Matt Menkeb57663b32019-03-01 17:17:10382 false /* cert_error */);
[email protected]ab838892009-06-30 18:49:05383 case kMockFailingJob:
[email protected]e772db3f2010-07-12 18:11:13384 return DoConnect(false /* error */, false /* sync */,
Matt Menkeb57663b32019-03-01 17:17:10385 false /* cert_error */);
[email protected]ab838892009-06-30 18:49:05386 case kMockPendingJob:
[email protected]5fc08e32009-07-15 17:09:57387 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47388
389 // Depending on execution timings, posting a delayed task can result
390 // in the task getting executed the at the earliest possible
391 // opportunity or only after returning once from the message loop and
392 // then a second call into the message loop. In order to make behavior
393 // more deterministic, we change the default delay to 2ms. This should
394 // always require us to wait for the second call into the message loop.
395 //
396 // N.B. The correct fix for this and similar timing problems is to
397 // abstract time for the purpose of unittests. Unfortunately, we have
398 // a lot of third-party components that directly call the various
399 // time functions, so this change would be rather invasive.
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(), true /* successful */,
Matt Menkeb57663b32019-03-01 17:17:10404 true /* async */, false /* cert_error */),
[email protected]5761ab9c2012-02-04 16:44:53405 base::TimeDelta::FromMilliseconds(kPendingConnectDelay));
[email protected]ab838892009-06-30 18:49:05406 return ERR_IO_PENDING;
407 case kMockPendingFailingJob:
[email protected]5fc08e32009-07-15 17:09:57408 set_load_state(LOAD_STATE_CONNECTING);
skyostil4891b25b2015-06-11 11:43:45409 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05410 FROM_HERE,
kylecharf4fe5172019-02-15 18:53:49411 base::BindOnce(base::IgnoreResult(&TestConnectJob::DoConnect),
412 weak_factory_.GetWeakPtr(), false /* error */,
Matt Menkeb57663b32019-03-01 17:17:10413 true /* async */, false /* cert_error */),
[email protected]5761ab9c2012-02-04 16:44:53414 base::TimeDelta::FromMilliseconds(2));
[email protected]ab838892009-06-30 18:49:05415 return ERR_IO_PENDING;
[email protected]5fc08e32009-07-15 17:09:57416 case kMockWaitingJob:
[email protected]03b7c8c2013-07-20 04:38:55417 set_load_state(LOAD_STATE_CONNECTING);
[email protected]5fc08e32009-07-15 17:09:57418 client_socket_factory_->WaitForSignal(this);
419 waiting_success_ = true;
420 return ERR_IO_PENDING;
Matt Menkeb57663b32019-03-01 17:17:10421 case kMockCertErrorJob:
[email protected]e772db3f2010-07-12 18:11:13422 return DoConnect(false /* error */, false /* sync */,
Matt Menkeb57663b32019-03-01 17:17:10423 true /* cert_error */);
424 case kMockPendingCertErrorJob:
[email protected]e772db3f2010-07-12 18:11:13425 set_load_state(LOAD_STATE_CONNECTING);
skyostil4891b25b2015-06-11 11:43:45426 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]e772db3f2010-07-12 18:11:13427 FROM_HERE,
kylecharf4fe5172019-02-15 18:53:49428 base::BindOnce(base::IgnoreResult(&TestConnectJob::DoConnect),
429 weak_factory_.GetWeakPtr(), false /* error */,
Matt Menkeb57663b32019-03-01 17:17:10430 true /* async */, true /* cert_error */),
[email protected]5761ab9c2012-02-04 16:44:53431 base::TimeDelta::FromMilliseconds(2));
[email protected]e772db3f2010-07-12 18:11:13432 return ERR_IO_PENDING;
[email protected]e60e47a2010-07-14 03:37:18433 case kMockAdditionalErrorStateJob:
434 store_additional_error_state_ = true;
435 return DoConnect(false /* error */, false /* sync */,
Matt Menkeb57663b32019-03-01 17:17:10436 false /* cert_error */);
[email protected]e60e47a2010-07-14 03:37:18437 case kMockPendingAdditionalErrorStateJob:
438 set_load_state(LOAD_STATE_CONNECTING);
439 store_additional_error_state_ = true;
skyostil4891b25b2015-06-11 11:43:45440 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]e60e47a2010-07-14 03:37:18441 FROM_HERE,
kylecharf4fe5172019-02-15 18:53:49442 base::BindOnce(base::IgnoreResult(&TestConnectJob::DoConnect),
443 weak_factory_.GetWeakPtr(), false /* error */,
Matt Menkeb57663b32019-03-01 17:17:10444 true /* async */, false /* cert_error */),
[email protected]5761ab9c2012-02-04 16:44:53445 base::TimeDelta::FromMilliseconds(2));
[email protected]e60e47a2010-07-14 03:37:18446 return ERR_IO_PENDING;
[email protected]0dc88b32014-03-26 20:12:28447 case kMockUnreadDataJob: {
448 int ret = DoConnect(true /* successful */, false /* sync */,
Matt Menkeb57663b32019-03-01 17:17:10449 false /* cert_error */);
[email protected]0dc88b32014-03-26 20:12:28450 static_cast<MockClientSocket*>(socket())->set_has_unread_data(true);
451 return ret;
452 }
Matt Menkeb57663b32019-03-01 17:17:10453 case kMockAuthChallengeOnceJob:
Matt Menke4b69f932019-03-04 16:20:01454 set_load_state(LOAD_STATE_CONNECTING);
Matt Menkeb57663b32019-03-01 17:17:10455 DoAdvanceAuthChallenge(1, true /* succeed_after_last_challenge */);
456 return ERR_IO_PENDING;
457 case kMockAuthChallengeTwiceJob:
Matt Menke4b69f932019-03-04 16:20:01458 set_load_state(LOAD_STATE_CONNECTING);
Matt Menkeb57663b32019-03-01 17:17:10459 DoAdvanceAuthChallenge(2, true /* succeed_after_last_challenge */);
460 return ERR_IO_PENDING;
461 case kMockAuthChallengeOnceFailingJob:
Matt Menke4b69f932019-03-04 16:20:01462 set_load_state(LOAD_STATE_CONNECTING);
Matt Menkeb57663b32019-03-01 17:17:10463 DoAdvanceAuthChallenge(1, false /* succeed_after_last_challenge */);
464 return ERR_IO_PENDING;
465 case kMockAuthChallengeTwiceFailingJob:
Matt Menke4b69f932019-03-04 16:20:01466 set_load_state(LOAD_STATE_CONNECTING);
Matt Menkeb57663b32019-03-01 17:17:10467 DoAdvanceAuthChallenge(2, false /* succeed_after_last_challenge */);
468 return ERR_IO_PENDING;
[email protected]ab838892009-06-30 18:49:05469 default:
470 NOTREACHED();
danakj655b66c2016-04-16 00:51:38471 SetSocket(std::unique_ptr<StreamSocket>());
[email protected]ab838892009-06-30 18:49:05472 return ERR_FAILED;
473 }
474 }
475
Lily Chen02ef29a2018-11-30 16:31:43476 void ChangePriorityInternal(RequestPriority priority) override {}
477
Matt Menkeb57663b32019-03-01 17:17:10478 int DoConnect(bool succeed, bool was_async, bool cert_error) {
[email protected]e772db3f2010-07-12 18:11:13479 int result = OK;
Matt Menke141b87f22019-01-30 02:43:03480 has_established_connection_ = true;
[email protected]ab838892009-06-30 18:49:05481 if (succeed) {
Matt Menkeb57663b32019-03-01 17:17:10482 SetSocket(std::make_unique<MockClientSocket>(net_log().net_log()));
Bence Békybdbb0e72018-08-07 21:42:59483 socket()->Connect(CompletionOnceCallback());
Matt Menkeb57663b32019-03-01 17:17:10484 } else if (cert_error) {
485 SetSocket(std::make_unique<MockClientSocket>(net_log().net_log()));
486 result = ERR_CERT_COMMON_NAME_INVALID;
[email protected]6e713f02009-08-06 02:56:40487 } else {
[email protected]e772db3f2010-07-12 18:11:13488 result = ERR_CONNECTION_FAILED;
danakj655b66c2016-04-16 00:51:38489 SetSocket(std::unique_ptr<StreamSocket>());
[email protected]ab838892009-06-30 18:49:05490 }
[email protected]2ab05b52009-07-01 23:57:58491
492 if (was_async)
[email protected]fd7b7c92009-08-20 19:38:30493 NotifyDelegateOfCompletion(result);
[email protected]ab838892009-06-30 18:49:05494 return result;
495 }
496
Matt Menkeb57663b32019-03-01 17:17:10497 void DoAdvanceAuthChallenge(int remaining_challenges,
498 bool succeed_after_last_challenge) {
499 base::ThreadTaskRunnerHandle::Get()->PostTask(
500 FROM_HERE,
501 base::BindOnce(&TestConnectJob::InvokeNextProxyAuthCallback,
502 weak_factory_.GetWeakPtr(), remaining_challenges,
503 succeed_after_last_challenge));
504 }
505
506 void InvokeNextProxyAuthCallback(int remaining_challenges,
507 bool succeed_after_last_challenge) {
Matt Menke4b69f932019-03-04 16:20:01508 set_load_state(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL);
Matt Menkeb57663b32019-03-01 17:17:10509 if (remaining_challenges == 0) {
510 DoConnect(succeed_after_last_challenge, true /* was_async */,
511 false /* cert_error */);
512 return;
513 }
514
515 // Integration tests make sure HttpResponseInfo and HttpAuthController work.
516 // The auth tests here are just focused on ConnectJob bookkeeping.
517 HttpResponseInfo info;
518 NotifyDelegateOfProxyAuth(
519 info, nullptr /* http_auth_controller */,
520 base::BindOnce(&TestConnectJob::DoAdvanceAuthChallenge,
521 weak_factory_.GetWeakPtr(), remaining_challenges - 1,
522 succeed_after_last_challenge));
523 }
524
[email protected]5fc08e32009-07-15 17:09:57525 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05526 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57527 MockClientSocketFactory* const client_socket_factory_;
[email protected]46451352009-09-01 14:54:21528 LoadState load_state_;
Matt Menke141b87f22019-01-30 02:43:03529 bool has_established_connection_;
[email protected]e60e47a2010-07-14 03:37:18530 bool store_additional_error_state_;
[email protected]ab838892009-06-30 18:49:05531
Jeremy Romand54000b22019-07-08 18:40:16532 base::WeakPtrFactory<TestConnectJob> weak_factory_{this};
[email protected]d5492c52013-11-10 20:44:39533
[email protected]ab838892009-06-30 18:49:05534 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
535};
536
[email protected]d80a4322009-08-14 07:07:49537class TestConnectJobFactory
Matt Menke16f5c2e52019-03-25 21:50:40538 : public TransportClientSocketPool::ConnectJobFactory {
[email protected]ab838892009-06-30 18:49:05539 public:
[email protected]034df0f32013-01-07 23:17:48540 TestConnectJobFactory(MockClientSocketFactory* client_socket_factory,
541 NetLog* net_log)
Matt Menkea6f99ad2019-03-08 02:26:43542 : common_connect_job_params_(
543 nullptr /* client_socket_factory */,
544 nullptr /* host_resolver */,
Matt Menkeb88837e2019-03-20 11:50:40545 nullptr /* http_auth_cache */,
546 nullptr /* http_auth_handler_factory */,
547 nullptr /* spdy_session_pool */,
Matt Menkeb5fb42b2019-03-22 17:26:13548 nullptr /* quic_supported_versions */,
Matt Menkeb88837e2019-03-20 11:50:40549 nullptr /* quic_stream_factory */,
Matt Menkea6f99ad2019-03-08 02:26:43550 nullptr /* proxy_delegate */,
Matt Menked732ea42019-03-08 12:05:00551 nullptr /* http_user_agent_settings */,
David Benjamin24725be2019-07-24 20:57:18552 nullptr /* ssl_client_context */,
Matt Menkea6f99ad2019-03-08 02:26:43553 nullptr /* socket_performance_watcher_factory */,
554 nullptr /* network_quality_estimator */,
555 net_log,
556 nullptr /* websocket_endpoint_lock_manager */),
557 job_type_(TestConnectJob::kMockJob),
Raul Tambre94493c652019-03-11 17:18:35558 job_types_(nullptr),
Matt Menkea6f99ad2019-03-08 02:26:43559 client_socket_factory_(client_socket_factory) {}
[email protected]ab838892009-06-30 18:49:05560
Chris Watkins7a41d3552017-12-01 02:13:27561 ~TestConnectJobFactory() override = default;
[email protected]ab838892009-06-30 18:49:05562
563 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
564
[email protected]51fdc7c2012-04-10 19:19:48565 void set_job_types(std::list<TestConnectJob::JobType>* job_types) {
566 job_types_ = job_types;
567 CHECK(!job_types_->empty());
568 }
569
[email protected]974ebd62009-08-03 23:14:34570 void set_timeout_duration(base::TimeDelta timeout_duration) {
571 timeout_duration_ = timeout_duration;
572 }
573
[email protected]3f55aa12011-12-07 02:03:33574 // ConnectJobFactory implementation.
[email protected]83039bb2011-12-09 18:43:55575
danakj655b66c2016-04-16 00:51:38576 std::unique_ptr<ConnectJob> NewConnectJob(
Matt Menkeaafff542019-04-22 22:09:36577 ClientSocketPool::GroupId group_id,
578 scoped_refptr<ClientSocketPool::SocketParams> socket_params,
Matt Menkef09e64c2019-04-23 22:16:28579 const base::Optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
Matt Menke16f5c2e52019-03-25 21:50:40580 RequestPriority request_priority,
581 SocketTag socket_tag,
mostynbba063d6032014-10-09 11:01:13582 ConnectJob::Delegate* delegate) const override {
[email protected]51fdc7c2012-04-10 19:19:48583 EXPECT_TRUE(!job_types_ || !job_types_->empty());
584 TestConnectJob::JobType job_type = job_type_;
585 if (job_types_ && !job_types_->empty()) {
586 job_type = job_types_->front();
587 job_types_->pop_front();
588 }
Matt Menkea6f99ad2019-03-08 02:26:43589 return std::make_unique<TestConnectJob>(
Matt Menke16f5c2e52019-03-25 21:50:40590 job_type, request_priority, socket_tag, timeout_duration_,
591 &common_connect_job_params_, delegate, client_socket_factory_);
[email protected]ab838892009-06-30 18:49:05592 }
593
594 private:
Matt Menkea6f99ad2019-03-08 02:26:43595 const CommonConnectJobParams common_connect_job_params_;
[email protected]ab838892009-06-30 18:49:05596 TestConnectJob::JobType job_type_;
[email protected]51fdc7c2012-04-10 19:19:48597 std::list<TestConnectJob::JobType>* job_types_;
[email protected]974ebd62009-08-03 23:14:34598 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57599 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05600
601 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
602};
603
[email protected]a937a06d2009-08-19 21:19:24604} // namespace
605
[email protected]a937a06d2009-08-19 21:19:24606namespace {
607
[email protected]5fc08e32009-07-15 17:09:57608void MockClientSocketFactory::SignalJobs() {
jdoerrie22a91d8b92018-10-05 08:43:26609 for (auto it = waiting_jobs_.begin(); it != waiting_jobs_.end(); ++it) {
[email protected]5fc08e32009-07-15 17:09:57610 (*it)->Signal();
611 }
612 waiting_jobs_.clear();
613}
614
[email protected]03b7c8c2013-07-20 04:38:55615void MockClientSocketFactory::SignalJob(size_t job) {
616 ASSERT_LT(job, waiting_jobs_.size());
617 waiting_jobs_[job]->Signal();
618 waiting_jobs_.erase(waiting_jobs_.begin() + job);
619}
620
621void MockClientSocketFactory::SetJobLoadState(size_t job,
622 LoadState load_state) {
623 ASSERT_LT(job, waiting_jobs_.size());
624 waiting_jobs_[job]->set_load_state(load_state);
625}
626
Matt Menke141b87f22019-01-30 02:43:03627void MockClientSocketFactory::SetJobHasEstablishedConnection(size_t job) {
628 ASSERT_LT(job, waiting_jobs_.size());
629 waiting_jobs_[job]->set_has_established_connection();
630}
631
Gabriel Charette694c3c332019-08-19 14:53:05632class ClientSocketPoolBaseTest : public TestWithTaskEnvironment {
[email protected]f6d1d6eb2009-06-24 20:16:09633 protected:
Alex Clarke0def2092018-12-10 12:01:45634 ClientSocketPoolBaseTest()
Gabriel Charette694c3c332019-08-19 14:53:05635 : TestWithTaskEnvironment(
636 base::test::TaskEnvironment::TimeSource::MOCK_TIME),
Matt Menke870e19ab2019-04-23 16:23:03637 params_(ClientSocketPool::SocketParams::CreateForHttpForTesting()) {
[email protected]636b8252011-04-08 19:56:54638 connect_backup_jobs_enabled_ =
Matt Menke16f5c2e52019-03-25 21:50:40639 TransportClientSocketPool::connect_backup_jobs_enabled();
640 TransportClientSocketPool::set_connect_backup_jobs_enabled(true);
[email protected]636b8252011-04-08 19:56:54641 }
[email protected]2431756e2010-09-29 20:26:13642
dcheng67be2b1f2014-10-27 21:47:29643 ~ClientSocketPoolBaseTest() override {
Matt Menke16f5c2e52019-03-25 21:50:40644 TransportClientSocketPool::set_connect_backup_jobs_enabled(
[email protected]636b8252011-04-08 19:56:54645 connect_backup_jobs_enabled_);
646 }
[email protected]c9d6a1d2009-07-14 16:15:20647
Matt Menke9fa17d52019-03-25 19:12:26648 void CreatePool(int max_sockets,
649 int max_sockets_per_group,
650 bool enable_backup_connect_jobs = false) {
Tarun Bansala7635092019-02-20 10:00:59651 CreatePoolWithIdleTimeouts(max_sockets, max_sockets_per_group,
652 kUnusedIdleSocketTimeout,
Matt Menke9fa17d52019-03-25 19:12:26653 ClientSocketPool::used_idle_socket_timeout(),
654 enable_backup_connect_jobs);
[email protected]9bf28db2009-08-29 01:35:16655 }
656
David Benjaminbac8dff2019-08-07 01:30:41657 void CreatePoolWithIdleTimeouts(
658 int max_sockets,
659 int max_sockets_per_group,
660 base::TimeDelta unused_idle_socket_timeout,
661 base::TimeDelta used_idle_socket_timeout,
662 bool enable_backup_connect_jobs = false,
663 ProxyServer proxy_server = ProxyServer::Direct()) {
[email protected]c9d6a1d2009-07-14 16:15:20664 DCHECK(!pool_.get());
Matt Menke9fa17d52019-03-25 19:12:26665 std::unique_ptr<TestConnectJobFactory> connect_job_factory =
666 std::make_unique<TestConnectJobFactory>(&client_socket_factory_,
667 &net_log_);
668 connect_job_factory_ = connect_job_factory.get();
669 pool_ = TransportClientSocketPool::CreateForTesting(
670 max_sockets, max_sockets_per_group, unused_idle_socket_timeout,
David Benjaminbac8dff2019-08-07 01:30:41671 used_idle_socket_timeout, proxy_server, std::move(connect_job_factory),
Matt Menke9fa17d52019-03-25 19:12:26672 nullptr /* ssl_config_service */, enable_backup_connect_jobs);
[email protected]c9d6a1d2009-07-14 16:15:20673 }
[email protected]f6d1d6eb2009-06-24 20:16:09674
mmenked3641e12016-01-28 16:06:15675 int StartRequestWithIgnoreLimits(
Matt Menkec6b3edf72019-03-19 17:00:39676 const ClientSocketPool::GroupId& group_id,
[email protected]b021ece62013-06-11 11:06:33677 RequestPriority priority,
mmenked3641e12016-01-28 16:06:15678 ClientSocketPool::RespectLimits respect_limits) {
Matt Menkec6b3edf72019-03-19 17:00:39679 return test_base_.StartRequestUsingPool(pool_.get(), group_id, priority,
mmenked3641e12016-01-28 16:06:15680 respect_limits, params_);
[email protected]b021ece62013-06-11 11:06:33681 }
682
Matt Menkec6b3edf72019-03-19 17:00:39683 int StartRequest(const ClientSocketPool::GroupId& group_id,
684 RequestPriority priority) {
mmenked3641e12016-01-28 16:06:15685 return StartRequestWithIgnoreLimits(
Matt Menkec6b3edf72019-03-19 17:00:39686 group_id, priority, ClientSocketPool::RespectLimits::ENABLED);
[email protected]f6d1d6eb2009-06-24 20:16:09687 }
688
[email protected]2431756e2010-09-29 20:26:13689 int GetOrderOfRequest(size_t index) const {
690 return test_base_.GetOrderOfRequest(index);
[email protected]f6d1d6eb2009-06-24 20:16:09691 }
692
[email protected]2431756e2010-09-29 20:26:13693 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
694 return test_base_.ReleaseOneConnection(keep_alive);
695 }
696
697 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
698 test_base_.ReleaseAllConnections(keep_alive);
699 }
700
Matt Menke433de6d2020-03-04 00:24:11701 // Expects a single NetLogEventType::SOCKET_POOL_CLOSING_SOCKET in |net_log_|.
702 // It should be logged for the provided source and have the indicated reason.
703 void ExpectSocketClosedWithReason(NetLogSource expected_source,
704 const char* expected_reason) {
705 auto entries = net_log_.GetEntriesForSourceWithType(
706 expected_source, NetLogEventType::SOCKET_POOL_CLOSING_SOCKET,
707 NetLogEventPhase::NONE);
708 ASSERT_EQ(1u, entries.size());
709 ASSERT_TRUE(entries[0].HasParams());
710 ASSERT_TRUE(entries[0].params.is_dict());
711 const std::string* reason = entries[0].params.FindStringKey("reason");
712 ASSERT_TRUE(reason);
713 EXPECT_EQ(expected_reason, *reason);
714 }
715
[email protected]2431756e2010-09-29 20:26:13716 TestSocketRequest* request(int i) { return test_base_.request(i); }
717 size_t requests_size() const { return test_base_.requests_size(); }
danakj655b66c2016-04-16 00:51:38718 std::vector<std::unique_ptr<TestSocketRequest>>* requests() {
olli.raula9d66b7d2015-11-23 08:30:42719 return test_base_.requests();
720 }
rdsmith29dbad12017-02-17 02:22:18721 // Only counts the requests that get sockets asynchronously;
722 // synchronous completions are not registered by this count.
[email protected]2431756e2010-09-29 20:26:13723 size_t completion_count() const { return test_base_.completion_count(); }
724
Matt Muellerd9342e3a2019-11-26 01:41:14725 RecordingTestNetLog net_log_;
[email protected]636b8252011-04-08 19:56:54726 bool connect_backup_jobs_enabled_;
[email protected]f6d1d6eb2009-06-24 20:16:09727 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04728 TestConnectJobFactory* connect_job_factory_;
Matt Menke9fa17d52019-03-25 19:12:26729 // These parameters are never actually used to create a TransportConnectJob.
Matt Menke84d11e562019-03-27 00:11:19730 scoped_refptr<ClientSocketPool::SocketParams> params_;
Matt Menke9fa17d52019-03-25 19:12:26731 std::unique_ptr<TransportClientSocketPool> pool_;
[email protected]2431756e2010-09-29 20:26:13732 ClientSocketPoolTest test_base_;
[email protected]f6d1d6eb2009-06-24 20:16:09733};
734
Shivani Sharma8ae506c2019-07-21 21:08:27735// TODO(950069): Add testing for frame_origin in NetworkIsolationKey
736// using kAppendInitiatingFrameOriginToNetworkIsolationKey.
737
[email protected]5fc08e32009-07-15 17:09:57738TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53739 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20740
[email protected]6ecf2b92011-12-15 01:14:52741 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06742 ClientSocketHandle handle;
Matt Muellerd9342e3a2019-11-26 01:41:14743 RecordingBoundTestNetLog log;
[email protected]034df0f32013-01-07 23:17:48744 TestLoadTimingInfoNotConnected(handle);
[email protected]9e743cd2010-03-16 07:03:53745
Matt Menkef09e64c2019-04-23 22:16:28746 EXPECT_EQ(OK, handle.Init(
747 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
748 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
749 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
750 pool_.get(), log.bound()));
[email protected]f6d1d6eb2009-06-24 20:16:09751 EXPECT_TRUE(handle.is_initialized());
752 EXPECT_TRUE(handle.socket());
[email protected]034df0f32013-01-07 23:17:48753 TestLoadTimingInfoConnectedNotReused(handle);
754
[email protected]f6d1d6eb2009-06-24 20:16:09755 handle.Reset();
[email protected]034df0f32013-01-07 23:17:48756 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:30757
Eric Roman79cc7552019-07-19 02:17:54758 auto entries = log.GetEntries();
[email protected]b2fcd0e2010-12-01 15:19:40759
Matt Menke9fa17d52019-03-25 19:12:26760 EXPECT_EQ(5u, entries.size());
[email protected]9e743cd2010-03-16 07:03:53761 EXPECT_TRUE(LogContainsEvent(
Matt Menke9fa17d52019-03-25 19:12:26762 entries, 0, NetLogEventType::TCP_CLIENT_SOCKET_POOL_REQUESTED_SOCKET,
mikecirone8b85c432016-09-08 19:11:00763 NetLogEventPhase::NONE));
Matt Menke9fa17d52019-03-25 19:12:26764 EXPECT_TRUE(LogContainsBeginEvent(entries, 1, NetLogEventType::SOCKET_POOL));
765 EXPECT_TRUE(LogContainsEvent(
766 entries, 2, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
767 NetLogEventPhase::NONE));
768 EXPECT_TRUE(LogContainsEvent(entries, 3,
mikecirone8b85c432016-09-08 19:11:00769 NetLogEventType::SOCKET_POOL_BOUND_TO_SOCKET,
770 NetLogEventPhase::NONE));
Matt Menke9fa17d52019-03-25 19:12:26771 EXPECT_TRUE(LogContainsEndEvent(entries, 4, NetLogEventType::SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09772}
773
[email protected]ab838892009-06-30 18:49:05774TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53775 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20776
[email protected]ab838892009-06-30 18:49:05777 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
Matt Muellerd9342e3a2019-11-26 01:41:14778 RecordingBoundTestNetLog log;
[email protected]9e743cd2010-03-16 07:03:53779
[email protected]2431756e2010-09-29 20:26:13780 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:52781 TestCompletionCallback callback;
[email protected]e60e47a2010-07-14 03:37:18782 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:13783 handle.set_is_ssl_error(true);
Matt Menke39b7c5a2019-04-10 19:47:51784 handle.set_ssl_cert_request_info(base::MakeRefCounted<SSLCertRequestInfo>());
Matt Menke28ac03e2019-02-25 22:25:50785 EXPECT_EQ(
786 ERR_CONNECTION_FAILED,
Matt Menkef09e64c2019-04-23 22:16:28787 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
788 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
789 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
790 pool_.get(), log.bound()));
[email protected]2431756e2010-09-29 20:26:13791 EXPECT_FALSE(handle.socket());
792 EXPECT_FALSE(handle.is_ssl_error());
Matt Menke39b7c5a2019-04-10 19:47:51793 EXPECT_FALSE(handle.ssl_cert_request_info());
[email protected]034df0f32013-01-07 23:17:48794 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:30795
Eric Roman79cc7552019-07-19 02:17:54796 auto entries = log.GetEntries();
[email protected]b2fcd0e2010-12-01 15:19:40797
Matt Menke9fa17d52019-03-25 19:12:26798 EXPECT_EQ(4u, entries.size());
[email protected]06650c52010-06-03 00:49:17799 EXPECT_TRUE(LogContainsEvent(
Matt Menke9fa17d52019-03-25 19:12:26800 entries, 0, NetLogEventType::TCP_CLIENT_SOCKET_POOL_REQUESTED_SOCKET,
mikecirone8b85c432016-09-08 19:11:00801 NetLogEventPhase::NONE));
Matt Menke9fa17d52019-03-25 19:12:26802 EXPECT_TRUE(LogContainsBeginEvent(entries, 1, NetLogEventType::SOCKET_POOL));
803 EXPECT_TRUE(LogContainsEvent(
804 entries, 2, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
805 NetLogEventPhase::NONE));
806 EXPECT_TRUE(LogContainsEndEvent(entries, 3, NetLogEventType::SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09807}
808
Matt Menke433de6d2020-03-04 00:24:11809// Test releasing an open socket into the socket pool, telling the socket pool
810// to close the socket.
811TEST_F(ClientSocketPoolBaseTest, ReleaseAndCloseConnection) {
812 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
813
814 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(OK));
815 ASSERT_TRUE(request(0)->handle()->socket());
816 net::NetLogSource source = request(0)->handle()->socket()->NetLog().source();
817 ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE);
818
819 EXPECT_EQ(0, pool_->IdleSocketCount());
820 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
821
822 ExpectSocketClosedWithReason(
823 source, TransportClientSocketPool::kClosedConnectionReturnedToPool);
824}
825
826TEST_F(ClientSocketPoolBaseTest, SocketWithUnreadDataReturnedToPool) {
827 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
828 connect_job_factory_->set_job_type(TestConnectJob::kMockUnreadDataJob);
829
830 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(OK));
831 ASSERT_TRUE(request(0)->handle()->socket());
832 net::NetLogSource source = request(0)->handle()->socket()->NetLog().source();
833 EXPECT_TRUE(request(0)->handle()->socket()->IsConnected());
834 EXPECT_FALSE(request(0)->handle()->socket()->IsConnectedAndIdle());
835 ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE);
836
837 EXPECT_EQ(0, pool_->IdleSocketCount());
838 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
839
840 ExpectSocketClosedWithReason(
841 source, TransportClientSocketPool::kDataReceivedUnexpectedly);
842}
843
Matt Menkef6edce752019-03-19 17:21:56844// Make sure different groups do not share sockets.
845TEST_F(ClientSocketPoolBaseTest, GroupSeparation) {
Matt Menke166443c2019-05-24 18:45:59846 base::test::ScopedFeatureList feature_list;
847 feature_list.InitAndEnableFeature(
848 features::kPartitionConnectionsByNetworkIsolationKey);
849
Matt Menkef6edce752019-03-19 17:21:56850 CreatePool(1000 /* max_sockets */, 2 /* max_sockets_per_group */);
851
852 const HostPortPair kHostPortPairs[] = {
853 {"a", 80},
854 {"a", 443},
855 {"b", 80},
856 };
857
858 const ClientSocketPool::SocketType kSocketTypes[] = {
859 ClientSocketPool::SocketType::kHttp,
860 ClientSocketPool::SocketType::kSsl,
Matt Menkef6edce752019-03-19 17:21:56861 };
862
Matt Menkebdf777802019-04-22 19:38:59863 const PrivacyMode kPrivacyModes[] = {PrivacyMode::PRIVACY_MODE_DISABLED,
864 PrivacyMode::PRIVACY_MODE_ENABLED};
Matt Menkef6edce752019-03-19 17:21:56865
Shivani Sharma8ae506c2019-07-21 21:08:27866 const auto kOriginA = url::Origin::Create(GURL("http://a.test/"));
867 const auto kOriginB = url::Origin::Create(GURL("http://b.test/"));
Matt Menke166443c2019-05-24 18:45:59868 const NetworkIsolationKey kNetworkIsolationKeys[] = {
Shivani Sharma8ae506c2019-07-21 21:08:27869 NetworkIsolationKey(kOriginA, kOriginA),
870 NetworkIsolationKey(kOriginB, kOriginB),
Matt Menke166443c2019-05-24 18:45:59871 };
872
dalyk5f48a132019-10-14 15:20:19873 const bool kDisableSecureDnsValues[] = {false, true};
874
Matt Menkef6edce752019-03-19 17:21:56875 int total_idle_sockets = 0;
876
877 // Walk through each GroupId, making sure that requesting a socket for one
878 // group does not return a previously connected socket for another group.
879 for (const auto& host_port_pair : kHostPortPairs) {
880 SCOPED_TRACE(host_port_pair.ToString());
881 for (const auto& socket_type : kSocketTypes) {
882 SCOPED_TRACE(static_cast<int>(socket_type));
883 for (const auto& privacy_mode : kPrivacyModes) {
884 SCOPED_TRACE(privacy_mode);
Matt Menke166443c2019-05-24 18:45:59885 for (const auto& network_isolation_key : kNetworkIsolationKeys) {
886 SCOPED_TRACE(network_isolation_key.ToString());
dalyk5f48a132019-10-14 15:20:19887 for (const auto& disable_secure_dns : kDisableSecureDnsValues) {
888 SCOPED_TRACE(disable_secure_dns);
Matt Menkef6edce752019-03-19 17:21:56889
dalyk5f48a132019-10-14 15:20:19890 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
Matt Menkef6edce752019-03-19 17:21:56891
dalyk5f48a132019-10-14 15:20:19892 ClientSocketPool::GroupId group_id(
893 host_port_pair, socket_type, privacy_mode,
894 network_isolation_key, disable_secure_dns);
Matt Menkef6edce752019-03-19 17:21:56895
dalyk5f48a132019-10-14 15:20:19896 EXPECT_FALSE(pool_->HasGroupForTesting(group_id));
Matt Menkef6edce752019-03-19 17:21:56897
dalyk5f48a132019-10-14 15:20:19898 TestCompletionCallback callback;
899 ClientSocketHandle handle;
Matt Menkef6edce752019-03-19 17:21:56900
dalyk5f48a132019-10-14 15:20:19901 // Since the group is empty, requesting a socket should not complete
902 // synchronously.
903 EXPECT_THAT(handle.Init(group_id, params_, base::nullopt,
904 DEFAULT_PRIORITY, SocketTag(),
905 ClientSocketPool::RespectLimits::ENABLED,
906 callback.callback(),
907 ClientSocketPool::ProxyAuthCallback(),
908 pool_.get(), NetLogWithSource()),
909 IsError(ERR_IO_PENDING));
910 EXPECT_TRUE(pool_->HasGroupForTesting(group_id));
911 EXPECT_EQ(total_idle_sockets, pool_->IdleSocketCount());
Matt Menkef6edce752019-03-19 17:21:56912
dalyk5f48a132019-10-14 15:20:19913 EXPECT_THAT(callback.WaitForResult(), IsOk());
914 EXPECT_TRUE(handle.socket());
915 EXPECT_TRUE(pool_->HasGroupForTesting(group_id));
916 EXPECT_EQ(total_idle_sockets, pool_->IdleSocketCount());
Matt Menkef6edce752019-03-19 17:21:56917
dalyk5f48a132019-10-14 15:20:19918 // Return socket to pool.
919 handle.Reset();
920 EXPECT_EQ(total_idle_sockets + 1, pool_->IdleSocketCount());
Matt Menkef6edce752019-03-19 17:21:56921
dalyk5f48a132019-10-14 15:20:19922 // Requesting a socket again should return the same socket as
923 // before, so should complete synchronously.
924 EXPECT_THAT(handle.Init(group_id, params_, base::nullopt,
925 DEFAULT_PRIORITY, SocketTag(),
926 ClientSocketPool::RespectLimits::ENABLED,
927 callback.callback(),
928 ClientSocketPool::ProxyAuthCallback(),
929 pool_.get(), NetLogWithSource()),
930 IsOk());
931 EXPECT_TRUE(handle.socket());
932 EXPECT_EQ(total_idle_sockets, pool_->IdleSocketCount());
Matt Menkef6edce752019-03-19 17:21:56933
dalyk5f48a132019-10-14 15:20:19934 // Return socket to pool again.
935 handle.Reset();
936 EXPECT_EQ(total_idle_sockets + 1, pool_->IdleSocketCount());
Matt Menkef6edce752019-03-19 17:21:56937
dalyk5f48a132019-10-14 15:20:19938 ++total_idle_sockets;
939 }
Matt Menke166443c2019-05-24 18:45:59940 }
Matt Menkef6edce752019-03-19 17:21:56941 }
942 }
943 }
944}
945
[email protected]211d21722009-07-22 15:48:53946TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
947 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
948
[email protected]9e743cd2010-03-16 07:03:53949 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30950
Matt Menkec6b3edf72019-03-19 17:00:39951 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
952 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
953 EXPECT_THAT(StartRequest(TestGroupId("c"), DEFAULT_PRIORITY), IsOk());
954 EXPECT_THAT(StartRequest(TestGroupId("d"), DEFAULT_PRIORITY), IsOk());
[email protected]211d21722009-07-22 15:48:53955
[email protected]2431756e2010-09-29 20:26:13956 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53957 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13958 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53959
Matt Menkec6b3edf72019-03-19 17:00:39960 EXPECT_THAT(StartRequest(TestGroupId("e"), DEFAULT_PRIORITY),
961 IsError(ERR_IO_PENDING));
962 EXPECT_THAT(StartRequest(TestGroupId("f"), DEFAULT_PRIORITY),
963 IsError(ERR_IO_PENDING));
964 EXPECT_THAT(StartRequest(TestGroupId("g"), DEFAULT_PRIORITY),
965 IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:53966
[email protected]2431756e2010-09-29 20:26:13967 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53968
[email protected]2431756e2010-09-29 20:26:13969 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53970 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13971 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53972
973 EXPECT_EQ(1, GetOrderOfRequest(1));
974 EXPECT_EQ(2, GetOrderOfRequest(2));
975 EXPECT_EQ(3, GetOrderOfRequest(3));
976 EXPECT_EQ(4, GetOrderOfRequest(4));
977 EXPECT_EQ(5, GetOrderOfRequest(5));
978 EXPECT_EQ(6, GetOrderOfRequest(6));
979 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17980
981 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13982 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53983}
984
985TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
986 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
987
[email protected]9e743cd2010-03-16 07:03:53988 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30989
[email protected]211d21722009-07-22 15:48:53990 // Reach all limits: max total sockets, and max sockets per group.
Matt Menkec6b3edf72019-03-19 17:00:39991 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
992 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
993 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
994 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
[email protected]211d21722009-07-22 15:48:53995
[email protected]2431756e2010-09-29 20:26:13996 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53997 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13998 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53999
1000 // Now create a new group and verify that we don't starve it.
Matt Menkec6b3edf72019-03-19 17:00:391001 EXPECT_THAT(StartRequest(TestGroupId("c"), DEFAULT_PRIORITY),
1002 IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:531003
[email protected]2431756e2010-09-29 20:26:131004 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:531005
[email protected]2431756e2010-09-29 20:26:131006 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531007 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131008 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:531009
1010 EXPECT_EQ(1, GetOrderOfRequest(1));
1011 EXPECT_EQ(2, GetOrderOfRequest(2));
1012 EXPECT_EQ(3, GetOrderOfRequest(3));
1013 EXPECT_EQ(4, GetOrderOfRequest(4));
1014 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:171015
1016 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131017 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:531018}
1019
1020TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
1021 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1022
Matt Menkec6b3edf72019-03-19 17:00:391023 EXPECT_THAT(StartRequest(TestGroupId("b"), LOWEST), IsOk());
1024 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsOk());
1025 EXPECT_THAT(StartRequest(TestGroupId("b"), HIGHEST), IsOk());
1026 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsOk());
[email protected]211d21722009-07-22 15:48:531027
[email protected]2431756e2010-09-29 20:26:131028 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531029 client_socket_factory_.allocation_count());
1030
Matt Menkec6b3edf72019-03-19 17:00:391031 EXPECT_THAT(StartRequest(TestGroupId("c"), LOWEST), IsError(ERR_IO_PENDING));
1032 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1033 EXPECT_THAT(StartRequest(TestGroupId("b"), HIGHEST), IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:531034
[email protected]2431756e2010-09-29 20:26:131035 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:531036
[email protected]2431756e2010-09-29 20:26:131037 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:531038
1039 // First 4 requests don't have to wait, and finish in order.
1040 EXPECT_EQ(1, GetOrderOfRequest(1));
1041 EXPECT_EQ(2, GetOrderOfRequest(2));
1042 EXPECT_EQ(3, GetOrderOfRequest(3));
1043 EXPECT_EQ(4, GetOrderOfRequest(4));
1044
Matt Menkec6b3edf72019-03-19 17:00:391045 // Request ("b", HIGHEST) has the highest priority, then (TestGroupId("a"),
1046 // MEDIUM), and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:531047 EXPECT_EQ(7, GetOrderOfRequest(5));
1048 EXPECT_EQ(6, GetOrderOfRequest(6));
1049 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171050
1051 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131052 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]211d21722009-07-22 15:48:531053}
1054
rdsmith29dbad12017-02-17 02:22:181055// Test reprioritizing a request before completion doesn't interfere with
1056// its completion.
1057TEST_F(ClientSocketPoolBaseTest, ReprioritizeOne) {
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"), MEDIUM), IsError(ERR_IO_PENDING));
rdsmith29dbad12017-02-17 02:22:181062 EXPECT_TRUE(request(0)->handle()->socket());
1063 EXPECT_FALSE(request(1)->handle()->socket());
1064
Lily Chenecebf932018-11-02 17:15:431065 request(1)->handle()->SetPriority(HIGHEST);
rdsmith29dbad12017-02-17 02:22:181066
1067 ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE);
1068
1069 EXPECT_TRUE(request(1)->handle()->socket());
1070}
1071
1072// Reprioritize a request up past another one and make sure that changes the
1073// completion order.
1074TEST_F(ClientSocketPoolBaseTest, ReprioritizeUpReorder) {
1075 CreatePool(kDefaultMaxSockets, 1);
1076
Matt Menkec6b3edf72019-03-19 17:00:391077 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(OK));
1078 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1079 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
rdsmith29dbad12017-02-17 02:22:181080 EXPECT_TRUE(request(0)->handle()->socket());
1081 EXPECT_FALSE(request(1)->handle()->socket());
1082 EXPECT_FALSE(request(2)->handle()->socket());
1083
1084 request(2)->handle()->SetPriority(HIGHEST);
1085
1086 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1087
1088 EXPECT_EQ(1, GetOrderOfRequest(1));
1089 EXPECT_EQ(3, GetOrderOfRequest(2));
1090 EXPECT_EQ(2, GetOrderOfRequest(3));
1091}
1092
1093// Reprioritize a request without changing relative priorities and check
1094// that the order doesn't change.
1095TEST_F(ClientSocketPoolBaseTest, ReprioritizeUpNoReorder) {
1096 CreatePool(kDefaultMaxSockets, 1);
1097
Matt Menkec6b3edf72019-03-19 17:00:391098 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(OK));
1099 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1100 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsError(ERR_IO_PENDING));
rdsmith29dbad12017-02-17 02:22:181101 EXPECT_TRUE(request(0)->handle()->socket());
1102 EXPECT_FALSE(request(1)->handle()->socket());
1103 EXPECT_FALSE(request(2)->handle()->socket());
1104
1105 request(2)->handle()->SetPriority(MEDIUM);
1106
1107 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1108
1109 EXPECT_EQ(1, GetOrderOfRequest(1));
1110 EXPECT_EQ(2, GetOrderOfRequest(2));
1111 EXPECT_EQ(3, GetOrderOfRequest(3));
1112}
1113
1114// Reprioritize a request past down another one and make sure that changes the
1115// completion order.
1116TEST_F(ClientSocketPoolBaseTest, ReprioritizeDownReorder) {
1117 CreatePool(kDefaultMaxSockets, 1);
1118
Matt Menkec6b3edf72019-03-19 17:00:391119 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(OK));
1120 EXPECT_THAT(StartRequest(TestGroupId("a"), HIGHEST), IsError(ERR_IO_PENDING));
1121 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
rdsmith29dbad12017-02-17 02:22:181122 EXPECT_TRUE(request(0)->handle()->socket());
1123 EXPECT_FALSE(request(1)->handle()->socket());
1124 EXPECT_FALSE(request(2)->handle()->socket());
1125
1126 request(1)->handle()->SetPriority(LOW);
1127
1128 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1129
1130 EXPECT_EQ(1, GetOrderOfRequest(1));
1131 EXPECT_EQ(3, GetOrderOfRequest(2));
1132 EXPECT_EQ(2, GetOrderOfRequest(3));
1133}
1134
1135// Reprioritize a request to the same level as another and confirm it is
1136// put after the old request.
1137TEST_F(ClientSocketPoolBaseTest, ReprioritizeResetFIFO) {
1138 CreatePool(kDefaultMaxSockets, 1);
1139
Matt Menkec6b3edf72019-03-19 17:00:391140 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(OK));
1141 EXPECT_THAT(StartRequest(TestGroupId("a"), HIGHEST), IsError(ERR_IO_PENDING));
1142 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
rdsmith29dbad12017-02-17 02:22:181143 EXPECT_TRUE(request(0)->handle()->socket());
1144 EXPECT_FALSE(request(1)->handle()->socket());
1145 EXPECT_FALSE(request(2)->handle()->socket());
1146
1147 request(1)->handle()->SetPriority(MEDIUM);
1148
1149 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1150
1151 EXPECT_EQ(1, GetOrderOfRequest(1));
1152 EXPECT_EQ(3, GetOrderOfRequest(2));
1153 EXPECT_EQ(2, GetOrderOfRequest(3));
1154}
1155
[email protected]211d21722009-07-22 15:48:531156TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
1157 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1158
Matt Menkec6b3edf72019-03-19 17:00:391159 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsOk());
1160 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsOk());
1161 EXPECT_THAT(StartRequest(TestGroupId("b"), HIGHEST), IsOk());
1162 EXPECT_THAT(StartRequest(TestGroupId("b"), MEDIUM), IsOk());
[email protected]211d21722009-07-22 15:48:531163
[email protected]2431756e2010-09-29 20:26:131164 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531165 client_socket_factory_.allocation_count());
1166
Matt Menkec6b3edf72019-03-19 17:00:391167 EXPECT_THAT(StartRequest(TestGroupId("c"), MEDIUM), IsError(ERR_IO_PENDING));
1168 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsError(ERR_IO_PENDING));
1169 EXPECT_THAT(StartRequest(TestGroupId("b"), HIGHEST), IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:531170
[email protected]2431756e2010-09-29 20:26:131171 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:531172
[email protected]2431756e2010-09-29 20:26:131173 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531174 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131175 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:531176
1177 // First 4 requests don't have to wait, and finish in order.
1178 EXPECT_EQ(1, GetOrderOfRequest(1));
1179 EXPECT_EQ(2, GetOrderOfRequest(2));
1180 EXPECT_EQ(3, GetOrderOfRequest(3));
1181 EXPECT_EQ(4, GetOrderOfRequest(4));
1182
1183 // Request ("b", 7) has the highest priority, but we can't make new socket for
1184 // group "b", because it has reached the per-group limit. Then we make
1185 // socket for ("c", 6), because it has higher priority than ("a", 4),
1186 // and we still can't make a socket for group "b".
1187 EXPECT_EQ(5, GetOrderOfRequest(5));
1188 EXPECT_EQ(6, GetOrderOfRequest(6));
1189 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171190
1191 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131192 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:531193}
1194
1195// Make sure that we count connecting sockets against the total limit.
1196TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
1197 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1198
Matt Menkec6b3edf72019-03-19 17:00:391199 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1200 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
1201 EXPECT_THAT(StartRequest(TestGroupId("c"), DEFAULT_PRIORITY), IsOk());
[email protected]211d21722009-07-22 15:48:531202
1203 // Create one asynchronous request.
1204 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
Matt Menkec6b3edf72019-03-19 17:00:391205 EXPECT_THAT(StartRequest(TestGroupId("d"), DEFAULT_PRIORITY),
1206 IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:531207
[email protected]6b175382009-10-13 06:47:471208 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1209 // actually become pending until 2ms after they have been created. In order
1210 // to flush all tasks, we need to wait so that we know there are no
1211 // soon-to-be-pending tasks waiting.
Alex Clarke0def2092018-12-10 12:01:451212 FastForwardBy(base::TimeDelta::FromMilliseconds(10));
[email protected]6b175382009-10-13 06:47:471213
[email protected]211d21722009-07-22 15:48:531214 // The next synchronous request should wait for its turn.
1215 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
Matt Menkec6b3edf72019-03-19 17:00:391216 EXPECT_THAT(StartRequest(TestGroupId("e"), DEFAULT_PRIORITY),
1217 IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:531218
[email protected]2431756e2010-09-29 20:26:131219 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:531220
[email protected]2431756e2010-09-29 20:26:131221 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531222 client_socket_factory_.allocation_count());
1223
1224 EXPECT_EQ(1, GetOrderOfRequest(1));
1225 EXPECT_EQ(2, GetOrderOfRequest(2));
1226 EXPECT_EQ(3, GetOrderOfRequest(3));
1227 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:171228 EXPECT_EQ(5, GetOrderOfRequest(5));
1229
1230 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131231 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:531232}
1233
[email protected]6427fe22010-04-16 22:27:411234TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
1235 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1236 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1237
Matt Menkec6b3edf72019-03-19 17:00:391238 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1239 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1240 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1241 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
[email protected]6427fe22010-04-16 22:27:411242
1243 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1244
1245 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1246
Matt Menkec6b3edf72019-03-19 17:00:391247 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY),
1248 IsError(ERR_IO_PENDING));
1249 EXPECT_THAT(StartRequest(TestGroupId("c"), DEFAULT_PRIORITY),
1250 IsError(ERR_IO_PENDING));
[email protected]6427fe22010-04-16 22:27:411251
1252 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1253
[email protected]2431756e2010-09-29 20:26:131254 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411255 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131256 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411257 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131258 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1259 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411260 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
1261}
1262
[email protected]d7027bb2010-05-10 18:58:541263TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
1264 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1265 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1266
1267 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521268 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:501269 EXPECT_EQ(
1270 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:281271 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
1272 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1273 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1274 pool_.get(), NetLogWithSource()));
[email protected]d7027bb2010-05-10 18:58:541275
1276 ClientSocketHandle handles[4];
Avi Drissman4365a4782018-12-28 19:26:241277 for (size_t i = 0; i < base::size(handles); ++i) {
[email protected]6ecf2b92011-12-15 01:14:521278 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:501279 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:391280 handles[i].Init(
Matt Menkef09e64c2019-04-23 22:16:281281 TestGroupId("b"), params_, base::nullopt, DEFAULT_PRIORITY,
1282 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1283 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1284 pool_.get(), NetLogWithSource()));
[email protected]d7027bb2010-05-10 18:58:541285 }
1286
1287 // One will be stalled, cancel all the handles now.
1288 // This should hit the OnAvailableSocketSlot() code where we previously had
1289 // stalled groups, but no longer have any.
Avi Drissman4365a4782018-12-28 19:26:241290 for (size_t i = 0; i < base::size(handles); ++i)
[email protected]d7027bb2010-05-10 18:58:541291 handles[i].Reset();
1292}
1293
[email protected]eb5a99382010-07-11 03:18:261294TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
[email protected]43a21b82010-06-10 21:30:541295 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1296 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1297
[email protected]eb5a99382010-07-11 03:18:261298 {
1299 ClientSocketHandle handles[kDefaultMaxSockets];
[email protected]6ecf2b92011-12-15 01:14:521300 TestCompletionCallback callbacks[kDefaultMaxSockets];
[email protected]eb5a99382010-07-11 03:18:261301 for (int i = 0; i < kDefaultMaxSockets; ++i) {
Matt Menkef09e64c2019-04-23 22:16:281302 EXPECT_EQ(OK,
1303 handles[i].Init(TestGroupId(base::NumberToString(i)), params_,
1304 base::nullopt, DEFAULT_PRIORITY, SocketTag(),
1305 ClientSocketPool::RespectLimits::ENABLED,
1306 callbacks[i].callback(),
1307 ClientSocketPool::ProxyAuthCallback(),
1308 pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261309 }
1310
1311 // Force a stalled group.
1312 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521313 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:201314 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:391315 stalled_handle.Init(
Matt Menkef09e64c2019-04-23 22:16:281316 TestGroupId("foo"), params_, base::nullopt, DEFAULT_PRIORITY,
1317 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1318 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1319 pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261320
1321 // Cancel the stalled request.
1322 stalled_handle.Reset();
1323
1324 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1325 EXPECT_EQ(0, pool_->IdleSocketCount());
1326
1327 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541328 }
1329
[email protected]43a21b82010-06-10 21:30:541330 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1331 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
[email protected]eb5a99382010-07-11 03:18:261332}
[email protected]43a21b82010-06-10 21:30:541333
[email protected]eb5a99382010-07-11 03:18:261334TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
1335 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1336 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1337
1338 {
1339 ClientSocketHandle handles[kDefaultMaxSockets];
1340 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:521341 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:201342 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:391343 handles[i].Init(TestGroupId(base::NumberToString(i)), params_,
Matt Menkef09e64c2019-04-23 22:16:281344 base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menkec6b3edf72019-03-19 17:00:391345 ClientSocketPool::RespectLimits::ENABLED,
1346 callback.callback(),
1347 ClientSocketPool::ProxyAuthCallback(),
1348 pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261349 }
1350
1351 // Force a stalled group.
1352 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1353 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521354 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:201355 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:391356 stalled_handle.Init(
Matt Menkef09e64c2019-04-23 22:16:281357 TestGroupId("foo"), params_, base::nullopt, DEFAULT_PRIORITY,
1358 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1359 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1360 pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261361
1362 // Since it is stalled, it should have no connect jobs.
Matt Menke9fa17d52019-03-25 19:12:261363 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("foo")));
1364 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
1365 TestGroupId("foo")));
1366 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroupForTesting(
1367 TestGroupId("foo")));
[email protected]eb5a99382010-07-11 03:18:261368
1369 // Cancel the stalled request.
1370 handles[0].Reset();
1371
[email protected]eb5a99382010-07-11 03:18:261372 // Now we should have a connect job.
Matt Menke9fa17d52019-03-25 19:12:261373 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("foo")));
1374 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
1375 TestGroupId("foo")));
1376 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroupForTesting(
1377 TestGroupId("foo")));
[email protected]eb5a99382010-07-11 03:18:261378
1379 // The stalled socket should connect.
robpercival214763f2016-07-01 23:27:011380 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:261381
1382 EXPECT_EQ(kDefaultMaxSockets + 1,
1383 client_socket_factory_.allocation_count());
1384 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menke9fa17d52019-03-25 19:12:261385 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("foo")));
1386 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
1387 TestGroupId("foo")));
1388 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroupForTesting(
1389 TestGroupId("foo")));
[email protected]eb5a99382010-07-11 03:18:261390
1391 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541392 }
1393
[email protected]eb5a99382010-07-11 03:18:261394 EXPECT_EQ(1, pool_->IdleSocketCount());
1395}
[email protected]43a21b82010-06-10 21:30:541396
[email protected]eb5a99382010-07-11 03:18:261397TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
1398 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1399 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]43a21b82010-06-10 21:30:541400
[email protected]eb5a99382010-07-11 03:18:261401 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521402 TestCompletionCallback callback;
[email protected]eb5a99382010-07-11 03:18:261403 {
[email protected]51fdc7c2012-04-10 19:19:481404 EXPECT_FALSE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261405 ClientSocketHandle handles[kDefaultMaxSockets];
1406 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:521407 TestCompletionCallback callback;
Matt Menkec6b3edf72019-03-19 17:00:391408 EXPECT_EQ(
Matt Menkef09e64c2019-04-23 22:16:281409 OK, handles[i].Init(
1410 TestGroupId(base::StringPrintf("Take 2: %d", i)), params_,
1411 base::nullopt, DEFAULT_PRIORITY, SocketTag(),
1412 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1413 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
1414 NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261415 }
1416
1417 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1418 EXPECT_EQ(0, pool_->IdleSocketCount());
[email protected]51fdc7c2012-04-10 19:19:481419 EXPECT_FALSE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261420
1421 // Now we will hit the socket limit.
tfarina428341112016-09-22 13:38:201422 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:391423 stalled_handle.Init(
Matt Menkef09e64c2019-04-23 22:16:281424 TestGroupId("foo"), params_, base::nullopt, DEFAULT_PRIORITY,
1425 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1426 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1427 pool_.get(), NetLogWithSource()));
[email protected]51fdc7c2012-04-10 19:19:481428 EXPECT_TRUE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261429
1430 // Dropping out of scope will close all handles and return them to idle.
1431 }
[email protected]43a21b82010-06-10 21:30:541432
1433 // But if we wait for it, the released idle sockets will be closed in
1434 // preference of the waiting request.
robpercival214763f2016-07-01 23:27:011435 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:261436
1437 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1438 EXPECT_EQ(3, pool_->IdleSocketCount());
[email protected]43a21b82010-06-10 21:30:541439}
1440
1441// Regression test for http://crbug.com/40952.
1442TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
Matt Menke9fa17d52019-03-25 19:12:261443 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1444 true /* enable_backup_connect_jobs */);
[email protected]43a21b82010-06-10 21:30:541445 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1446
1447 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1448 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521449 TestCompletionCallback callback;
Matt Menkec6b3edf72019-03-19 17:00:391450 EXPECT_EQ(OK, handle.Init(TestGroupId(base::NumberToString(i)), params_,
Matt Menkef09e64c2019-04-23 22:16:281451 base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menkec6b3edf72019-03-19 17:00:391452 ClientSocketPool::RespectLimits::ENABLED,
1453 callback.callback(),
1454 ClientSocketPool::ProxyAuthCallback(),
1455 pool_.get(), NetLogWithSource()));
[email protected]43a21b82010-06-10 21:30:541456 }
1457
1458 // Flush all the DoReleaseSocket tasks.
fdoray5eeb7642016-06-22 16:11:281459 base::RunLoop().RunUntilIdle();
[email protected]43a21b82010-06-10 21:30:541460
1461 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
1462 // reuse a socket.
1463 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1464 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521465 TestCompletionCallback callback;
[email protected]43a21b82010-06-10 21:30:541466
1467 // "0" is special here, since it should be the first entry in the sorted map,
1468 // which is the one which we would close an idle socket for. We shouldn't
1469 // close an idle socket though, since we should reuse the idle socket.
Matt Menkec6b3edf72019-03-19 17:00:391470 EXPECT_EQ(OK, handle.Init(
Matt Menkef09e64c2019-04-23 22:16:281471 TestGroupId("0"), params_, base::nullopt, DEFAULT_PRIORITY,
1472 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menkec6b3edf72019-03-19 17:00:391473 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1474 pool_.get(), NetLogWithSource()));
[email protected]43a21b82010-06-10 21:30:541475
1476 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1477 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
1478}
1479
[email protected]ab838892009-06-30 18:49:051480TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:531481 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091482
Matt Menkec6b3edf72019-03-19 17:00:391483 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1484 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1485 EXPECT_THAT(StartRequest(TestGroupId("a"), IDLE), IsError(ERR_IO_PENDING));
1486 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
1487 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1488 EXPECT_THAT(StartRequest(TestGroupId("a"), HIGHEST), IsError(ERR_IO_PENDING));
1489 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsError(ERR_IO_PENDING));
1490 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091491
[email protected]2431756e2010-09-29 20:26:131492 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]c9d6a1d2009-07-14 16:15:201493 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1494 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131495 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1496 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091497
[email protected]c9d6a1d2009-07-14 16:15:201498 EXPECT_EQ(1, GetOrderOfRequest(1));
1499 EXPECT_EQ(2, GetOrderOfRequest(2));
[email protected]c9c6f5c2010-07-31 01:30:031500 EXPECT_EQ(8, GetOrderOfRequest(3));
1501 EXPECT_EQ(6, GetOrderOfRequest(4));
1502 EXPECT_EQ(4, GetOrderOfRequest(5));
1503 EXPECT_EQ(3, GetOrderOfRequest(6));
1504 EXPECT_EQ(5, GetOrderOfRequest(7));
1505 EXPECT_EQ(7, GetOrderOfRequest(8));
[email protected]75439d3b2009-07-23 22:11:171506
1507 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131508 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]f6d1d6eb2009-06-24 20:16:091509}
1510
[email protected]ab838892009-06-30 18:49:051511TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:531512 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091513
Matt Menkec6b3edf72019-03-19 17:00:391514 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1515 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1516 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
1517 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1518 EXPECT_THAT(StartRequest(TestGroupId("a"), HIGHEST), IsError(ERR_IO_PENDING));
1519 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsError(ERR_IO_PENDING));
1520 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091521
[email protected]2431756e2010-09-29 20:26:131522 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091523
[email protected]2431756e2010-09-29 20:26:131524 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i)
robpercival214763f2016-07-01 23:27:011525 EXPECT_THAT(request(i)->WaitForResult(), IsOk());
[email protected]c9d6a1d2009-07-14 16:15:201526
[email protected]2431756e2010-09-29 20:26:131527 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]c9d6a1d2009-07-14 16:15:201528 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131529 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1530 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091531}
1532
Matt Menke7eb405e2019-04-25 20:48:211533TEST_F(ClientSocketPoolBaseTest, ResetAndCloseSocket) {
1534 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1535
1536 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1537 ClientSocketHandle handle;
1538 TestCompletionCallback callback;
1539 EXPECT_EQ(
1540 ERR_IO_PENDING,
1541 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
1542 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1543 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1544 pool_.get(), NetLogWithSource()));
1545
1546 EXPECT_THAT(callback.WaitForResult(), IsOk());
1547 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1548 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1549 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
1550 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
1551
1552 handle.ResetAndCloseSocket();
1553 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
1554}
1555
Matt Menke99251ea42019-04-25 22:59:021556// This test will start up a socket request and then call Reset() on the handle.
1557// The pending ConnectJob should not be destroyed.
Matt Menke7eb405e2019-04-25 20:48:211558TEST_F(ClientSocketPoolBaseTest, CancelRequestKeepsConnectJob) {
[email protected]211d21722009-07-22 15:48:531559 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201560
[email protected]ab838892009-06-30 18:49:051561 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131562 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521563 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:501564 EXPECT_EQ(
1565 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:281566 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
1567 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1568 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1569 pool_.get(), NetLogWithSource()));
[email protected]2431756e2010-09-29 20:26:131570 handle.Reset();
Matt Menke7eb405e2019-04-25 20:48:211571 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1572 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1573}
1574
Matt Menke99251ea42019-04-25 22:59:021575// This test will start up a socket request and then call ResetAndCloseSocket()
1576// on the handle. The pending ConnectJob or connected socket should be
1577// destroyed.
Matt Menke7eb405e2019-04-25 20:48:211578TEST_F(ClientSocketPoolBaseTest, CancelRequestAndCloseSocket) {
1579 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1580
Matt Menke99251ea42019-04-25 22:59:021581 // When true, the socket connects before it's canceled.
1582 for (bool cancel_when_callback_pending : {false, true}) {
1583 if (cancel_when_callback_pending) {
1584 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1585 } else {
1586 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1587 }
1588 ClientSocketHandle handle;
1589 TestCompletionCallback callback;
1590 EXPECT_EQ(
1591 ERR_IO_PENDING,
1592 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
1593 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1594 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1595 pool_.get(), NetLogWithSource()));
1596 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1597 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1598
1599 if (cancel_when_callback_pending) {
1600 client_socket_factory_.SignalJobs();
1601 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1602 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
1603 }
1604
1605 handle.ResetAndCloseSocket();
1606 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
1607 }
Matt Menke7eb405e2019-04-25 20:48:211608}
1609
1610TEST_F(ClientSocketPoolBaseTest,
1611 CancelRequestAndCloseSocketWhenMoreRequestsThanConnectJobs) {
1612 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1613
Matt Menke99251ea42019-04-25 22:59:021614 // When true, the sockets connect before they're canceled.
1615 for (bool cancel_when_callback_pending : {false, true}) {
1616 if (cancel_when_callback_pending) {
1617 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1618 } else {
1619 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1620 }
Matt Menke7eb405e2019-04-25 20:48:211621
Matt Menke99251ea42019-04-25 22:59:021622 std::vector<std::unique_ptr<ClientSocketHandle>> handles;
1623 TestCompletionCallback callback;
1624 // Make |kDefaultMaxSockets + 1| socket requests.
1625 for (int i = 0; i < kDefaultMaxSocketsPerGroup + 1; ++i) {
1626 std::unique_ptr<ClientSocketHandle> handle =
1627 std::make_unique<ClientSocketHandle>();
1628 EXPECT_EQ(ERR_IO_PENDING,
1629 handle->Init(
1630 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
1631 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1632 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1633 pool_.get(), NetLogWithSource()));
1634 handles.push_back(std::move(handle));
Matt Menke7eb405e2019-04-25 20:48:211635 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
Matt Menke99251ea42019-04-25 22:59:021636 EXPECT_EQ(
1637 static_cast<size_t>(std::min(i + 1, kDefaultMaxSocketsPerGroup)),
1638 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1639 }
1640
1641 if (cancel_when_callback_pending) {
1642 client_socket_factory_.SignalJobs();
1643 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1644 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1645 pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
1646 }
1647
1648 // Calling ResetAndCloseSocket() on a handle should not cancel a ConnectJob
1649 // or close a socket, since there are more requests than ConnectJobs or
1650 // sockets.
1651 handles[kDefaultMaxSocketsPerGroup]->ResetAndCloseSocket();
1652 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1653 if (cancel_when_callback_pending) {
1654 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1655 pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
1656 } else {
1657 EXPECT_EQ(static_cast<size_t>(kDefaultMaxSocketsPerGroup),
Matt Menke7eb405e2019-04-25 20:48:211658 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1659 }
Matt Menke99251ea42019-04-25 22:59:021660
1661 // Calling ResetAndCloseSocket() on other handles should cancel a ConnectJob
1662 // or close a socket.
1663 for (int i = kDefaultMaxSocketsPerGroup - 1; i >= 0; --i) {
1664 handles[i]->ResetAndCloseSocket();
1665 if (i > 0) {
1666 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1667 if (cancel_when_callback_pending) {
1668 EXPECT_EQ(i,
1669 pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
1670 } else {
1671 EXPECT_EQ(static_cast<size_t>(i),
1672 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1673 }
1674 } else {
1675 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
1676 }
1677 }
Matt Menke7eb405e2019-04-25 20:48:211678 }
[email protected]f6d1d6eb2009-06-24 20:16:091679}
1680
[email protected]ab838892009-06-30 18:49:051681TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531682 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201683
[email protected]ab838892009-06-30 18:49:051684 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061685 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521686 TestCompletionCallback callback;
[email protected]f6d1d6eb2009-06-24 20:16:091687
Matt Menke28ac03e2019-02-25 22:25:501688 EXPECT_EQ(
1689 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:281690 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
1691 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1692 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1693 pool_.get(), NetLogWithSource()));
[email protected]f6d1d6eb2009-06-24 20:16:091694
1695 handle.Reset();
Matt Menke7eb405e2019-04-25 20:48:211696 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1697 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]f6d1d6eb2009-06-24 20:16:091698
Matt Menke7eb405e2019-04-25 20:48:211699 // This will create a second ConnectJob, since the other ConnectJob was
1700 // previously assigned to a request.
[email protected]6ecf2b92011-12-15 01:14:521701 TestCompletionCallback callback2;
Matt Menke28ac03e2019-02-25 22:25:501702 EXPECT_EQ(
1703 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:281704 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
1705 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501706 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
1707 pool_.get(), NetLogWithSource()));
[email protected]f6d1d6eb2009-06-24 20:16:091708
Matt Menke7eb405e2019-04-25 20:48:211709 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1710 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1711
robpercival214763f2016-07-01 23:27:011712 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]f6d1d6eb2009-06-24 20:16:091713 EXPECT_FALSE(callback.have_result());
Matt Menke7eb405e2019-04-25 20:48:211714 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1715 // One ConnectJob completed, and its socket is now assigned to |handle|.
1716 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
1717 // The other ConnectJob should have either completed, or still be connecting.
1718 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")) +
1719 pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]f6d1d6eb2009-06-24 20:16:091720
1721 handle.Reset();
Matt Menke7eb405e2019-04-25 20:48:211722 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1723 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")) +
1724 pool_->IdleSocketCountInGroup(TestGroupId("a")));
1725 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
[email protected]f6d1d6eb2009-06-24 20:16:091726}
1727
[email protected]ab838892009-06-30 18:49:051728TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531729 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091730
Matt Menkec6b3edf72019-03-19 17:00:391731 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1732 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1733 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
1734 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1735 EXPECT_THAT(StartRequest(TestGroupId("a"), HIGHEST), IsError(ERR_IO_PENDING));
1736 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsError(ERR_IO_PENDING));
1737 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091738
1739 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:201740 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]2431756e2010-09-29 20:26:131741 EXPECT_FALSE((*requests())[index_to_cancel]->handle()->is_initialized());
1742 (*requests())[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091743
[email protected]2431756e2010-09-29 20:26:131744 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091745
[email protected]c9d6a1d2009-07-14 16:15:201746 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1747 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131748 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup - 1,
1749 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091750
[email protected]c9d6a1d2009-07-14 16:15:201751 EXPECT_EQ(1, GetOrderOfRequest(1));
1752 EXPECT_EQ(2, GetOrderOfRequest(2));
1753 EXPECT_EQ(5, GetOrderOfRequest(3));
1754 EXPECT_EQ(3, GetOrderOfRequest(4));
[email protected]2431756e2010-09-29 20:26:131755 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
1756 GetOrderOfRequest(5)); // Canceled request.
[email protected]c9d6a1d2009-07-14 16:15:201757 EXPECT_EQ(4, GetOrderOfRequest(6));
1758 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171759
1760 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131761 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:091762}
1763
mmenke33d24423d2015-05-19 19:41:091764// Function to be used as a callback on socket request completion. It first
1765// disconnects the successfully connected socket from the first request, and
1766// then reuses the ClientSocketHandle to request another socket.
1767//
1768// |nested_callback| is called with the result of the second socket request.
1769void RequestSocketOnComplete(ClientSocketHandle* handle,
Matt Menke9fa17d52019-03-25 19:12:261770 TransportClientSocketPool* pool,
mmenke33d24423d2015-05-19 19:41:091771 TestConnectJobFactory* test_connect_job_factory,
1772 TestConnectJob::JobType next_job_type,
Bence Békya4a50932018-08-10 13:39:411773 TestCompletionCallback* nested_callback,
mmenke33d24423d2015-05-19 19:41:091774 int first_request_result) {
robpercival214763f2016-07-01 23:27:011775 EXPECT_THAT(first_request_result, IsOk());
mmenke33d24423d2015-05-19 19:41:091776
1777 test_connect_job_factory->set_job_type(next_job_type);
1778
1779 // Don't allow reuse of the socket. Disconnect it and then release it.
1780 if (handle->socket())
1781 handle->socket()->Disconnect();
1782 handle->Reset();
1783
mmenke33d24423d2015-05-19 19:41:091784 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:501785 int rv = handle->Init(
Matt Menke870e19ab2019-04-23 16:23:031786 TestGroupId("a"),
Matt Menkef09e64c2019-04-23 22:16:281787 ClientSocketPool::SocketParams::CreateForHttpForTesting(), base::nullopt,
1788 LOWEST, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke870e19ab2019-04-23 16:23:031789 nested_callback->callback(), ClientSocketPool::ProxyAuthCallback(), pool,
1790 NetLogWithSource());
mmenke33d24423d2015-05-19 19:41:091791 if (rv != ERR_IO_PENDING) {
1792 DCHECK_EQ(TestConnectJob::kMockJob, next_job_type);
Bence Békya4a50932018-08-10 13:39:411793 nested_callback->callback().Run(rv);
mmenke33d24423d2015-05-19 19:41:091794 } else {
1795 DCHECK_EQ(TestConnectJob::kMockPendingJob, next_job_type);
[email protected]6ecf2b92011-12-15 01:14:521796 }
mmenke33d24423d2015-05-19 19:41:091797}
[email protected]f6d1d6eb2009-06-24 20:16:091798
mmenke33d24423d2015-05-19 19:41:091799// Tests the case where a second socket is requested in a completion callback,
1800// and the second socket connects asynchronously. Reuses the same
1801// ClientSocketHandle for the second socket, after disconnecting the first.
[email protected]2ab05b52009-07-01 23:57:581802TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531803 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201804
[email protected]0b7648c2009-07-06 20:14:011805 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061806 ClientSocketHandle handle;
mmenke33d24423d2015-05-19 19:41:091807 TestCompletionCallback second_result_callback;
1808 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:281809 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Paul Jensen8d6f87ec2018-01-13 00:46:541810 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501811 base::BindOnce(&RequestSocketOnComplete, &handle, pool_.get(),
1812 connect_job_factory_, TestConnectJob::kMockPendingJob,
1813 &second_result_callback),
1814 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011815 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091816
robpercival214763f2016-07-01 23:27:011817 EXPECT_THAT(second_result_callback.WaitForResult(), IsOk());
[email protected]2ab05b52009-07-01 23:57:581818}
[email protected]f6d1d6eb2009-06-24 20:16:091819
mmenke33d24423d2015-05-19 19:41:091820// Tests the case where a second socket is requested in a completion callback,
1821// and the second socket connects synchronously. Reuses the same
1822// ClientSocketHandle for the second socket, after disconnecting the first.
[email protected]2ab05b52009-07-01 23:57:581823TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531824 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201825
[email protected]0b7648c2009-07-06 20:14:011826 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061827 ClientSocketHandle handle;
mmenke33d24423d2015-05-19 19:41:091828 TestCompletionCallback second_result_callback;
1829 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:281830 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Paul Jensen8d6f87ec2018-01-13 00:46:541831 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501832 base::BindOnce(&RequestSocketOnComplete, &handle, pool_.get(),
1833 connect_job_factory_, TestConnectJob::kMockPendingJob,
1834 &second_result_callback),
1835 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011836 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2ab05b52009-07-01 23:57:581837
robpercival214763f2016-07-01 23:27:011838 EXPECT_THAT(second_result_callback.WaitForResult(), IsOk());
[email protected]f6d1d6eb2009-06-24 20:16:091839}
1840
1841// Make sure that pending requests get serviced after active requests get
1842// cancelled.
[email protected]ab838892009-06-30 18:49:051843TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531844 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201845
[email protected]0b7648c2009-07-06 20:14:011846 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091847
Matt Menkec6b3edf72019-03-19 17:00:391848 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1849 IsError(ERR_IO_PENDING));
1850 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1851 IsError(ERR_IO_PENDING));
1852 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1853 IsError(ERR_IO_PENDING));
1854 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1855 IsError(ERR_IO_PENDING));
1856 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1857 IsError(ERR_IO_PENDING));
1858 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1859 IsError(ERR_IO_PENDING));
1860 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1861 IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091862
[email protected]c9d6a1d2009-07-14 16:15:201863 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1864 // Let's cancel them.
1865 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]2431756e2010-09-29 20:26:131866 ASSERT_FALSE(request(i)->handle()->is_initialized());
1867 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091868 }
1869
[email protected]f6d1d6eb2009-06-24 20:16:091870 // Let's wait for the rest to complete now.
[email protected]2431756e2010-09-29 20:26:131871 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i) {
robpercival214763f2016-07-01 23:27:011872 EXPECT_THAT(request(i)->WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:131873 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091874 }
1875
[email protected]2431756e2010-09-29 20:26:131876 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1877 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091878}
1879
1880// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051881TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531882 const size_t kMaxSockets = 5;
1883 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201884
[email protected]0b7648c2009-07-06 20:14:011885 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091886
[email protected]211d21722009-07-22 15:48:531887 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1888 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091889
1890 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531891 for (size_t i = 0; i < kNumberOfRequests; ++i)
Matt Menkec6b3edf72019-03-19 17:00:391892 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1893 IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091894
[email protected]211d21722009-07-22 15:48:531895 for (size_t i = 0; i < kNumberOfRequests; ++i)
robpercival214763f2016-07-01 23:27:011896 EXPECT_THAT(request(i)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]f6d1d6eb2009-06-24 20:16:091897}
1898
mmenke9d72fe42017-05-18 22:36:071899// Make sure that pending requests that complete synchronously get serviced
1900// after active requests fail. See https://crbug.com/723748
1901TEST_F(ClientSocketPoolBaseTest, HandleMultipleSyncFailuresAfterAsyncFailure) {
1902 const size_t kNumberOfRequests = 10;
1903 const size_t kMaxSockets = 1;
1904 CreatePool(kMaxSockets, kMaxSockets);
1905
1906 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1907
Matt Menkec6b3edf72019-03-19 17:00:391908 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1909 IsError(ERR_IO_PENDING));
mmenke9d72fe42017-05-18 22:36:071910
1911 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
1912
1913 // Queue up all the other requests
1914 for (size_t i = 1; i < kNumberOfRequests; ++i)
Matt Menkec6b3edf72019-03-19 17:00:391915 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1916 IsError(ERR_IO_PENDING));
mmenke9d72fe42017-05-18 22:36:071917
1918 // Make sure all requests fail, instead of hanging.
1919 for (size_t i = 0; i < kNumberOfRequests; ++i)
1920 EXPECT_THAT(request(i)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
1921}
1922
[email protected]5fc08e32009-07-15 17:09:571923TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531924 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571925
1926 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1927
[email protected]2431756e2010-09-29 20:26:131928 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521929 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:501930 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:281931 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:501932 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1933 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011934 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:571935
1936 // Cancel the active request.
[email protected]2431756e2010-09-29 20:26:131937 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571938
Matt Menkef09e64c2019-04-23 22:16:281939 rv = handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
1940 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501941 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1942 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011943 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1944 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]5fc08e32009-07-15 17:09:571945
[email protected]2431756e2010-09-29 20:26:131946 EXPECT_FALSE(handle.is_reused());
[email protected]034df0f32013-01-07 23:17:481947 TestLoadTimingInfoConnectedNotReused(handle);
[email protected]5fc08e32009-07-15 17:09:571948 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1949}
1950
xunjieli26619e72016-11-23 19:39:551951TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsForced) {
Matt Menke433de6d2020-03-04 00:24:111952 const char kReason[] = "Really nifty reason";
1953
xunjieli26619e72016-11-23 19:39:551954 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1955 ClientSocketHandle handle;
1956 TestCompletionCallback callback;
Matt Muellerd9342e3a2019-11-26 01:41:141957 RecordingBoundTestNetLog log;
Matt Menke28ac03e2019-02-25 22:25:501958 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:281959 TestGroupId("a"), params_, base::nullopt, LOWEST, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:501960 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1961 ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound());
xunjieli26619e72016-11-23 19:39:551962 EXPECT_THAT(rv, IsOk());
Matt Menke433de6d2020-03-04 00:24:111963 ASSERT_TRUE(handle.socket());
1964 NetLogSource source = handle.socket()->NetLog().source();
xunjieli26619e72016-11-23 19:39:551965 handle.Reset();
1966 EXPECT_EQ(1, pool_->IdleSocketCount());
Matt Menke433de6d2020-03-04 00:24:111967 pool_->CloseIdleSockets(kReason);
1968 ExpectSocketClosedWithReason(source, kReason);
xunjieli26619e72016-11-23 19:39:551969}
1970
xunjieli92feb332017-03-03 17:19:231971TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsInGroupForced) {
xunjieli92feb332017-03-03 17:19:231972 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1973 TestCompletionCallback callback;
Matt Muellerd9342e3a2019-11-26 01:41:141974 RecordingBoundTestNetLog log;
xunjieli92feb332017-03-03 17:19:231975 ClientSocketHandle handle1;
Matt Menke28ac03e2019-02-25 22:25:501976 int rv = handle1.Init(
Matt Menkef09e64c2019-04-23 22:16:281977 TestGroupId("a"), params_, base::nullopt, LOWEST, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:501978 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1979 ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound());
xunjieli92feb332017-03-03 17:19:231980 EXPECT_THAT(rv, IsOk());
1981 ClientSocketHandle handle2;
Matt Menkef09e64c2019-04-23 22:16:281982 rv = handle2.Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
1983 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501984 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1985 pool_.get(), log.bound());
xunjieli92feb332017-03-03 17:19:231986 ClientSocketHandle handle3;
Matt Menkef09e64c2019-04-23 22:16:281987 rv = handle3.Init(TestGroupId("b"), params_, base::nullopt, LOWEST,
1988 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501989 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1990 pool_.get(), log.bound());
xunjieli92feb332017-03-03 17:19:231991 EXPECT_THAT(rv, IsOk());
1992 handle1.Reset();
1993 handle2.Reset();
1994 handle3.Reset();
1995 EXPECT_EQ(3, pool_->IdleSocketCount());
Matt Menke433de6d2020-03-04 00:24:111996 pool_->CloseIdleSocketsInGroup(TestGroupId("a"), "Very good reason");
xunjieli92feb332017-03-03 17:19:231997 EXPECT_EQ(1, pool_->IdleSocketCount());
xunjieli92feb332017-03-03 17:19:231998}
1999
xunjieli26619e72016-11-23 19:39:552000TEST_F(ClientSocketPoolBaseTest, CleanUpUnusableIdleSockets) {
xunjieli26619e72016-11-23 19:39:552001 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2002 ClientSocketHandle handle;
2003 TestCompletionCallback callback;
Matt Muellerd9342e3a2019-11-26 01:41:142004 RecordingBoundTestNetLog log;
Matt Menke28ac03e2019-02-25 22:25:502005 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:282006 TestGroupId("a"), params_, base::nullopt, LOWEST, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502007 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2008 ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound());
xunjieli26619e72016-11-23 19:39:552009 EXPECT_THAT(rv, IsOk());
2010 StreamSocket* socket = handle.socket();
Matt Menke433de6d2020-03-04 00:24:112011 ASSERT_TRUE(socket);
xunjieli26619e72016-11-23 19:39:552012 handle.Reset();
2013 EXPECT_EQ(1, pool_->IdleSocketCount());
2014
2015 // Disconnect socket now to make the socket unusable.
Matt Menke433de6d2020-03-04 00:24:112016 NetLogSource source = socket->NetLog().source();
xunjieli26619e72016-11-23 19:39:552017 socket->Disconnect();
2018 ClientSocketHandle handle2;
Matt Menkef09e64c2019-04-23 22:16:282019 rv = handle2.Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
2020 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502021 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2022 pool_.get(), log.bound());
xunjieli26619e72016-11-23 19:39:552023 EXPECT_THAT(rv, IsOk());
2024 EXPECT_FALSE(handle2.is_reused());
Matt Menke433de6d2020-03-04 00:24:112025
2026 // This is admittedly not an accurate error in this case, but normally code
2027 // doesn't secretly keep a raw pointers to sockets returned to the socket pool
2028 // and close them out of band, so discovering an idle socket was closed when
2029 // trying to reuse it normally means it was closed by the remote side.
2030 ExpectSocketClosedWithReason(
2031 source, TransportClientSocketPool::kRemoteSideClosedConnection);
xunjieli26619e72016-11-23 19:39:552032}
2033
[email protected]2b7523d2009-07-29 20:29:232034// Regression test for http://crbug.com/17985.
2035TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
2036 const int kMaxSockets = 3;
2037 const int kMaxSocketsPerGroup = 2;
2038 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
2039
[email protected]ac790b42009-12-02 04:31:312040 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:232041
Matt Menkec6b3edf72019-03-19 17:00:392042 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
2043 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
[email protected]2b7523d2009-07-29 20:29:232044
2045 // This is going to be a pending request in an otherwise empty group.
Matt Menkec6b3edf72019-03-19 17:00:392046 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2047 IsError(ERR_IO_PENDING));
[email protected]2b7523d2009-07-29 20:29:232048
2049 // Reach the maximum socket limit.
Matt Menkec6b3edf72019-03-19 17:00:392050 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
[email protected]2b7523d2009-07-29 20:29:232051
2052 // Create a stalled group with high priorities.
Matt Menkec6b3edf72019-03-19 17:00:392053 EXPECT_THAT(StartRequest(TestGroupId("c"), kHighPriority),
2054 IsError(ERR_IO_PENDING));
2055 EXPECT_THAT(StartRequest(TestGroupId("c"), kHighPriority),
2056 IsError(ERR_IO_PENDING));
[email protected]2b7523d2009-07-29 20:29:232057
Matt Menkec6b3edf72019-03-19 17:00:392058 // Release the first two sockets from TestGroupId("a"). Because this is a
2059 // keepalive, the first release will unblock the pending request for
2060 // TestGroupId("a"). The second release will unblock a request for "c",
2061 // because it is the next high priority socket.
[email protected]2431756e2010-09-29 20:26:132062 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
2063 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]2b7523d2009-07-29 20:29:232064
2065 // Closing idle sockets should not get us into trouble, but in the bug
2066 // we were hitting a CHECK here.
Matt Menkec6b3edf72019-03-19 17:00:392067 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menke433de6d2020-03-04 00:24:112068 pool_->CloseIdleSockets("Very good reason");
[email protected]eb5a99382010-07-11 03:18:262069
[email protected]2da659e2013-05-23 20:51:342070 // Run the released socket wakeups.
fdoray5eeb7642016-06-22 16:11:282071 base::RunLoop().RunUntilIdle();
[email protected]2b7523d2009-07-29 20:29:232072}
2073
[email protected]4d3b05d2010-01-27 21:27:292074TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:532075 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:572076
2077 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:132078 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522079 TestCompletionCallback callback;
Matt Muellerd9342e3a2019-11-26 01:41:142080 RecordingBoundTestNetLog log;
Matt Menke28ac03e2019-02-25 22:25:502081 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:282082 TestGroupId("a"), params_, base::nullopt, LOWEST, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502083 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2084 ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound());
robpercival214763f2016-07-01 23:27:012085 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Matt Menkec6b3edf72019-03-19 17:00:392086 EXPECT_EQ(LOAD_STATE_CONNECTING,
2087 pool_->GetLoadState(TestGroupId("a"), &handle));
[email protected]034df0f32013-01-07 23:17:482088 TestLoadTimingInfoNotConnected(handle);
2089
robpercival214763f2016-07-01 23:27:012090 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132091 EXPECT_TRUE(handle.is_initialized());
2092 EXPECT_TRUE(handle.socket());
[email protected]034df0f32013-01-07 23:17:482093 TestLoadTimingInfoConnectedNotReused(handle);
2094
[email protected]2431756e2010-09-29 20:26:132095 handle.Reset();
[email protected]034df0f32013-01-07 23:17:482096 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:302097
Eric Roman79cc7552019-07-19 02:17:542098 auto entries = log.GetEntries();
[email protected]b2fcd0e2010-12-01 15:19:402099
Matt Menke9fa17d52019-03-25 19:12:262100 EXPECT_EQ(5u, entries.size());
[email protected]06650c52010-06-03 00:49:172101 EXPECT_TRUE(LogContainsEvent(
Matt Menke9fa17d52019-03-25 19:12:262102 entries, 0, NetLogEventType::TCP_CLIENT_SOCKET_POOL_REQUESTED_SOCKET,
mikecirone8b85c432016-09-08 19:11:002103 NetLogEventPhase::NONE));
Matt Menke9fa17d52019-03-25 19:12:262104 EXPECT_TRUE(LogContainsBeginEvent(entries, 1, NetLogEventType::SOCKET_POOL));
2105 EXPECT_TRUE(LogContainsEvent(
2106 entries, 2, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
2107 NetLogEventPhase::NONE));
2108 EXPECT_TRUE(LogContainsEvent(entries, 3,
mikecirone8b85c432016-09-08 19:11:002109 NetLogEventType::SOCKET_POOL_BOUND_TO_SOCKET,
2110 NetLogEventPhase::NONE));
Matt Menke9fa17d52019-03-25 19:12:262111 EXPECT_TRUE(LogContainsEndEvent(entries, 4, NetLogEventType::SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:572112}
2113
[email protected]4d3b05d2010-01-27 21:27:292114TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:572115 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:532116 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:572117
2118 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]2431756e2010-09-29 20:26:132119 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522120 TestCompletionCallback callback;
Matt Muellerd9342e3a2019-11-26 01:41:142121 RecordingBoundTestNetLog log;
[email protected]e60e47a2010-07-14 03:37:182122 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:132123 handle.set_is_ssl_error(true);
Matt Menke39b7c5a2019-04-10 19:47:512124 handle.set_ssl_cert_request_info(base::MakeRefCounted<SSLCertRequestInfo>());
Matt Menke28ac03e2019-02-25 22:25:502125 EXPECT_EQ(
2126 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:282127 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2128 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2129 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2130 pool_.get(), log.bound()));
Matt Menkec6b3edf72019-03-19 17:00:392131 EXPECT_EQ(LOAD_STATE_CONNECTING,
2132 pool_->GetLoadState(TestGroupId("a"), &handle));
robpercival214763f2016-07-01 23:27:012133 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]2431756e2010-09-29 20:26:132134 EXPECT_FALSE(handle.is_ssl_error());
Matt Menke39b7c5a2019-04-10 19:47:512135 EXPECT_FALSE(handle.ssl_cert_request_info());
[email protected]fd7b7c92009-08-20 19:38:302136
Eric Roman79cc7552019-07-19 02:17:542137 auto entries = log.GetEntries();
[email protected]b2fcd0e2010-12-01 15:19:402138
Matt Menke9fa17d52019-03-25 19:12:262139 EXPECT_EQ(4u, entries.size());
[email protected]06650c52010-06-03 00:49:172140 EXPECT_TRUE(LogContainsEvent(
Matt Menke9fa17d52019-03-25 19:12:262141 entries, 0, NetLogEventType::TCP_CLIENT_SOCKET_POOL_REQUESTED_SOCKET,
mikecirone8b85c432016-09-08 19:11:002142 NetLogEventPhase::NONE));
Matt Menke9fa17d52019-03-25 19:12:262143 EXPECT_TRUE(LogContainsBeginEvent(entries, 1, NetLogEventType::SOCKET_POOL));
2144 EXPECT_TRUE(LogContainsEvent(
2145 entries, 2, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
2146 NetLogEventPhase::NONE));
2147 EXPECT_TRUE(LogContainsEndEvent(entries, 3, NetLogEventType::SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:572148}
2149
mmenke6be122f2015-03-09 22:22:472150// Check that an async ConnectJob failure does not result in creation of a new
2151// ConnectJob when there's another pending request also waiting on its own
2152// ConnectJob. See http://crbug.com/463960.
2153TEST_F(ClientSocketPoolBaseTest, AsyncFailureWithPendingRequestWithJob) {
2154 CreatePool(2, 2);
2155 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2156
Matt Menkec6b3edf72019-03-19 17:00:392157 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2158 IsError(ERR_IO_PENDING));
2159 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2160 IsError(ERR_IO_PENDING));
mmenke6be122f2015-03-09 22:22:472161
robpercival214763f2016-07-01 23:27:012162 EXPECT_THAT(request(0)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
2163 EXPECT_THAT(request(1)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
mmenke6be122f2015-03-09 22:22:472164
2165 EXPECT_EQ(2, client_socket_factory_.allocation_count());
2166}
2167
[email protected]4d3b05d2010-01-27 21:27:292168TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]b22b5162010-03-16 07:53:102169 // TODO(eroman): Add back the log expectations! Removed them because the
2170 // ordering is difficult, and some may fire during destructor.
[email protected]211d21722009-07-22 15:48:532171 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:572172
2173 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:132174 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522175 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132176 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522177 TestCompletionCallback callback2;
[email protected]5fc08e32009-07-15 17:09:572178
Matt Menke28ac03e2019-02-25 22:25:502179 EXPECT_EQ(
2180 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:282181 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2182 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2183 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2184 pool_.get(), NetLogWithSource()));
Matt Muellerd9342e3a2019-11-26 01:41:142185 RecordingBoundTestNetLog log2;
tfarina428341112016-09-22 13:38:202186 EXPECT_EQ(
2187 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:282188 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2189 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502190 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2191 pool_.get(), NetLogWithSource()));
[email protected]5fc08e32009-07-15 17:09:572192
[email protected]2431756e2010-09-29 20:26:132193 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:572194
[email protected]fd7b7c92009-08-20 19:38:302195
2196 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]fd7b7c92009-08-20 19:38:302197
robpercival214763f2016-07-01 23:27:012198 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132199 handle2.Reset();
[email protected]fd7b7c92009-08-20 19:38:302200
2201 // Now request 2 has actually finished.
[email protected]9e743cd2010-03-16 07:03:532202 // TODO(eroman): Add back log expectations.
[email protected]5fc08e32009-07-15 17:09:572203}
2204
[email protected]4d3b05d2010-01-27 21:27:292205TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:342206 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2207
[email protected]17a0c6c2009-08-04 00:07:042208 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2209
Matt Menkec6b3edf72019-03-19 17:00:392210 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
2211 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsError(ERR_IO_PENDING));
2212 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
2213 EXPECT_THAT(StartRequest(TestGroupId("a"), HIGHEST), IsError(ERR_IO_PENDING));
[email protected]974ebd62009-08-03 23:14:342214
Raul Tambre8335a6d2019-02-21 16:57:432215 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
Matt Menke9fa17d52019-03-25 19:12:262216 static_cast<int>(
2217 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))));
[email protected]2431756e2010-09-29 20:26:132218 (*requests())[2]->handle()->Reset();
2219 (*requests())[3]->handle()->Reset();
Raul Tambre8335a6d2019-02-21 16:57:432220 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
Matt Menke9fa17d52019-03-25 19:12:262221 static_cast<int>(
2222 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))));
[email protected]974ebd62009-08-03 23:14:342223
[email protected]2431756e2010-09-29 20:26:132224 (*requests())[1]->handle()->Reset();
Raul Tambre8335a6d2019-02-21 16:57:432225 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
Matt Menke9fa17d52019-03-25 19:12:262226 static_cast<int>(
2227 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))));
[email protected]974ebd62009-08-03 23:14:342228
[email protected]2431756e2010-09-29 20:26:132229 (*requests())[0]->handle()->Reset();
Raul Tambre8335a6d2019-02-21 16:57:432230 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
Matt Menke9fa17d52019-03-25 19:12:262231 static_cast<int>(
2232 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))));
[email protected]974ebd62009-08-03 23:14:342233}
2234
[email protected]5fc08e32009-07-15 17:09:572235// When requests and ConnectJobs are not coupled, the request will get serviced
2236// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:292237TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:532238 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:572239
2240 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:322241 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:572242
[email protected]2431756e2010-09-29 20:26:132243 std::vector<TestSocketRequest*> request_order;
2244 size_t completion_count; // unused
2245 TestSocketRequest req1(&request_order, &completion_count);
Matt Menke28ac03e2019-02-25 22:25:502246 int rv = req1.handle()->Init(
Matt Menkef09e64c2019-04-23 22:16:282247 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502248 ClientSocketPool::RespectLimits::ENABLED, req1.callback(),
2249 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012250 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2251 EXPECT_THAT(req1.WaitForResult(), IsOk());
[email protected]5fc08e32009-07-15 17:09:572252
2253 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
2254 // without a job.
2255 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2256
[email protected]2431756e2010-09-29 20:26:132257 TestSocketRequest req2(&request_order, &completion_count);
Matt Menke28ac03e2019-02-25 22:25:502258 rv = req2.handle()->Init(
Matt Menkef09e64c2019-04-23 22:16:282259 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502260 ClientSocketPool::RespectLimits::ENABLED, req2.callback(),
2261 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012262 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2431756e2010-09-29 20:26:132263 TestSocketRequest req3(&request_order, &completion_count);
Matt Menke28ac03e2019-02-25 22:25:502264 rv = req3.handle()->Init(
Matt Menkef09e64c2019-04-23 22:16:282265 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502266 ClientSocketPool::RespectLimits::ENABLED, req3.callback(),
2267 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012268 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:572269
2270 // Both Requests 2 and 3 are pending. We release socket 1 which should
2271 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:332272 req1.handle()->Reset();
[email protected]2da659e2013-05-23 20:51:342273 // Run the released socket wakeups.
fdoray5eeb7642016-06-22 16:11:282274 base::RunLoop().RunUntilIdle();
[email protected]a6c59f62009-07-29 16:33:332275 ASSERT_TRUE(req2.handle()->socket());
robpercival214763f2016-07-01 23:27:012276 EXPECT_THAT(req2.WaitForResult(), IsOk());
[email protected]a6c59f62009-07-29 16:33:332277 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:572278
2279 // Signal job 2, which should service request 3.
2280
2281 client_socket_factory_.SignalJobs();
robpercival214763f2016-07-01 23:27:012282 EXPECT_THAT(req3.WaitForResult(), IsOk());
[email protected]5fc08e32009-07-15 17:09:572283
Raul Tambre8335a6d2019-02-21 16:57:432284 ASSERT_EQ(3u, request_order.size());
[email protected]2431756e2010-09-29 20:26:132285 EXPECT_EQ(&req1, request_order[0]);
2286 EXPECT_EQ(&req2, request_order[1]);
2287 EXPECT_EQ(&req3, request_order[2]);
Matt Menkec6b3edf72019-03-19 17:00:392288 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]5fc08e32009-07-15 17:09:572289}
2290
2291// The requests are not coupled to the jobs. So, the requests should finish in
2292// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:292293TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:532294 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:572295 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:322296 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:572297
[email protected]2431756e2010-09-29 20:26:132298 std::vector<TestSocketRequest*> request_order;
2299 size_t completion_count; // unused
2300 TestSocketRequest req1(&request_order, &completion_count);
Matt Menke28ac03e2019-02-25 22:25:502301 int rv = req1.handle()->Init(
Matt Menkef09e64c2019-04-23 22:16:282302 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502303 ClientSocketPool::RespectLimits::ENABLED, req1.callback(),
2304 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012305 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:572306
[email protected]2431756e2010-09-29 20:26:132307 TestSocketRequest req2(&request_order, &completion_count);
Matt Menke28ac03e2019-02-25 22:25:502308 rv = req2.handle()->Init(
Matt Menkef09e64c2019-04-23 22:16:282309 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502310 ClientSocketPool::RespectLimits::ENABLED, req2.callback(),
2311 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012312 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:572313
2314 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:322315 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:572316
[email protected]2431756e2010-09-29 20:26:132317 TestSocketRequest req3(&request_order, &completion_count);
Matt Menke28ac03e2019-02-25 22:25:502318 rv = req3.handle()->Init(
Matt Menkef09e64c2019-04-23 22:16:282319 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502320 ClientSocketPool::RespectLimits::ENABLED, req3.callback(),
2321 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012322 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:572323
robpercival214763f2016-07-01 23:27:012324 EXPECT_THAT(req1.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
2325 EXPECT_THAT(req2.WaitForResult(), IsOk());
2326 EXPECT_THAT(req3.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]5fc08e32009-07-15 17:09:572327
Raul Tambre8335a6d2019-02-21 16:57:432328 ASSERT_EQ(3u, request_order.size());
[email protected]2431756e2010-09-29 20:26:132329 EXPECT_EQ(&req1, request_order[0]);
2330 EXPECT_EQ(&req2, request_order[1]);
2331 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:572332}
2333
[email protected]03b7c8c2013-07-20 04:38:552334// Test GetLoadState in the case there's only one socket request.
2335TEST_F(ClientSocketPoolBaseTest, LoadStateOneRequest) {
[email protected]211d21722009-07-22 15:48:532336 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]03b7c8c2013-07-20 04:38:552337 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
[email protected]5fc08e32009-07-15 17:09:572338
[email protected]2431756e2010-09-29 20:26:132339 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522340 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502341 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:282342 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502343 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2344 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012345 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552346 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:572347
[email protected]03b7c8c2013-07-20 04:38:552348 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2349 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
2350
2351 // No point in completing the connection, since ClientSocketHandles only
2352 // expect the LoadState to be checked while connecting.
2353}
2354
2355// Test GetLoadState in the case there are two socket requests.
2356TEST_F(ClientSocketPoolBaseTest, LoadStateTwoRequests) {
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));
haavardm835c1d62015-04-22 08:18:002367 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_RESOLVING_HOST);
2368
2369 ClientSocketHandle handle2;
2370 TestCompletionCallback callback2;
Matt Menkef09e64c2019-04-23 22:16:282371 rv = handle2.Init(TestGroupId("a"), 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));
haavardm835c1d62015-04-22 08:18:002376 client_socket_factory_.SetJobLoadState(1, LOAD_STATE_RESOLVING_HOST);
2377
Matt Menke4b69f932019-03-04 16:20:012378 // Each handle should reflect the state of its own job.
haavardm835c1d62015-04-22 08:18:002379 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle.GetLoadState());
2380 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle2.GetLoadState());
2381
Matt Menke4b69f932019-03-04 16:20:012382 // Update the state of the first job.
haavardm835c1d62015-04-22 08:18:002383 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_CONNECTING);
2384
Matt Menke4b69f932019-03-04 16:20:012385 // Only the state of the first request should have changed.
haavardm835c1d62015-04-22 08:18:002386 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
haavardm835c1d62015-04-22 08:18:002387 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle2.GetLoadState());
Matt Menke4b69f932019-03-04 16:20:012388
2389 // Update the state of the second job.
2390 client_socket_factory_.SetJobLoadState(1, LOAD_STATE_SSL_HANDSHAKE);
2391
2392 // Only the state of the second request should have changed.
2393 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2394 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle2.GetLoadState());
2395
2396 // Second job connects and the first request gets the socket. The
2397 // second handle switches to the state of the remaining ConnectJob.
2398 client_socket_factory_.SignalJob(1);
2399 EXPECT_THAT(callback.WaitForResult(), IsOk());
2400 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
[email protected]03b7c8c2013-07-20 04:38:552401}
2402
2403// Test GetLoadState in the case the per-group limit is reached.
2404TEST_F(ClientSocketPoolBaseTest, LoadStateGroupLimit) {
2405 CreatePool(2, 1);
2406 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2407
2408 ClientSocketHandle handle;
2409 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502410 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:282411 TestGroupId("a"), params_, base::nullopt, MEDIUM, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502412 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2413 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012414 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552415 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2416
2417 // Request another socket from the same pool, buth with a higher priority.
2418 // The first request should now be stalled at the socket group limit.
2419 ClientSocketHandle handle2;
2420 TestCompletionCallback callback2;
Matt Menkef09e64c2019-04-23 22:16:282421 rv = handle2.Init(TestGroupId("a"), params_, base::nullopt, HIGHEST,
2422 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502423 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2424 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012425 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552426 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2427 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
2428
2429 // The first handle should remain stalled as the other socket goes through
2430 // the connect process.
2431
2432 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2433 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2434 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle2.GetLoadState());
2435
2436 client_socket_factory_.SignalJob(0);
robpercival214763f2016-07-01 23:27:012437 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]03b7c8c2013-07-20 04:38:552438 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2439
2440 // Closing the second socket should cause the stalled handle to finally get a
2441 // ConnectJob.
2442 handle2.socket()->Disconnect();
2443 handle2.Reset();
2444 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2445}
2446
2447// Test GetLoadState in the case the per-pool limit is reached.
2448TEST_F(ClientSocketPoolBaseTest, LoadStatePoolLimit) {
2449 CreatePool(2, 2);
2450 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2451
2452 ClientSocketHandle handle;
2453 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502454 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:282455 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502456 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2457 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012458 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552459
2460 // Request for socket from another pool.
2461 ClientSocketHandle handle2;
2462 TestCompletionCallback callback2;
Matt Menkef09e64c2019-04-23 22:16:282463 rv = handle2.Init(TestGroupId("b"), params_, base::nullopt, DEFAULT_PRIORITY,
2464 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502465 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2466 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012467 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552468
2469 // Request another socket from the first pool. Request should stall at the
2470 // socket pool limit.
2471 ClientSocketHandle handle3;
2472 TestCompletionCallback callback3;
Matt Menkef09e64c2019-04-23 22:16:282473 rv = handle3.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2474 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502475 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2476 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012477 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552478
2479 // The third handle should remain stalled as the other sockets in its group
2480 // goes through the connect process.
2481
2482 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2483 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2484
2485 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2486 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
2487 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2488
2489 client_socket_factory_.SignalJob(0);
robpercival214763f2016-07-01 23:27:012490 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]03b7c8c2013-07-20 04:38:552491 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2492
2493 // Closing a socket should allow the stalled handle to finally get a new
2494 // ConnectJob.
2495 handle.socket()->Disconnect();
2496 handle.Reset();
2497 EXPECT_EQ(LOAD_STATE_CONNECTING, handle3.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:572498}
2499
Matt Menkeb57663b32019-03-01 17:17:102500TEST_F(ClientSocketPoolBaseTest, CertError) {
[email protected]e772db3f2010-07-12 18:11:132501 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
Matt Menkeb57663b32019-03-01 17:17:102502 connect_job_factory_->set_job_type(TestConnectJob::kMockCertErrorJob);
[email protected]e772db3f2010-07-12 18:11:132503
[email protected]2431756e2010-09-29 20:26:132504 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522505 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502506 EXPECT_EQ(
Matt Menkeb57663b32019-03-01 17:17:102507 ERR_CERT_COMMON_NAME_INVALID,
Matt Menkef09e64c2019-04-23 22:16:282508 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2509 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2510 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2511 pool_.get(), NetLogWithSource()));
[email protected]2431756e2010-09-29 20:26:132512 EXPECT_TRUE(handle.is_initialized());
2513 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:132514}
2515
Matt Menkeb57663b32019-03-01 17:17:102516TEST_F(ClientSocketPoolBaseTest, AsyncCertError) {
[email protected]e772db3f2010-07-12 18:11:132517 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2518
Matt Menkeb57663b32019-03-01 17:17:102519 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingCertErrorJob);
[email protected]2431756e2010-09-29 20:26:132520 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522521 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502522 EXPECT_EQ(
2523 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:282524 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2525 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2526 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2527 pool_.get(), NetLogWithSource()));
Matt Menkec6b3edf72019-03-19 17:00:392528 EXPECT_EQ(LOAD_STATE_CONNECTING,
2529 pool_->GetLoadState(TestGroupId("a"), &handle));
Matt Menkeb57663b32019-03-01 17:17:102530 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CERT_COMMON_NAME_INVALID));
[email protected]2431756e2010-09-29 20:26:132531 EXPECT_TRUE(handle.is_initialized());
2532 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:132533}
2534
[email protected]e60e47a2010-07-14 03:37:182535TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) {
2536 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2537 connect_job_factory_->set_job_type(
2538 TestConnectJob::kMockAdditionalErrorStateJob);
2539
[email protected]2431756e2010-09-29 20:26:132540 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522541 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502542 EXPECT_EQ(
2543 ERR_CONNECTION_FAILED,
Matt Menkef09e64c2019-04-23 22:16:282544 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2545 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2546 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2547 pool_.get(), NetLogWithSource()));
[email protected]2431756e2010-09-29 20:26:132548 EXPECT_FALSE(handle.is_initialized());
2549 EXPECT_FALSE(handle.socket());
2550 EXPECT_TRUE(handle.is_ssl_error());
Matt Menke39b7c5a2019-04-10 19:47:512551 EXPECT_TRUE(handle.ssl_cert_request_info());
[email protected]e60e47a2010-07-14 03:37:182552}
2553
2554TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) {
2555 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2556
2557 connect_job_factory_->set_job_type(
2558 TestConnectJob::kMockPendingAdditionalErrorStateJob);
[email protected]2431756e2010-09-29 20:26:132559 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522560 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502561 EXPECT_EQ(
2562 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:282563 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2564 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2565 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2566 pool_.get(), NetLogWithSource()));
Matt Menkec6b3edf72019-03-19 17:00:392567 EXPECT_EQ(LOAD_STATE_CONNECTING,
2568 pool_->GetLoadState(TestGroupId("a"), &handle));
robpercival214763f2016-07-01 23:27:012569 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]2431756e2010-09-29 20:26:132570 EXPECT_FALSE(handle.is_initialized());
2571 EXPECT_FALSE(handle.socket());
2572 EXPECT_TRUE(handle.is_ssl_error());
Matt Menke39b7c5a2019-04-10 19:47:512573 EXPECT_TRUE(handle.ssl_cert_request_info());
[email protected]e60e47a2010-07-14 03:37:182574}
2575
martijn003cd612016-05-19 22:24:382576// Make sure we can reuse sockets.
2577TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSocketsReuse) {
[email protected]64770b7d2011-11-16 04:30:412578 CreatePoolWithIdleTimeouts(
2579 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
[email protected]e7b1c6d2c2012-05-05 00:54:032580 base::TimeDelta(), // Time out unused sockets immediately.
2581 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2582
2583 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2584
2585 ClientSocketHandle handle;
2586 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502587 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:282588 TestGroupId("a"), params_, base::nullopt, LOWEST, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502589 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2590 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012591 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
Matt Menkec6b3edf72019-03-19 17:00:392592 EXPECT_EQ(LOAD_STATE_CONNECTING,
2593 pool_->GetLoadState(TestGroupId("a"), &handle));
robpercival214763f2016-07-01 23:27:012594 ASSERT_THAT(callback.WaitForResult(), IsOk());
[email protected]e7b1c6d2c2012-05-05 00:54:032595
2596 // Use and release the socket.
Raul Tambre94493c652019-03-11 17:18:352597 EXPECT_EQ(1, handle.socket()->Write(nullptr, 1, CompletionOnceCallback(),
Ramin Halavati0a08cc82018-02-06 07:46:382598 TRAFFIC_ANNOTATION_FOR_TESTS));
[email protected]034df0f32013-01-07 23:17:482599 TestLoadTimingInfoConnectedNotReused(handle);
[email protected]e7b1c6d2c2012-05-05 00:54:032600 handle.Reset();
2601
2602 // Should now have one idle socket.
2603 ASSERT_EQ(1, pool_->IdleSocketCount());
2604
2605 // Request a new socket. This should reuse the old socket and complete
2606 // synchronously.
Matt Muellerd9342e3a2019-11-26 01:41:142607 RecordingBoundTestNetLog log;
Matt Menke28ac03e2019-02-25 22:25:502608 rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:282609 TestGroupId("a"), params_, base::nullopt, LOWEST, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502610 ClientSocketPool::RespectLimits::ENABLED, CompletionOnceCallback(),
2611 ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound());
robpercival214763f2016-07-01 23:27:012612 ASSERT_THAT(rv, IsOk());
[email protected]e7b1c6d2c2012-05-05 00:54:032613 EXPECT_TRUE(handle.is_reused());
[email protected]034df0f32013-01-07 23:17:482614 TestLoadTimingInfoConnectedReused(handle);
[email protected]e7b1c6d2c2012-05-05 00:54:032615
Matt Menke9fa17d52019-03-25 19:12:262616 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:392617 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menke9fa17d52019-03-25 19:12:262618 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
[email protected]e7b1c6d2c2012-05-05 00:54:032619
Eric Roman79cc7552019-07-19 02:17:542620 auto entries = log.GetEntries();
Matt Menke9fa17d52019-03-25 19:12:262621 EXPECT_TRUE(LogContainsEvent(
2622 entries, 0, NetLogEventType::TCP_CLIENT_SOCKET_POOL_REQUESTED_SOCKET,
2623 NetLogEventPhase::NONE));
2624 EXPECT_TRUE(LogContainsBeginEvent(entries, 1, NetLogEventType::SOCKET_POOL));
[email protected]e7b1c6d2c2012-05-05 00:54:032625 EXPECT_TRUE(LogContainsEntryWithType(
Matt Menke9fa17d52019-03-25 19:12:262626 entries, 2, NetLogEventType::SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]e7b1c6d2c2012-05-05 00:54:032627}
2628
martijn003cd612016-05-19 22:24:382629// Make sure we cleanup old unused sockets.
Eric Romanb49715e2018-04-24 22:41:172630TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSocketsNoReuse) {
[email protected]e7b1c6d2c2012-05-05 00:54:032631 CreatePoolWithIdleTimeouts(
2632 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2633 base::TimeDelta(), // Time out unused sockets immediately
2634 base::TimeDelta()); // Time out used sockets immediately
[email protected]64770b7d2011-11-16 04:30:412635
2636 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2637
2638 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
2639
2640 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522641 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502642 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:282643 TestGroupId("a"), params_, base::nullopt, LOWEST, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502644 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2645 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012646 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
Matt Menkec6b3edf72019-03-19 17:00:392647 EXPECT_EQ(LOAD_STATE_CONNECTING,
2648 pool_->GetLoadState(TestGroupId("a"), &handle));
[email protected]64770b7d2011-11-16 04:30:412649
2650 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522651 TestCompletionCallback callback2;
Matt Menkef09e64c2019-04-23 22:16:282652 rv = handle2.Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
2653 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502654 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2655 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012656 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
Matt Menkec6b3edf72019-03-19 17:00:392657 EXPECT_EQ(LOAD_STATE_CONNECTING,
2658 pool_->GetLoadState(TestGroupId("a"), &handle2));
[email protected]64770b7d2011-11-16 04:30:412659
2660 // Cancel one of the requests. Wait for the other, which will get the first
2661 // job. Release the socket. Run the loop again to make sure the second
2662 // socket is sitting idle and the first one is released (since ReleaseSocket()
2663 // just posts a DoReleaseSocket() task).
2664
2665 handle.Reset();
robpercival214763f2016-07-01 23:27:012666 ASSERT_THAT(callback2.WaitForResult(), IsOk());
Matt Menke433de6d2020-03-04 00:24:112667 // Get the NetLogSource for the socket, so the time out reason can be checked
2668 // at the end of the test.
2669 NetLogSource net_log_source2 = handle2.socket()->NetLog().source();
[email protected]64770b7d2011-11-16 04:30:412670 // Use the socket.
Raul Tambre94493c652019-03-11 17:18:352671 EXPECT_EQ(1, handle2.socket()->Write(nullptr, 1, CompletionOnceCallback(),
Ramin Halavati0a08cc82018-02-06 07:46:382672 TRAFFIC_ANNOTATION_FOR_TESTS));
[email protected]64770b7d2011-11-16 04:30:412673 handle2.Reset();
2674
[email protected]e7b1c6d2c2012-05-05 00:54:032675 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
2676 // actually become pending until 2ms after they have been created. In order
2677 // to flush all tasks, we need to wait so that we know there are no
2678 // soon-to-be-pending tasks waiting.
Alex Clarke0def2092018-12-10 12:01:452679 FastForwardBy(base::TimeDelta::FromMilliseconds(10));
[email protected]64770b7d2011-11-16 04:30:412680
[email protected]e7b1c6d2c2012-05-05 00:54:032681 // Both sockets should now be idle.
[email protected]64770b7d2011-11-16 04:30:412682 ASSERT_EQ(2, pool_->IdleSocketCount());
2683
2684 // Request a new socket. This should cleanup the unused and timed out ones.
2685 // A new socket will be created rather than reusing the idle one.
Matt Muellerd9342e3a2019-11-26 01:41:142686 RecordingBoundTestNetLog log;
[email protected]6ecf2b92011-12-15 01:14:522687 TestCompletionCallback callback3;
Matt Menkef09e64c2019-04-23 22:16:282688 rv = handle.Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
2689 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502690 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
2691 pool_.get(), log.bound());
robpercival214763f2016-07-01 23:27:012692 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
2693 ASSERT_THAT(callback3.WaitForResult(), IsOk());
[email protected]64770b7d2011-11-16 04:30:412694 EXPECT_FALSE(handle.is_reused());
2695
[email protected]e7b1c6d2c2012-05-05 00:54:032696 // Make sure the idle socket is closed.
Matt Menke9fa17d52019-03-25 19:12:262697 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:392698 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menke9fa17d52019-03-25 19:12:262699 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
[email protected]64770b7d2011-11-16 04:30:412700
Eric Roman79cc7552019-07-19 02:17:542701 auto entries = log.GetEntries();
[email protected]64770b7d2011-11-16 04:30:412702 EXPECT_FALSE(LogContainsEntryWithType(
mikecirone8b85c432016-09-08 19:11:002703 entries, 1, NetLogEventType::SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
Matt Menke433de6d2020-03-04 00:24:112704 ExpectSocketClosedWithReason(
2705 net_log_source2, TransportClientSocketPool::kIdleTimeLimitExpired);
[email protected]64770b7d2011-11-16 04:30:412706}
2707
[email protected]2041cf342010-02-19 03:15:592708// Make sure that we process all pending requests even when we're stalling
[email protected]4f2abec2010-02-03 18:10:162709// because of multiple releasing disconnected sockets.
2710TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
2711 CreatePoolWithIdleTimeouts(
2712 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2713 base::TimeDelta(), // Time out unused sockets immediately.
2714 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2715
2716 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2717
2718 // Startup 4 connect jobs. Two of them will be pending.
2719
[email protected]2431756e2010-09-29 20:26:132720 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522721 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502722 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:282723 TestGroupId("a"), params_, base::nullopt, LOWEST, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502724 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2725 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012726 EXPECT_THAT(rv, IsOk());
[email protected]4f2abec2010-02-03 18:10:162727
[email protected]2431756e2010-09-29 20:26:132728 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522729 TestCompletionCallback callback2;
Matt Menkef09e64c2019-04-23 22:16:282730 rv = handle2.Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
2731 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502732 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2733 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012734 EXPECT_THAT(rv, IsOk());
[email protected]4f2abec2010-02-03 18:10:162735
[email protected]2431756e2010-09-29 20:26:132736 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:522737 TestCompletionCallback callback3;
Matt Menkef09e64c2019-04-23 22:16:282738 rv = handle3.Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
2739 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502740 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
2741 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012742 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4f2abec2010-02-03 18:10:162743
[email protected]2431756e2010-09-29 20:26:132744 ClientSocketHandle handle4;
[email protected]6ecf2b92011-12-15 01:14:522745 TestCompletionCallback callback4;
Matt Menkef09e64c2019-04-23 22:16:282746 rv = handle4.Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
2747 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502748 callback4.callback(), ClientSocketPool::ProxyAuthCallback(),
2749 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012750 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4f2abec2010-02-03 18:10:162751
2752 // Release two disconnected sockets.
2753
[email protected]2431756e2010-09-29 20:26:132754 handle.socket()->Disconnect();
2755 handle.Reset();
2756 handle2.socket()->Disconnect();
2757 handle2.Reset();
[email protected]4f2abec2010-02-03 18:10:162758
robpercival214763f2016-07-01 23:27:012759 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132760 EXPECT_FALSE(handle3.is_reused());
robpercival214763f2016-07-01 23:27:012761 EXPECT_THAT(callback4.WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132762 EXPECT_FALSE(handle4.is_reused());
[email protected]4f2abec2010-02-03 18:10:162763}
2764
[email protected]d7027bb2010-05-10 18:58:542765// Regression test for http://crbug.com/42267.
2766// When DoReleaseSocket() is processed for one socket, it is blocked because the
2767// other stalled groups all have releasing sockets, so no progress can be made.
2768TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
2769 CreatePoolWithIdleTimeouts(
2770 4 /* socket limit */, 4 /* socket limit per group */,
2771 base::TimeDelta(), // Time out unused sockets immediately.
2772 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2773
2774 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2775
2776 // Max out the socket limit with 2 per group.
2777
[email protected]2431756e2010-09-29 20:26:132778 ClientSocketHandle handle_a[4];
[email protected]6ecf2b92011-12-15 01:14:522779 TestCompletionCallback callback_a[4];
[email protected]2431756e2010-09-29 20:26:132780 ClientSocketHandle handle_b[4];
[email protected]6ecf2b92011-12-15 01:14:522781 TestCompletionCallback callback_b[4];
[email protected]d7027bb2010-05-10 18:58:542782
2783 for (int i = 0; i < 2; ++i) {
Matt Menkef09e64c2019-04-23 22:16:282784 EXPECT_EQ(OK, handle_a[i].Init(TestGroupId("a"), params_, base::nullopt,
2785 LOWEST, SocketTag(),
2786 ClientSocketPool::RespectLimits::ENABLED,
2787 callback_a[i].callback(),
2788 ClientSocketPool::ProxyAuthCallback(),
2789 pool_.get(), NetLogWithSource()));
2790 EXPECT_EQ(OK, handle_b[i].Init(TestGroupId("b"), params_, base::nullopt,
2791 LOWEST, SocketTag(),
2792 ClientSocketPool::RespectLimits::ENABLED,
2793 callback_b[i].callback(),
2794 ClientSocketPool::ProxyAuthCallback(),
2795 pool_.get(), NetLogWithSource()));
[email protected]d7027bb2010-05-10 18:58:542796 }
[email protected]b89f7e42010-05-20 20:37:002797
[email protected]d7027bb2010-05-10 18:58:542798 // Make 4 pending requests, 2 per group.
2799
2800 for (int i = 2; i < 4; ++i) {
Matt Menkef09e64c2019-04-23 22:16:282801 EXPECT_EQ(
2802 ERR_IO_PENDING,
2803 handle_a[i].Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
2804 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2805 callback_a[i].callback(),
2806 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2807 NetLogWithSource()));
2808 EXPECT_EQ(
2809 ERR_IO_PENDING,
2810 handle_b[i].Init(TestGroupId("b"), params_, base::nullopt, LOWEST,
2811 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2812 callback_b[i].callback(),
2813 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2814 NetLogWithSource()));
[email protected]d7027bb2010-05-10 18:58:542815 }
2816
2817 // Release b's socket first. The order is important, because in
2818 // DoReleaseSocket(), we'll process b's released socket, and since both b and
2819 // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
2820 // first, which has a releasing socket, so it refuses to start up another
2821 // ConnectJob. So, we used to infinite loop on this.
[email protected]2431756e2010-09-29 20:26:132822 handle_b[0].socket()->Disconnect();
2823 handle_b[0].Reset();
2824 handle_a[0].socket()->Disconnect();
2825 handle_a[0].Reset();
[email protected]d7027bb2010-05-10 18:58:542826
2827 // Used to get stuck here.
fdoray5eeb7642016-06-22 16:11:282828 base::RunLoop().RunUntilIdle();
[email protected]d7027bb2010-05-10 18:58:542829
[email protected]2431756e2010-09-29 20:26:132830 handle_b[1].socket()->Disconnect();
2831 handle_b[1].Reset();
2832 handle_a[1].socket()->Disconnect();
2833 handle_a[1].Reset();
[email protected]d7027bb2010-05-10 18:58:542834
2835 for (int i = 2; i < 4; ++i) {
robpercival214763f2016-07-01 23:27:012836 EXPECT_THAT(callback_b[i].WaitForResult(), IsOk());
2837 EXPECT_THAT(callback_a[i].WaitForResult(), IsOk());
[email protected]d7027bb2010-05-10 18:58:542838 }
2839}
2840
[email protected]fd4fe0b2010-02-08 23:02:152841TEST_F(ClientSocketPoolBaseTest,
2842 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
2843 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2844
2845 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2846
Matt Menkec6b3edf72019-03-19 17:00:392847 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2848 IsError(ERR_IO_PENDING));
2849 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2850 IsError(ERR_IO_PENDING));
2851 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2852 IsError(ERR_IO_PENDING));
2853 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2854 IsError(ERR_IO_PENDING));
[email protected]fd4fe0b2010-02-08 23:02:152855
robpercival214763f2016-07-01 23:27:012856 EXPECT_THAT((*requests())[0]->WaitForResult(), IsOk());
2857 EXPECT_THAT((*requests())[1]->WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132858 EXPECT_EQ(2u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152859
2860 // Releases one connection.
[email protected]2431756e2010-09-29 20:26:132861 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
robpercival214763f2016-07-01 23:27:012862 EXPECT_THAT((*requests())[2]->WaitForResult(), IsOk());
[email protected]fd4fe0b2010-02-08 23:02:152863
[email protected]2431756e2010-09-29 20:26:132864 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
robpercival214763f2016-07-01 23:27:012865 EXPECT_THAT((*requests())[3]->WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132866 EXPECT_EQ(4u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152867
2868 EXPECT_EQ(1, GetOrderOfRequest(1));
2869 EXPECT_EQ(2, GetOrderOfRequest(2));
2870 EXPECT_EQ(3, GetOrderOfRequest(3));
2871 EXPECT_EQ(4, GetOrderOfRequest(4));
2872
2873 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:132874 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(5));
[email protected]fd4fe0b2010-02-08 23:02:152875}
2876
[email protected]6ecf2b92011-12-15 01:14:522877class TestReleasingSocketRequest : public TestCompletionCallbackBase {
[email protected]4f1e4982010-03-02 18:31:042878 public:
Matt Menke9fa17d52019-03-25 19:12:262879 TestReleasingSocketRequest(TransportClientSocketPool* pool,
[email protected]2431756e2010-09-29 20:26:132880 int expected_result,
[email protected]e60e47a2010-07-14 03:37:182881 bool reset_releasing_handle)
2882 : pool_(pool),
2883 expected_result_(expected_result),
Bence Béky8ddc2492018-06-13 01:02:042884 reset_releasing_handle_(reset_releasing_handle) {}
[email protected]6ecf2b92011-12-15 01:14:522885
Chris Watkins7a41d3552017-12-01 02:13:272886 ~TestReleasingSocketRequest() override = default;
[email protected]4f1e4982010-03-02 18:31:042887
2888 ClientSocketHandle* handle() { return &handle_; }
2889
Bence Béky8ddc2492018-06-13 01:02:042890 CompletionOnceCallback callback() {
2891 return base::BindOnce(&TestReleasingSocketRequest::OnComplete,
2892 base::Unretained(this));
2893 }
[email protected]4f1e4982010-03-02 18:31:042894
2895 private:
[email protected]6ecf2b92011-12-15 01:14:522896 void OnComplete(int result) {
2897 SetResult(result);
2898 if (reset_releasing_handle_)
2899 handle_.Reset();
2900
Matt Menkec6b3edf72019-03-19 17:00:392901 EXPECT_EQ(
2902 expected_result_,
Matt Menke870e19ab2019-04-23 16:23:032903 handle2_.Init(
2904 TestGroupId("a"),
2905 ClientSocketPool::SocketParams::CreateForHttpForTesting(),
Matt Menkef09e64c2019-04-23 22:16:282906 base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menke870e19ab2019-04-23 16:23:032907 ClientSocketPool::RespectLimits::ENABLED, CompletionOnceCallback(),
2908 ClientSocketPool::ProxyAuthCallback(), pool_, NetLogWithSource()));
[email protected]6ecf2b92011-12-15 01:14:522909 }
2910
Matt Menke9fa17d52019-03-25 19:12:262911 TransportClientSocketPool* const pool_;
[email protected]e60e47a2010-07-14 03:37:182912 int expected_result_;
2913 bool reset_releasing_handle_;
[email protected]4f1e4982010-03-02 18:31:042914 ClientSocketHandle handle_;
2915 ClientSocketHandle handle2_;
[email protected]4f1e4982010-03-02 18:31:042916};
2917
[email protected]e60e47a2010-07-14 03:37:182918
2919TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) {
2920 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2921
Matt Menkec6b3edf72019-03-19 17:00:392922 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
2923 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
2924 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
[email protected]e60e47a2010-07-14 03:37:182925
[email protected]2431756e2010-09-29 20:26:132926 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]e60e47a2010-07-14 03:37:182927 client_socket_factory_.allocation_count());
2928
2929 connect_job_factory_->set_job_type(
2930 TestConnectJob::kMockPendingAdditionalErrorStateJob);
2931 TestReleasingSocketRequest req(pool_.get(), OK, false);
Matt Menkef09e64c2019-04-23 22:16:282932 EXPECT_EQ(ERR_IO_PENDING,
2933 req.handle()->Init(
2934 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2935 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2936 req.callback(), ClientSocketPool::ProxyAuthCallback(),
2937 pool_.get(), NetLogWithSource()));
[email protected]e60e47a2010-07-14 03:37:182938 // The next job should complete synchronously
2939 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2940
robpercival214763f2016-07-01 23:27:012941 EXPECT_THAT(req.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:182942 EXPECT_FALSE(req.handle()->is_initialized());
2943 EXPECT_FALSE(req.handle()->socket());
2944 EXPECT_TRUE(req.handle()->is_ssl_error());
Matt Menke39b7c5a2019-04-10 19:47:512945 EXPECT_TRUE(req.handle()->ssl_cert_request_info());
[email protected]e60e47a2010-07-14 03:37:182946}
2947
[email protected]b6501d3d2010-06-03 23:53:342948// http://crbug.com/44724 regression test.
2949// We start releasing the pool when we flush on network change. When that
2950// happens, the only active references are in the ClientSocketHandles. When a
2951// ConnectJob completes and calls back into the last ClientSocketHandle, that
2952// callback can release the last reference and delete the pool. After the
2953// callback finishes, we go back to the stack frame within the now-deleted pool.
2954// Executing any code that refers to members of the now-deleted pool can cause
2955// crashes.
2956TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
2957 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2958 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2959
2960 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522961 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502962 EXPECT_EQ(
2963 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:282964 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2965 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2966 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2967 pool_.get(), NetLogWithSource()));
[email protected]b6501d3d2010-06-03 23:53:342968
Matt Menke433de6d2020-03-04 00:24:112969 pool_->FlushWithError(ERR_NETWORK_CHANGED, "Network changed");
[email protected]b6501d3d2010-06-03 23:53:342970
2971 // We'll call back into this now.
2972 callback.WaitForResult();
2973}
2974
[email protected]a7e38572010-06-07 18:22:242975TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
2976 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2977 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2978
2979 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522980 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502981 EXPECT_EQ(
2982 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:282983 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2984 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2985 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2986 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:012987 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]a7e38572010-06-07 18:22:242988 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
Matt Menke433de6d2020-03-04 00:24:112989 NetLogSource source = handle.socket()->NetLog().source();
[email protected]a7e38572010-06-07 18:22:242990
Matt Menke433de6d2020-03-04 00:24:112991 pool_->FlushWithError(ERR_NETWORK_CHANGED, "Network changed");
[email protected]a7e38572010-06-07 18:22:242992
2993 handle.Reset();
fdoray5eeb7642016-06-22 16:11:282994 base::RunLoop().RunUntilIdle();
[email protected]a7e38572010-06-07 18:22:242995
Matt Menke28ac03e2019-02-25 22:25:502996 EXPECT_EQ(
2997 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:282998 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2999 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3000 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3001 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013002 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]a7e38572010-06-07 18:22:243003 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
Matt Menke433de6d2020-03-04 00:24:113004
3005 ExpectSocketClosedWithReason(
3006 source, TransportClientSocketPool::kSocketGenerationOutOfDate);
[email protected]a7e38572010-06-07 18:22:243007}
3008
[email protected]6ecf2b92011-12-15 01:14:523009class ConnectWithinCallback : public TestCompletionCallbackBase {
[email protected]06f92462010-08-31 19:24:143010 public:
Matt Menke9fa17d52019-03-25 19:12:263011 ConnectWithinCallback(
3012 const ClientSocketPool::GroupId& group_id,
Matt Menke84d11e562019-03-27 00:11:193013 const scoped_refptr<ClientSocketPool::SocketParams>& params,
Matt Menke9fa17d52019-03-25 19:12:263014 TransportClientSocketPool* pool)
Matt Menkec6b3edf72019-03-19 17:00:393015 : group_id_(group_id), params_(params), pool_(pool) {}
[email protected]06f92462010-08-31 19:24:143016
Chris Watkins7a41d3552017-12-01 02:13:273017 ~ConnectWithinCallback() override = default;
[email protected]06f92462010-08-31 19:24:143018
3019 int WaitForNestedResult() {
3020 return nested_callback_.WaitForResult();
3021 }
3022
Bence Béky8ddc2492018-06-13 01:02:043023 CompletionOnceCallback callback() {
3024 return base::BindOnce(&ConnectWithinCallback::OnComplete,
3025 base::Unretained(this));
3026 }
[email protected]6ecf2b92011-12-15 01:14:523027
[email protected]06f92462010-08-31 19:24:143028 private:
[email protected]6ecf2b92011-12-15 01:14:523029 void OnComplete(int result) {
3030 SetResult(result);
Matt Menkef09e64c2019-04-23 22:16:283031 EXPECT_EQ(
3032 ERR_IO_PENDING,
3033 handle_.Init(group_id_, params_, base::nullopt, DEFAULT_PRIORITY,
3034 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3035 nested_callback_.callback(),
3036 ClientSocketPool::ProxyAuthCallback(), pool_,
3037 NetLogWithSource()));
[email protected]6ecf2b92011-12-15 01:14:523038 }
3039
Matt Menkec6b3edf72019-03-19 17:00:393040 const ClientSocketPool::GroupId group_id_;
Matt Menke84d11e562019-03-27 00:11:193041 const scoped_refptr<ClientSocketPool::SocketParams> params_;
Matt Menke9fa17d52019-03-25 19:12:263042 TransportClientSocketPool* const pool_;
[email protected]06f92462010-08-31 19:24:143043 ClientSocketHandle handle_;
[email protected]6ecf2b92011-12-15 01:14:523044 TestCompletionCallback nested_callback_;
3045
3046 DISALLOW_COPY_AND_ASSIGN(ConnectWithinCallback);
[email protected]06f92462010-08-31 19:24:143047};
3048
3049TEST_F(ClientSocketPoolBaseTest, AbortAllRequestsOnFlush) {
3050 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3051
3052 // First job will be waiting until it gets aborted.
3053 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3054
3055 ClientSocketHandle handle;
Matt Menkec6b3edf72019-03-19 17:00:393056 ConnectWithinCallback callback(TestGroupId("a"), params_, pool_.get());
Matt Menke28ac03e2019-02-25 22:25:503057 EXPECT_EQ(
3058 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283059 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3060 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3061 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3062 pool_.get(), NetLogWithSource()));
[email protected]06f92462010-08-31 19:24:143063
3064 // Second job will be started during the first callback, and will
3065 // asynchronously complete with OK.
3066 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
Matt Menke433de6d2020-03-04 00:24:113067 pool_->FlushWithError(ERR_NETWORK_CHANGED, "Network changed");
robpercival214763f2016-07-01 23:27:013068 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NETWORK_CHANGED));
3069 EXPECT_THAT(callback.WaitForNestedResult(), IsOk());
[email protected]06f92462010-08-31 19:24:143070}
3071
Matt Menke141b87f22019-01-30 02:43:033072TEST_F(ClientSocketPoolBaseTest, BackupSocketWaitsForHostResolution) {
Matt Menke9fa17d52019-03-25 19:12:263073 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets,
3074 true /* enable_backup_connect_jobs */);
Matt Menke141b87f22019-01-30 02:43:033075
3076 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3077 ClientSocketHandle handle;
3078 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:503079 EXPECT_EQ(
3080 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283081 handle.Init(TestGroupId("bar"), params_, base::nullopt, DEFAULT_PRIORITY,
3082 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3083 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3084 pool_.get(), NetLogWithSource()));
Matt Menke141b87f22019-01-30 02:43:033085 // The backup timer fires but doesn't start a new ConnectJob while resolving
3086 // the hostname.
3087 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_RESOLVING_HOST);
3088 FastForwardBy(base::TimeDelta::FromMilliseconds(
3089 ClientSocketPool::kMaxConnectRetryIntervalMs * 100));
3090 EXPECT_EQ(1, client_socket_factory_.allocation_count());
3091
3092 // Once the ConnectJob has finished resolving the hostname, the backup timer
3093 // will create a ConnectJob when it fires.
3094 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_CONNECTING);
3095 FastForwardBy(base::TimeDelta::FromMilliseconds(
3096 ClientSocketPool::kMaxConnectRetryIntervalMs));
3097 EXPECT_EQ(2, client_socket_factory_.allocation_count());
3098}
3099
3100// Test that no backup socket is created when a ConnectJob connects before it
3101// completes.
3102TEST_F(ClientSocketPoolBaseTest, NoBackupSocketWhenConnected) {
Matt Menke9fa17d52019-03-25 19:12:263103 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets,
3104 true /* enable_backup_connect_jobs */);
Matt Menke141b87f22019-01-30 02:43:033105
3106 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3107 ClientSocketHandle handle;
3108 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:503109 EXPECT_EQ(
3110 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283111 handle.Init(TestGroupId("bar"), params_, base::nullopt, DEFAULT_PRIORITY,
3112 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3113 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3114 pool_.get(), NetLogWithSource()));
Matt Menke141b87f22019-01-30 02:43:033115 // The backup timer fires but doesn't start a new ConnectJob while resolving
3116 // the hostname.
3117 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_RESOLVING_HOST);
3118 FastForwardBy(base::TimeDelta::FromMilliseconds(
3119 ClientSocketPool::kMaxConnectRetryIntervalMs * 100));
3120 EXPECT_EQ(1, client_socket_factory_.allocation_count());
3121
3122 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
3123 client_socket_factory_.SetJobHasEstablishedConnection(0);
3124 FastForwardBy(base::TimeDelta::FromMilliseconds(
3125 ClientSocketPool::kMaxConnectRetryIntervalMs * 100));
3126 EXPECT_EQ(1, client_socket_factory_.allocation_count());
3127}
3128
[email protected]25eea382010-07-10 23:55:263129// Cancel a pending socket request while we're at max sockets,
3130// and verify that the backup socket firing doesn't cause a crash.
3131TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
3132 // Max 4 sockets globally, max 4 sockets per group.
Matt Menke9fa17d52019-03-25 19:12:263133 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets,
3134 true /* enable_backup_connect_jobs */);
[email protected]25eea382010-07-10 23:55:263135
[email protected]4baaf9d2010-08-31 15:15:443136 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
3137 // timer.
[email protected]25eea382010-07-10 23:55:263138 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3139 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:523140 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:503141 EXPECT_EQ(
3142 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283143 handle.Init(TestGroupId("bar"), params_, base::nullopt, DEFAULT_PRIORITY,
3144 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3145 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3146 pool_.get(), NetLogWithSource()));
[email protected]25eea382010-07-10 23:55:263147
3148 // Start (MaxSockets - 1) connected sockets to reach max sockets.
3149 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3150 ClientSocketHandle handles[kDefaultMaxSockets];
3151 for (int i = 1; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:523152 TestCompletionCallback callback;
Matt Menkef09e64c2019-04-23 22:16:283153 EXPECT_EQ(OK, handles[i].Init(TestGroupId("bar"), params_, base::nullopt,
3154 DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203155 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503156 callback.callback(),
3157 ClientSocketPool::ProxyAuthCallback(),
3158 pool_.get(), NetLogWithSource()));
[email protected]25eea382010-07-10 23:55:263159 }
3160
fdoray5eeb7642016-06-22 16:11:283161 base::RunLoop().RunUntilIdle();
[email protected]25eea382010-07-10 23:55:263162
3163 // Cancel the pending request.
3164 handle.Reset();
3165
3166 // Wait for the backup timer to fire (add some slop to ensure it fires)
Alex Clarke0def2092018-12-10 12:01:453167 FastForwardBy(base::TimeDelta::FromMilliseconds(
[email protected]26b9973962012-01-28 00:57:003168 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]25eea382010-07-10 23:55:263169
[email protected]25eea382010-07-10 23:55:263170 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
3171}
3172
[email protected]3f00be82010-09-27 19:50:023173TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterCancelingAllRequests) {
Matt Menke9fa17d52019-03-25 19:12:263174 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets,
3175 true /* enable_backup_connect_jobs */);
[email protected]4baaf9d2010-08-31 15:15:443176
3177 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
3178 // timer.
3179 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3180 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:523181 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:503182 EXPECT_EQ(
3183 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283184 handle.Init(TestGroupId("bar"), params_, base::nullopt, DEFAULT_PRIORITY,
3185 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3186 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3187 pool_.get(), NetLogWithSource()));
Matt Menke9fa17d52019-03-25 19:12:263188 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("bar")));
3189 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("bar")));
3190 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3191 TestGroupId("bar")));
3192 EXPECT_EQ(
3193 0u, pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("bar")));
[email protected]4baaf9d2010-08-31 15:15:443194
3195 // Cancel the socket request. This should cancel the backup timer. Wait for
3196 // the backup time to see if it indeed got canceled.
3197 handle.Reset();
3198 // Wait for the backup timer to fire (add some slop to ensure it fires)
Alex Clarke0def2092018-12-10 12:01:453199 FastForwardBy(base::TimeDelta::FromMilliseconds(
[email protected]26b9973962012-01-28 00:57:003200 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
Matt Menke9fa17d52019-03-25 19:12:263201 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("bar")));
3202 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("bar")));
[email protected]4baaf9d2010-08-31 15:15:443203}
3204
[email protected]3f00be82010-09-27 19:50:023205TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterFinishingAllRequests) {
Matt Menke9fa17d52019-03-25 19:12:263206 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets,
3207 true /* enable_backup_connect_jobs */);
[email protected]3f00be82010-09-27 19:50:023208
3209 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
3210 // timer.
3211 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3212 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:523213 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:503214 EXPECT_EQ(
3215 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283216 handle.Init(TestGroupId("bar"), params_, base::nullopt, DEFAULT_PRIORITY,
3217 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3218 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3219 pool_.get(), NetLogWithSource()));
[email protected]3f00be82010-09-27 19:50:023220 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3221 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523222 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203223 EXPECT_EQ(
3224 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283225 handle2.Init(TestGroupId("bar"), params_, base::nullopt, DEFAULT_PRIORITY,
3226 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503227 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3228 pool_.get(), NetLogWithSource()));
Matt Menke9fa17d52019-03-25 19:12:263229 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("bar")));
3230 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("bar")));
[email protected]3f00be82010-09-27 19:50:023231
3232 // Cancel request 1 and then complete request 2. With the requests finished,
3233 // the backup timer should be cancelled.
3234 handle.Reset();
robpercival214763f2016-07-01 23:27:013235 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]3f00be82010-09-27 19:50:023236 // Wait for the backup timer to fire (add some slop to ensure it fires)
Alex Clarke0def2092018-12-10 12:01:453237 FastForwardBy(base::TimeDelta::FromMilliseconds(
[email protected]26b9973962012-01-28 00:57:003238 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]3f00be82010-09-27 19:50:023239}
3240
[email protected]eb5a99382010-07-11 03:18:263241// Test delayed socket binding for the case where we have two connects,
3242// and while one is waiting on a connect, the other frees up.
3243// The socket waiting on a connect should switch immediately to the freed
3244// up socket.
3245TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
3246 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3247 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3248
3249 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523250 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:503251 EXPECT_EQ(
3252 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283253 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3254 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503255 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3256 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013257 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:263258
3259 // No idle sockets, no pending jobs.
3260 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menke9fa17d52019-03-25 19:12:263261 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263262
3263 // Create a second socket to the same host, but this one will wait.
3264 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3265 ClientSocketHandle handle2;
Matt Menke28ac03e2019-02-25 22:25:503266 EXPECT_EQ(
3267 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283268 handle2.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()));
[email protected]eb5a99382010-07-11 03:18:263272 // No idle sockets, and one connecting job.
3273 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menke9fa17d52019-03-25 19:12:263274 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263275
3276 // Return the first handle to the pool. This will initiate the delayed
3277 // binding.
3278 handle1.Reset();
3279
fdoray5eeb7642016-06-22 16:11:283280 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263281
3282 // Still no idle sockets, still one pending connect job.
3283 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menke9fa17d52019-03-25 19:12:263284 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263285
3286 // The second socket connected, even though it was a Waiting Job.
robpercival214763f2016-07-01 23:27:013287 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:263288
3289 // And we can see there is still one job waiting.
Matt Menke9fa17d52019-03-25 19:12:263290 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263291
3292 // Finally, signal the waiting Connect.
3293 client_socket_factory_.SignalJobs();
Matt Menke9fa17d52019-03-25 19:12:263294 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263295
fdoray5eeb7642016-06-22 16:11:283296 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263297}
3298
3299// Test delayed socket binding when a group is at capacity and one
3300// of the group's sockets frees up.
3301TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
3302 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3303 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3304
3305 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523306 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:503307 EXPECT_EQ(
3308 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283309 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3310 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503311 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3312 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013313 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:263314
3315 // No idle sockets, no pending jobs.
3316 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menke9fa17d52019-03-25 19:12:263317 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263318
3319 // Create a second socket to the same host, but this one will wait.
3320 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3321 ClientSocketHandle handle2;
Matt Menke28ac03e2019-02-25 22:25:503322 EXPECT_EQ(
3323 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283324 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3325 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503326 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3327 pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:263328 // No idle sockets, and one connecting job.
3329 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menke9fa17d52019-03-25 19:12:263330 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263331
3332 // Return the first handle to the pool. This will initiate the delayed
3333 // binding.
3334 handle1.Reset();
3335
fdoray5eeb7642016-06-22 16:11:283336 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263337
3338 // Still no idle sockets, still one pending connect job.
3339 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menke9fa17d52019-03-25 19:12:263340 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263341
3342 // The second socket connected, even though it was a Waiting Job.
robpercival214763f2016-07-01 23:27:013343 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:263344
3345 // And we can see there is still one job waiting.
Matt Menke9fa17d52019-03-25 19:12:263346 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263347
3348 // Finally, signal the waiting Connect.
3349 client_socket_factory_.SignalJobs();
Matt Menke9fa17d52019-03-25 19:12:263350 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263351
fdoray5eeb7642016-06-22 16:11:283352 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263353}
3354
3355// Test out the case where we have one socket connected, one
3356// connecting, when the first socket finishes and goes idle.
[email protected]2abfe90a2010-08-25 17:49:513357// Although the second connection is pending, the second request
[email protected]eb5a99382010-07-11 03:18:263358// should complete, by taking the first socket's idle socket.
3359TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
3360 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3361 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3362
3363 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523364 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:503365 EXPECT_EQ(
3366 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283367 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3368 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503369 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3370 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013371 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:263372
3373 // No idle sockets, no pending jobs.
3374 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menke9fa17d52019-03-25 19:12:263375 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263376
3377 // Create a second socket to the same host, but this one will wait.
3378 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3379 ClientSocketHandle handle2;
Matt Menke28ac03e2019-02-25 22:25:503380 EXPECT_EQ(
3381 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283382 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3383 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503384 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3385 pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:263386 // No idle sockets, and one connecting job.
3387 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menke9fa17d52019-03-25 19:12:263388 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263389
3390 // Return the first handle to the pool. This will initiate the delayed
3391 // binding.
3392 handle1.Reset();
3393
fdoray5eeb7642016-06-22 16:11:283394 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263395
3396 // Still no idle sockets, still one pending connect job.
3397 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menke9fa17d52019-03-25 19:12:263398 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263399
3400 // The second socket connected, even though it was a Waiting Job.
robpercival214763f2016-07-01 23:27:013401 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:263402
3403 // And we can see there is still one job waiting.
Matt Menke9fa17d52019-03-25 19:12:263404 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263405
3406 // Finally, signal the waiting Connect.
3407 client_socket_factory_.SignalJobs();
Matt Menke9fa17d52019-03-25 19:12:263408 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263409
fdoray5eeb7642016-06-22 16:11:283410 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263411}
3412
[email protected]2abfe90a2010-08-25 17:49:513413// Cover the case where on an available socket slot, we have one pending
3414// request that completes synchronously, thereby making the Group empty.
3415TEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) {
3416 const int kUnlimitedSockets = 100;
3417 const int kOneSocketPerGroup = 1;
3418 CreatePool(kUnlimitedSockets, kOneSocketPerGroup);
3419
3420 // Make the first request asynchronous fail.
3421 // This will free up a socket slot later.
3422 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
3423
3424 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523425 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203426 EXPECT_EQ(
3427 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283428 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3429 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503430 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3431 pool_.get(), NetLogWithSource()));
Matt Menke9fa17d52019-03-25 19:12:263432 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]2abfe90a2010-08-25 17:49:513433
3434 // Make the second request synchronously fail. This should make the Group
3435 // empty.
3436 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3437 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523438 TestCompletionCallback callback2;
[email protected]2abfe90a2010-08-25 17:49:513439 // It'll be ERR_IO_PENDING now, but the TestConnectJob will synchronously fail
3440 // when created.
tfarina428341112016-09-22 13:38:203441 EXPECT_EQ(
3442 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283443 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3444 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503445 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3446 pool_.get(), NetLogWithSource()));
[email protected]2abfe90a2010-08-25 17:49:513447
Matt Menke9fa17d52019-03-25 19:12:263448 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]2abfe90a2010-08-25 17:49:513449
robpercival214763f2016-07-01 23:27:013450 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
3451 EXPECT_THAT(callback2.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
Matt Menke9fa17d52019-03-25 19:12:263452 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
[email protected]2abfe90a2010-08-25 17:49:513453}
3454
[email protected]e1b54dc2010-10-06 21:27:223455TEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) {
3456 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3457
3458 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3459
3460 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523461 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203462 EXPECT_EQ(
3463 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283464 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3465 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503466 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3467 pool_.get(), NetLogWithSource()));
[email protected]e1b54dc2010-10-06 21:27:223468
3469 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523470 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203471 EXPECT_EQ(
3472 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283473 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3474 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503475 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3476 pool_.get(), NetLogWithSource()));
[email protected]e1b54dc2010-10-06 21:27:223477 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:523478 TestCompletionCallback callback3;
tfarina428341112016-09-22 13:38:203479 EXPECT_EQ(
3480 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283481 handle3.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3482 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503483 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
3484 pool_.get(), NetLogWithSource()));
[email protected]e1b54dc2010-10-06 21:27:223485
robpercival214763f2016-07-01 23:27:013486 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3487 EXPECT_THAT(callback2.WaitForResult(), IsOk());
3488 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]e1b54dc2010-10-06 21:27:223489
3490 // Use the socket.
Raul Tambre94493c652019-03-11 17:18:353491 EXPECT_EQ(1, handle1.socket()->Write(nullptr, 1, CompletionOnceCallback(),
Ramin Halavati0a08cc82018-02-06 07:46:383492 TRAFFIC_ANNOTATION_FOR_TESTS));
Raul Tambre94493c652019-03-11 17:18:353493 EXPECT_EQ(1, handle3.socket()->Write(nullptr, 1, CompletionOnceCallback(),
Ramin Halavati0a08cc82018-02-06 07:46:383494 TRAFFIC_ANNOTATION_FOR_TESTS));
[email protected]e1b54dc2010-10-06 21:27:223495
3496 handle1.Reset();
3497 handle2.Reset();
3498 handle3.Reset();
3499
Matt Menkec6b3edf72019-03-19 17:00:393500 EXPECT_EQ(OK, handle1.Init(
Matt Menkef09e64c2019-04-23 22:16:283501 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3502 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menkec6b3edf72019-03-19 17:00:393503 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3504 pool_.get(), NetLogWithSource()));
3505 EXPECT_EQ(OK, handle2.Init(
Matt Menkef09e64c2019-04-23 22:16:283506 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3507 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menkec6b3edf72019-03-19 17:00:393508 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3509 pool_.get(), NetLogWithSource()));
3510 EXPECT_EQ(OK, handle3.Init(
Matt Menkef09e64c2019-04-23 22:16:283511 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3512 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menkec6b3edf72019-03-19 17:00:393513 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
3514 pool_.get(), NetLogWithSource()));
[email protected]e1b54dc2010-10-06 21:27:223515
3516 EXPECT_TRUE(handle1.socket()->WasEverUsed());
3517 EXPECT_TRUE(handle2.socket()->WasEverUsed());
3518 EXPECT_FALSE(handle3.socket()->WasEverUsed());
3519}
3520
[email protected]2c2bef152010-10-13 00:55:033521TEST_F(ClientSocketPoolBaseTest, RequestSockets) {
3522 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3523 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3524
Matt Menkef09e64c2019-04-23 22:16:283525 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
3526 NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033527
Matt Menke9fa17d52019-03-25 19:12:263528 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3529 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3530 EXPECT_EQ(2u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3531 TestGroupId("a")));
3532 EXPECT_EQ(2u,
3533 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393534 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033535
3536 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523537 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203538 EXPECT_EQ(
3539 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283540 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3541 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503542 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3543 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033544
3545 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523546 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203547 EXPECT_EQ(
3548 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283549 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3550 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503551 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3552 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033553
Matt Menke9fa17d52019-03-25 19:12:263554 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3555 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3556 TestGroupId("a")));
3557 EXPECT_EQ(0u,
3558 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393559 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033560
robpercival214763f2016-07-01 23:27:013561 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3562 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033563 handle1.Reset();
3564 handle2.Reset();
3565
Matt Menke9fa17d52019-03-25 19:12:263566 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3567 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3568 TestGroupId("a")));
3569 EXPECT_EQ(0u,
3570 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393571 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033572}
3573
3574TEST_F(ClientSocketPoolBaseTest, RequestSocketsWhenAlreadyHaveAConnectJob) {
3575 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3576 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3577
3578 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523579 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203580 EXPECT_EQ(
3581 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283582 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3583 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503584 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3585 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033586
Matt Menke9fa17d52019-03-25 19:12:263587 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3588 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3589 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3590 TestGroupId("a")));
3591 EXPECT_EQ(0u,
3592 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393593 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033594
Matt Menkef09e64c2019-04-23 22:16:283595 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
3596 NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033597
Matt Menke9fa17d52019-03-25 19:12:263598 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3599 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3600 TestGroupId("a")));
3601 EXPECT_EQ(1u,
3602 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393603 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033604
3605 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523606 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203607 EXPECT_EQ(
3608 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283609 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3610 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503611 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3612 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033613
Matt Menke9fa17d52019-03-25 19:12:263614 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3615 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3616 TestGroupId("a")));
3617 EXPECT_EQ(0u,
3618 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393619 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033620
robpercival214763f2016-07-01 23:27:013621 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3622 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033623 handle1.Reset();
3624 handle2.Reset();
3625
Matt Menke9fa17d52019-03-25 19:12:263626 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3627 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3628 TestGroupId("a")));
3629 EXPECT_EQ(0u,
3630 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393631 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033632}
3633
3634TEST_F(ClientSocketPoolBaseTest,
3635 RequestSocketsWhenAlreadyHaveMultipleConnectJob) {
3636 CreatePool(4, 4);
3637 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3638
3639 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523640 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203641 EXPECT_EQ(
3642 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283643 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3644 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503645 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3646 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033647
3648 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523649 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203650 EXPECT_EQ(
3651 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283652 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3653 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503654 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3655 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033656
3657 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:523658 TestCompletionCallback callback3;
tfarina428341112016-09-22 13:38:203659 EXPECT_EQ(
3660 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283661 handle3.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3662 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503663 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
3664 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033665
Matt Menke9fa17d52019-03-25 19:12:263666 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3667 EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3668 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3669 TestGroupId("a")));
3670 EXPECT_EQ(0u,
3671 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393672 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033673
Matt Menkef09e64c2019-04-23 22:16:283674 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
3675 NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033676
Matt Menke9fa17d52019-03-25 19:12:263677 EXPECT_EQ(3u, 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(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033683
robpercival214763f2016-07-01 23:27:013684 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3685 EXPECT_THAT(callback2.WaitForResult(), IsOk());
3686 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033687 handle1.Reset();
3688 handle2.Reset();
3689 handle3.Reset();
3690
Matt Menke9fa17d52019-03-25 19:12:263691 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3692 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3693 TestGroupId("a")));
3694 EXPECT_EQ(0u,
3695 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393696 EXPECT_EQ(3u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033697}
3698
3699TEST_F(ClientSocketPoolBaseTest, RequestSocketsAtMaxSocketLimit) {
3700 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3701 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3702
Matt Menke9fa17d52019-03-25 19:12:263703 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033704
Matt Menkef09e64c2019-04-23 22:16:283705 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt,
3706 kDefaultMaxSockets, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033707
Matt Menke9fa17d52019-03-25 19:12:263708 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
Raul Tambre8335a6d2019-02-21 16:57:433709 EXPECT_EQ(kDefaultMaxSockets,
Matt Menkec6b3edf72019-03-19 17:00:393710 static_cast<int>(
Matt Menke9fa17d52019-03-25 19:12:263711 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))));
3712 EXPECT_EQ(
3713 kDefaultMaxSockets,
3714 static_cast<int>(pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3715 TestGroupId("a"))));
Raul Tambre8335a6d2019-02-21 16:57:433716 EXPECT_EQ(kDefaultMaxSockets,
Matt Menke9fa17d52019-03-25 19:12:263717 static_cast<int>(pool_->NumUnassignedConnectJobsInGroupForTesting(
3718 TestGroupId("a"))));
[email protected]2c2bef152010-10-13 00:55:033719
Matt Menke9fa17d52019-03-25 19:12:263720 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("b")));
[email protected]2c2bef152010-10-13 00:55:033721
Matt Menkef09e64c2019-04-23 22:16:283722 pool_->RequestSockets(TestGroupId("b"), params_, base::nullopt,
3723 kDefaultMaxSockets, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033724
Matt Menke9fa17d52019-03-25 19:12:263725 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("b")));
[email protected]2c2bef152010-10-13 00:55:033726}
3727
3728TEST_F(ClientSocketPoolBaseTest, RequestSocketsHitMaxSocketLimit) {
3729 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3730 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3731
Matt Menke9fa17d52019-03-25 19:12:263732 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033733
Matt Menkef09e64c2019-04-23 22:16:283734 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt,
3735 kDefaultMaxSockets - 1, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033736
Matt Menke9fa17d52019-03-25 19:12:263737 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:433738 EXPECT_EQ(kDefaultMaxSockets - 1,
Matt Menkec6b3edf72019-03-19 17:00:393739 static_cast<int>(
Matt Menke9fa17d52019-03-25 19:12:263740 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))));
3741 EXPECT_EQ(
3742 kDefaultMaxSockets - 1,
3743 static_cast<int>(pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3744 TestGroupId("a"))));
Raul Tambre8335a6d2019-02-21 16:57:433745 EXPECT_EQ(kDefaultMaxSockets - 1,
Matt Menke9fa17d52019-03-25 19:12:263746 static_cast<int>(pool_->NumUnassignedConnectJobsInGroupForTesting(
3747 TestGroupId("a"))));
[email protected]51fdc7c2012-04-10 19:19:483748 EXPECT_FALSE(pool_->IsStalled());
[email protected]2c2bef152010-10-13 00:55:033749
Matt Menke9fa17d52019-03-25 19:12:263750 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("b")));
[email protected]2c2bef152010-10-13 00:55:033751
Matt Menkef09e64c2019-04-23 22:16:283752 pool_->RequestSockets(TestGroupId("b"), params_, base::nullopt,
3753 kDefaultMaxSockets, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033754
Matt Menke9fa17d52019-03-25 19:12:263755 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("b")));
3756 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
[email protected]51fdc7c2012-04-10 19:19:483757 EXPECT_FALSE(pool_->IsStalled());
[email protected]2c2bef152010-10-13 00:55:033758}
3759
3760TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) {
3761 CreatePool(4, 4);
3762 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3763
3764 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523765 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203766 EXPECT_EQ(
3767 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283768 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3769 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503770 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3771 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013772 ASSERT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033773 handle1.Reset();
3774
Matt Menke9fa17d52019-03-25 19:12:263775 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3776 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3777 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3778 TestGroupId("a")));
3779 EXPECT_EQ(0u,
3780 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393781 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033782
Matt Menkef09e64c2019-04-23 22:16:283783 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
3784 NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033785
Matt Menke9fa17d52019-03-25 19:12:263786 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3787 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3788 TestGroupId("a")));
3789 EXPECT_EQ(1u,
3790 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393791 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033792}
3793
3794TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountActiveSockets) {
3795 CreatePool(4, 4);
3796 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3797
3798 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523799 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203800 EXPECT_EQ(
3801 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283802 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3803 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503804 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3805 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013806 ASSERT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033807
Matt Menke9fa17d52019-03-25 19:12:263808 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3809 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3810 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3811 TestGroupId("a")));
3812 EXPECT_EQ(0u,
3813 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393814 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menke9fa17d52019-03-25 19:12:263815 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033816
Matt Menkef09e64c2019-04-23 22:16:283817 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
3818 NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033819
Matt Menke9fa17d52019-03-25 19:12:263820 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3821 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3822 TestGroupId("a")));
3823 EXPECT_EQ(1u,
3824 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393825 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menke9fa17d52019-03-25 19:12:263826 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033827}
3828
3829TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronous) {
3830 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3831 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3832
Matt Menkef09e64c2019-04-23 22:16:283833 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt,
3834 kDefaultMaxSocketsPerGroup, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033835
Matt Menke9fa17d52019-03-25 19:12:263836 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3837 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3838 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3839 TestGroupId("a")));
3840 EXPECT_EQ(0u,
3841 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Raul Tambre8335a6d2019-02-21 16:57:433842 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
Matt Menkec6b3edf72019-03-19 17:00:393843 static_cast<int>(pool_->IdleSocketCountInGroup(TestGroupId("a"))));
[email protected]2c2bef152010-10-13 00:55:033844
Matt Menkef09e64c2019-04-23 22:16:283845 pool_->RequestSockets(TestGroupId("b"), params_, base::nullopt,
3846 kDefaultMaxSocketsPerGroup, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033847
Matt Menke9fa17d52019-03-25 19:12:263848 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
3849 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3850 TestGroupId("b")));
3851 EXPECT_EQ(0u,
3852 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("b")));
Raul Tambre8335a6d2019-02-21 16:57:433853 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
Matt Menkec6b3edf72019-03-19 17:00:393854 static_cast<int>(pool_->IdleSocketCountInGroup(TestGroupId("b"))));
[email protected]2c2bef152010-10-13 00:55:033855}
3856
[email protected]3c819f522010-12-02 02:03:123857TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronousError) {
3858 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3859 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3860
Matt Menkef09e64c2019-04-23 22:16:283861 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt,
3862 kDefaultMaxSocketsPerGroup, NetLogWithSource());
[email protected]3c819f522010-12-02 02:03:123863
Matt Menke9fa17d52019-03-25 19:12:263864 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
[email protected]fd2e53e2011-01-14 20:40:523865
3866 connect_job_factory_->set_job_type(
3867 TestConnectJob::kMockAdditionalErrorStateJob);
Matt Menkef09e64c2019-04-23 22:16:283868 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt,
3869 kDefaultMaxSocketsPerGroup, NetLogWithSource());
[email protected]fd2e53e2011-01-14 20:40:523870
Matt Menke9fa17d52019-03-25 19:12:263871 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
[email protected]3c819f522010-12-02 02:03:123872}
3873
[email protected]8159a1c2012-06-07 00:00:103874TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) {
[email protected]2c2bef152010-10-13 00:55:033875 CreatePool(4, 4);
Lily Chenecebf932018-11-02 17:15:433876 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
[email protected]2c2bef152010-10-13 00:55:033877
Matt Menkef09e64c2019-04-23 22:16:283878 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
3879 NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033880
Matt Menke9fa17d52019-03-25 19:12:263881 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3882 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3883 EXPECT_EQ(2u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3884 TestGroupId("a")));
3885 EXPECT_EQ(2u,
3886 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3887 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393888 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033889
Matt Menkef09e64c2019-04-23 22:16:283890 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
3891 NetLogWithSource());
Matt Menke9fa17d52019-03-25 19:12:263892 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3893 EXPECT_EQ(2u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3894 TestGroupId("a")));
3895 EXPECT_EQ(2u,
3896 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3897 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393898 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033899
3900 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523901 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203902 EXPECT_EQ(
3903 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283904 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3905 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503906 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3907 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:433908
3909 client_socket_factory_.SignalJob(0);
3910 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3911
Matt Menke9fa17d52019-03-25 19:12:263912 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3913 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3914 TestGroupId("a")));
3915 EXPECT_EQ(1u,
3916 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3917 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(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 handle2;
[email protected]6ecf2b92011-12-15 01:14:523921 TestCompletionCallback callback2;
Lily Chenecebf932018-11-02 17:15:433922 EXPECT_EQ(
3923 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283924 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3925 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503926 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3927 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:433928 client_socket_factory_.SignalJob(0);
3929 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033930
Matt Menke9fa17d52019-03-25 19:12:263931 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3932 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3933 TestGroupId("a")));
3934 EXPECT_EQ(0u,
3935 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3936 EXPECT_EQ(2, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393937 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]8159a1c2012-06-07 00:00:103938
[email protected]2c2bef152010-10-13 00:55:033939 handle1.Reset();
3940 handle2.Reset();
3941
Matt Menke9fa17d52019-03-25 19:12:263942 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3943 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3944 TestGroupId("a")));
3945 EXPECT_EQ(0u,
3946 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3947 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393948 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033949
Matt Menkef09e64c2019-04-23 22:16:283950 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
3951 NetLogWithSource());
Matt Menke9fa17d52019-03-25 19:12:263952 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3953 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3954 TestGroupId("a")));
3955 EXPECT_EQ(0u,
3956 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3957 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393958 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033959}
3960
3961TEST_F(ClientSocketPoolBaseTest, RequestSocketsDifferentNumSockets) {
3962 CreatePool(4, 4);
3963 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3964
Matt Menkef09e64c2019-04-23 22:16:283965 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 1,
3966 NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033967
Matt Menke9fa17d52019-03-25 19:12:263968 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3969 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3970 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3971 TestGroupId("a")));
3972 EXPECT_EQ(1u,
3973 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393974 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033975
Matt Menkef09e64c2019-04-23 22:16:283976 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
3977 NetLogWithSource());
Matt Menke9fa17d52019-03-25 19:12:263978 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3979 EXPECT_EQ(2u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3980 TestGroupId("a")));
3981 EXPECT_EQ(2u,
3982 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393983 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033984
Matt Menkef09e64c2019-04-23 22:16:283985 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 3,
3986 NetLogWithSource());
Matt Menke9fa17d52019-03-25 19:12:263987 EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3988 EXPECT_EQ(3u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3989 TestGroupId("a")));
3990 EXPECT_EQ(3u,
3991 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393992 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033993
Matt Menkef09e64c2019-04-23 22:16:283994 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 1,
3995 NetLogWithSource());
Matt Menke9fa17d52019-03-25 19:12:263996 EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3997 EXPECT_EQ(3u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3998 TestGroupId("a")));
3999 EXPECT_EQ(3u,
4000 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394001 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:034002}
4003
4004TEST_F(ClientSocketPoolBaseTest, PreconnectJobsTakenByNormalRequests) {
4005 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
Lily Chenecebf932018-11-02 17:15:434006 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
[email protected]2c2bef152010-10-13 00:55:034007
Matt Menkef09e64c2019-04-23 22:16:284008 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 1,
4009 NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:034010
Matt Menke9fa17d52019-03-25 19:12:264011 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
4012 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4013 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4014 TestGroupId("a")));
4015 EXPECT_EQ(1u,
4016 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394017 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:034018
4019 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:524020 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:204021 EXPECT_EQ(
4022 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284023 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4024 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504025 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4026 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:034027
Matt Menke9fa17d52019-03-25 19:12:264028 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4029 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4030 TestGroupId("a")));
4031 EXPECT_EQ(0u,
4032 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394033 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:034034
Lily Chenecebf932018-11-02 17:15:434035 client_socket_factory_.SignalJobs();
4036 EXPECT_THAT(callback1.WaitForResult(), IsOk());
4037
Matt Menke9fa17d52019-03-25 19:12:264038 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4039 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4040 TestGroupId("a")));
4041 EXPECT_EQ(0u,
4042 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394043 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menke9fa17d52019-03-25 19:12:264044 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:034045
[email protected]0dc88b32014-03-26 20:12:284046 // Make sure if a preconnected socket is not fully connected when a request
[email protected]034df0f32013-01-07 23:17:484047 // starts, it has a connect start time.
4048 TestLoadTimingInfoConnectedNotReused(handle1);
[email protected]2c2bef152010-10-13 00:55:034049 handle1.Reset();
4050
Matt Menkec6b3edf72019-03-19 17:00:394051 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:034052}
4053
[email protected]034df0f32013-01-07 23:17:484054// Checks that fully connected preconnect jobs have no connect times, and are
4055// marked as reused.
4056TEST_F(ClientSocketPoolBaseTest, ConnectedPreconnectJobsHaveNoConnectTimes) {
4057 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4058 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
Matt Menkef09e64c2019-04-23 22:16:284059 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 1,
4060 NetLogWithSource());
[email protected]034df0f32013-01-07 23:17:484061
Matt Menke9fa17d52019-03-25 19:12:264062 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
4063 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4064 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4065 TestGroupId("a")));
4066 EXPECT_EQ(0u,
4067 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394068 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]034df0f32013-01-07 23:17:484069
4070 ClientSocketHandle handle;
4071 TestCompletionCallback callback;
Matt Menkec6b3edf72019-03-19 17:00:394072 EXPECT_EQ(OK, handle.Init(
Matt Menkef09e64c2019-04-23 22:16:284073 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4074 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menkec6b3edf72019-03-19 17:00:394075 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
4076 pool_.get(), NetLogWithSource()));
[email protected]034df0f32013-01-07 23:17:484077
4078 // Make sure the idle socket was used.
Matt Menkec6b3edf72019-03-19 17:00:394079 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]034df0f32013-01-07 23:17:484080
4081 TestLoadTimingInfoConnectedReused(handle);
4082 handle.Reset();
4083 TestLoadTimingInfoNotConnected(handle);
4084}
4085
[email protected]dcbe168a2010-12-02 03:14:464086// http://crbug.com/64940 regression test.
4087TEST_F(ClientSocketPoolBaseTest, PreconnectClosesIdleSocketRemovesGroup) {
4088 const int kMaxTotalSockets = 3;
4089 const int kMaxSocketsPerGroup = 2;
4090 CreatePool(kMaxTotalSockets, kMaxSocketsPerGroup);
Lily Chenecebf932018-11-02 17:15:434091 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
[email protected]dcbe168a2010-12-02 03:14:464092
Matt Menkef6edce752019-03-19 17:21:564093 // Note that group id ordering matters here. "a" comes before "b", so
[email protected]dcbe168a2010-12-02 03:14:464094 // CloseOneIdleSocket() will try to close "a"'s idle socket.
4095
4096 // Set up one idle socket in "a".
4097 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:524098 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:204099 EXPECT_EQ(
4100 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284101 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4102 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504103 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4104 pool_.get(), NetLogWithSource()));
Matt Menke9fa17d52019-03-25 19:12:264105 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
4106 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4107 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4108 TestGroupId("a")));
4109 EXPECT_EQ(0u,
4110 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394111 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]dcbe168a2010-12-02 03:14:464112
Lily Chenecebf932018-11-02 17:15:434113 client_socket_factory_.SignalJobs();
robpercival214763f2016-07-01 23:27:014114 ASSERT_THAT(callback1.WaitForResult(), IsOk());
Matt Menke9fa17d52019-03-25 19:12:264115 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4116 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4117 TestGroupId("a")));
4118 EXPECT_EQ(0u,
4119 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4120 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434121
[email protected]dcbe168a2010-12-02 03:14:464122 handle1.Reset();
Matt Menkec6b3edf72019-03-19 17:00:394123 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]dcbe168a2010-12-02 03:14:464124
4125 // Set up two active sockets in "b".
4126 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:524127 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:204128 EXPECT_EQ(
4129 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284130 handle1.Init(TestGroupId("b"), params_, base::nullopt, DEFAULT_PRIORITY,
4131 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504132 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4133 pool_.get(), NetLogWithSource()));
tfarina428341112016-09-22 13:38:204134 EXPECT_EQ(
4135 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284136 handle2.Init(TestGroupId("b"), params_, base::nullopt, DEFAULT_PRIORITY,
4137 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504138 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4139 pool_.get(), NetLogWithSource()));
[email protected]dcbe168a2010-12-02 03:14:464140
Matt Menke9fa17d52019-03-25 19:12:264141 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("b")));
4142 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
4143 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4144 TestGroupId("b")));
4145 EXPECT_EQ(0u,
4146 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("b")));
Matt Menkec6b3edf72019-03-19 17:00:394147 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("b")));
Lily Chenecebf932018-11-02 17:15:434148
4149 client_socket_factory_.SignalJobs();
robpercival214763f2016-07-01 23:27:014150 ASSERT_THAT(callback1.WaitForResult(), IsOk());
4151 ASSERT_THAT(callback2.WaitForResult(), IsOk());
Matt Menkec6b3edf72019-03-19 17:00:394152 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("b")));
Matt Menke9fa17d52019-03-25 19:12:264153 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4154 TestGroupId("b")));
4155 EXPECT_EQ(0u,
4156 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("b")));
4157 EXPECT_EQ(2, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("b")));
[email protected]dcbe168a2010-12-02 03:14:464158
4159 // Now we have 1 idle socket in "a" and 2 active sockets in "b". This means
4160 // we've maxed out on sockets, since we set |kMaxTotalSockets| to 3.
4161 // Requesting 2 preconnected sockets for "a" should fail to allocate any more
4162 // sockets for "a", and "b" should still have 2 active sockets.
4163
Matt Menkef09e64c2019-04-23 22:16:284164 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
4165 NetLogWithSource());
Matt Menke9fa17d52019-03-25 19:12:264166 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4167 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4168 TestGroupId("a")));
4169 EXPECT_EQ(0u,
4170 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394171 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menke9fa17d52019-03-25 19:12:264172 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
4173 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
4174 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4175 TestGroupId("b")));
4176 EXPECT_EQ(0u,
4177 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("b")));
Matt Menkec6b3edf72019-03-19 17:00:394178 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("b")));
Matt Menke9fa17d52019-03-25 19:12:264179 EXPECT_EQ(2, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("b")));
[email protected]dcbe168a2010-12-02 03:14:464180
4181 // Now release the 2 active sockets for "b". This will give us 1 idle socket
4182 // in "a" and 2 idle sockets in "b". Requesting 2 preconnected sockets for
4183 // "a" should result in closing 1 for "b".
4184 handle1.Reset();
4185 handle2.Reset();
Matt Menkec6b3edf72019-03-19 17:00:394186 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(TestGroupId("b")));
Matt Menke9fa17d52019-03-25 19:12:264187 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("b")));
[email protected]dcbe168a2010-12-02 03:14:464188
Matt Menkef09e64c2019-04-23 22:16:284189 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
4190 NetLogWithSource());
Matt Menke9fa17d52019-03-25 19:12:264191 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4192 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4193 TestGroupId("a")));
4194 EXPECT_EQ(1u,
4195 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394196 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menke9fa17d52019-03-25 19:12:264197 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
4198 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
4199 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4200 TestGroupId("b")));
4201 EXPECT_EQ(0u,
4202 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("b")));
Matt Menkec6b3edf72019-03-19 17:00:394203 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("b")));
Matt Menke9fa17d52019-03-25 19:12:264204 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("b")));
[email protected]dcbe168a2010-12-02 03:14:464205}
4206
[email protected]b7b8be42011-07-12 12:46:414207TEST_F(ClientSocketPoolBaseTest, PreconnectWithoutBackupJob) {
Matt Menke9fa17d52019-03-25 19:12:264208 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
4209 true /* enable_backup_connect_jobs */);
[email protected]a9fc8fc2011-05-10 02:41:074210
4211 // Make the ConnectJob hang until it times out, shorten the timeout.
4212 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4213 connect_job_factory_->set_timeout_duration(
4214 base::TimeDelta::FromMilliseconds(500));
Matt Menkef09e64c2019-04-23 22:16:284215 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 1,
4216 NetLogWithSource());
Matt Menke9fa17d52019-03-25 19:12:264217 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4218 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4219 TestGroupId("a")));
4220 EXPECT_EQ(1u,
4221 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394222 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]a9fc8fc2011-05-10 02:41:074223
[email protected]b7b8be42011-07-12 12:46:414224 // Verify the backup timer doesn't create a backup job, by making
4225 // the backup job a pending job instead of a waiting job, so it
4226 // *would* complete if it were created.
Lukasz Krakowiak28dcf9d62020-06-04 09:46:594227 base::RunLoop loop;
[email protected]a9fc8fc2011-05-10 02:41:074228 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
skyostil4891b25b2015-06-11 11:43:454229 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
Lukasz Krakowiak28dcf9d62020-06-04 09:46:594230 FROM_HERE, loop.QuitWhenIdleClosure(), base::TimeDelta::FromSeconds(1));
4231 loop.Run();
Matt Menke9fa17d52019-03-25 19:12:264232 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
[email protected]a9fc8fc2011-05-10 02:41:074233}
4234
[email protected]b7b8be42011-07-12 12:46:414235TEST_F(ClientSocketPoolBaseTest, PreconnectWithBackupJob) {
Matt Menke9fa17d52019-03-25 19:12:264236 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
4237 true /* enable_backup_connect_jobs */);
[email protected]a9fc8fc2011-05-10 02:41:074238
4239 // Make the ConnectJob hang forever.
4240 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
Matt Menkef09e64c2019-04-23 22:16:284241 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 1,
4242 NetLogWithSource());
Matt Menke9fa17d52019-03-25 19:12:264243 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4244 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4245 TestGroupId("a")));
4246 EXPECT_EQ(1u,
4247 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394248 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
fdoray5eeb7642016-06-22 16:11:284249 base::RunLoop().RunUntilIdle();
[email protected]a9fc8fc2011-05-10 02:41:074250
4251 // Make the backup job be a pending job, so it completes normally.
4252 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
4253 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:524254 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:504255 EXPECT_EQ(
4256 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284257 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4258 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4259 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
4260 pool_.get(), NetLogWithSource()));
[email protected]b7b8be42011-07-12 12:46:414261 // Timer has started, but the backup connect job shouldn't be created yet.
Matt Menke9fa17d52019-03-25 19:12:264262 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4263 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4264 TestGroupId("a")));
4265 EXPECT_EQ(0u,
4266 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394267 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menke9fa17d52019-03-25 19:12:264268 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
robpercival214763f2016-07-01 23:27:014269 ASSERT_THAT(callback.WaitForResult(), IsOk());
[email protected]a9fc8fc2011-05-10 02:41:074270
4271 // The hung connect job should still be there, but everything else should be
4272 // complete.
Matt Menke9fa17d52019-03-25 19:12:264273 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4274 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4275 TestGroupId("a")));
4276 EXPECT_EQ(1u,
4277 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394278 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menke9fa17d52019-03-25 19:12:264279 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
[email protected]a9fc8fc2011-05-10 02:41:074280}
4281
[email protected]0dc88b32014-03-26 20:12:284282// Tests that a preconnect that starts out with unread data can still be used.
4283// http://crbug.com/334467
4284TEST_F(ClientSocketPoolBaseTest, PreconnectWithUnreadData) {
4285 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4286 connect_job_factory_->set_job_type(TestConnectJob::kMockUnreadDataJob);
4287
Matt Menkef09e64c2019-04-23 22:16:284288 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 1,
4289 NetLogWithSource());
[email protected]0dc88b32014-03-26 20:12:284290
Matt Menke9fa17d52019-03-25 19:12:264291 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
4292 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4293 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4294 TestGroupId("a")));
4295 EXPECT_EQ(0u,
4296 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394297 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]0dc88b32014-03-26 20:12:284298
4299 // Fail future jobs to be sure that handle receives the preconnected socket
4300 // rather than closing it and making a new one.
4301 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
4302 ClientSocketHandle handle;
4303 TestCompletionCallback callback;
Matt Menkec6b3edf72019-03-19 17:00:394304 EXPECT_EQ(OK, handle.Init(
Matt Menkef09e64c2019-04-23 22:16:284305 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4306 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menkec6b3edf72019-03-19 17:00:394307 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
4308 pool_.get(), NetLogWithSource()));
[email protected]0dc88b32014-03-26 20:12:284309
Matt Menke9fa17d52019-03-25 19:12:264310 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
4311 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4312 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4313 TestGroupId("a")));
4314 EXPECT_EQ(0u,
4315 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394316 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menke9fa17d52019-03-25 19:12:264317 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
[email protected]0dc88b32014-03-26 20:12:284318
4319 // Drain the pending read.
Raul Tambre94493c652019-03-11 17:18:354320 EXPECT_EQ(1, handle.socket()->Read(nullptr, 1, CompletionOnceCallback()));
[email protected]0dc88b32014-03-26 20:12:284321
4322 TestLoadTimingInfoConnectedReused(handle);
4323 handle.Reset();
4324
4325 // The socket should be usable now that it's idle again.
Matt Menkec6b3edf72019-03-19 17:00:394326 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]0dc88b32014-03-26 20:12:284327}
4328
Lily Chenecebf932018-11-02 17:15:434329TEST_F(ClientSocketPoolBaseTest, RequestGetsAssignedJob) {
4330 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4331 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4332
4333 ClientSocketHandle handle1;
4334 TestCompletionCallback callback1;
4335 EXPECT_EQ(
4336 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284337 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4338 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504339 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4340 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434341
Matt Menke9fa17d52019-03-25 19:12:264342 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4343 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4344 TestGroupId("a")));
4345 EXPECT_EQ(0u,
4346 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394347 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434348
Matt Menkec6b3edf72019-03-19 17:00:394349 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4350 &handle1));
Lily Chenecebf932018-11-02 17:15:434351}
4352
4353TEST_F(ClientSocketPoolBaseTest, MultipleRequestsGetAssignedJobs) {
4354 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4355 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4356
4357 ClientSocketHandle handle1;
4358 TestCompletionCallback callback1;
4359 EXPECT_EQ(
4360 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284361 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4362 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504363 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4364 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434365
Matt Menke9fa17d52019-03-25 19:12:264366 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4367 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4368 TestGroupId("a")));
4369 EXPECT_EQ(0u,
4370 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394371 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434372
4373 ClientSocketHandle handle2;
4374 TestCompletionCallback callback2;
4375 EXPECT_EQ(
4376 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284377 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4378 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504379 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4380 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434381
Matt Menke9fa17d52019-03-25 19:12:264382 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4383 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4384 TestGroupId("a")));
4385 EXPECT_EQ(0u,
4386 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394387 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434388
Matt Menkec6b3edf72019-03-19 17:00:394389 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4390 &handle1));
4391 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4392 &handle2));
Lily Chenecebf932018-11-02 17:15:434393
4394 // One job completes. The other request should still have its job.
4395 client_socket_factory_.SignalJob(0);
4396 EXPECT_THAT(callback1.WaitForResult(), IsOk());
4397
Matt Menke9fa17d52019-03-25 19:12:264398 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4399 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4400 TestGroupId("a")));
4401 EXPECT_EQ(0u,
4402 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4403 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394404 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434405
Matt Menkec6b3edf72019-03-19 17:00:394406 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4407 &handle2));
Lily Chenecebf932018-11-02 17:15:434408}
4409
4410TEST_F(ClientSocketPoolBaseTest, PreconnectJobGetsAssignedToRequest) {
4411 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4412 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4413
Matt Menkef09e64c2019-04-23 22:16:284414 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 1,
4415 NetLogWithSource());
Lily Chenecebf932018-11-02 17:15:434416
Matt Menke9fa17d52019-03-25 19:12:264417 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
4418 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4419 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4420 TestGroupId("a")));
4421 EXPECT_EQ(1u,
4422 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394423 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434424
4425 ClientSocketHandle handle1;
4426 TestCompletionCallback callback1;
4427 EXPECT_EQ(
4428 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284429 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4430 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504431 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4432 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434433
Matt Menke9fa17d52019-03-25 19:12:264434 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4435 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4436 TestGroupId("a")));
4437 EXPECT_EQ(0u,
4438 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394439 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434440
Matt Menkec6b3edf72019-03-19 17:00:394441 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4442 &handle1));
Lily Chenecebf932018-11-02 17:15:434443}
4444
4445TEST_F(ClientSocketPoolBaseTest, HigherPriorityRequestStealsJob) {
4446 CreatePool(kDefaultMaxSockets, 1);
4447 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4448
4449 ClientSocketHandle handle1;
4450 TestCompletionCallback callback1;
4451 EXPECT_EQ(
4452 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284453 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4454 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504455 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4456 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434457
Matt Menke9fa17d52019-03-25 19:12:264458 EXPECT_EQ(1u, 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
Matt Menkec6b3edf72019-03-19 17:00:394465 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4466 &handle1));
Lily Chenecebf932018-11-02 17:15:434467
4468 // Insert a higher priority request
4469 ClientSocketHandle handle2;
4470 TestCompletionCallback callback2;
4471 EXPECT_EQ(
4472 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284473 handle2.Init(TestGroupId("a"), params_, base::nullopt, HIGHEST,
4474 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504475 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4476 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434477
Matt Menke9fa17d52019-03-25 19:12:264478 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4479 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4480 TestGroupId("a")));
4481 EXPECT_EQ(0u,
4482 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394483 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434484
4485 // The highest priority request should steal the job from the default priority
4486 // request.
Matt Menkec6b3edf72019-03-19 17:00:394487 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4488 &handle2));
4489 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4490 &handle1));
Lily Chenecebf932018-11-02 17:15:434491}
4492
4493TEST_F(ClientSocketPoolBaseTest, RequestStealsJobFromLowestRequestWithJob) {
4494 CreatePool(3, 3);
4495 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4496
4497 ClientSocketHandle handle_lowest;
4498 TestCompletionCallback callback_lowest;
Matt Menkef09e64c2019-04-23 22:16:284499 EXPECT_EQ(
4500 ERR_IO_PENDING,
4501 handle_lowest.Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
4502 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4503 callback_lowest.callback(),
4504 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4505 NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434506
Matt Menke9fa17d52019-03-25 19:12:264507 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4508 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4509 TestGroupId("a")));
4510 EXPECT_EQ(0u,
4511 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394512 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434513
4514 ClientSocketHandle handle_highest;
4515 TestCompletionCallback callback_highest;
Matt Menkef09e64c2019-04-23 22:16:284516 EXPECT_EQ(
4517 ERR_IO_PENDING,
4518 handle_highest.Init(TestGroupId("a"), params_, base::nullopt, HIGHEST,
4519 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4520 callback_highest.callback(),
4521 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4522 NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434523
Matt Menke9fa17d52019-03-25 19:12:264524 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4525 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4526 TestGroupId("a")));
4527 EXPECT_EQ(0u,
4528 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394529 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434530
4531 ClientSocketHandle handle_low;
4532 TestCompletionCallback callback_low;
4533 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284534 handle_low.Init(
4535 TestGroupId("a"), params_, base::nullopt, LOW, SocketTag(),
4536 ClientSocketPool::RespectLimits::ENABLED,
4537 callback_low.callback(), ClientSocketPool::ProxyAuthCallback(),
4538 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434539
Matt Menke9fa17d52019-03-25 19:12:264540 EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4541 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4542 TestGroupId("a")));
4543 EXPECT_EQ(0u,
4544 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394545 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434546
4547 ClientSocketHandle handle_lowest2;
4548 TestCompletionCallback callback_lowest2;
Matt Menkef09e64c2019-04-23 22:16:284549 EXPECT_EQ(
4550 ERR_IO_PENDING,
4551 handle_lowest2.Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
4552 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4553 callback_lowest2.callback(),
4554 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4555 NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434556
Matt Menke9fa17d52019-03-25 19:12:264557 EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4558 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4559 TestGroupId("a")));
4560 EXPECT_EQ(0u,
4561 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394562 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434563
4564 // The top three requests in the queue should have jobs.
Matt Menkec6b3edf72019-03-19 17:00:394565 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4566 &handle_highest));
4567 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4568 &handle_low));
4569 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4570 &handle_lowest));
4571 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(
4572 TestGroupId("a"), &handle_lowest2));
Lily Chenecebf932018-11-02 17:15:434573
4574 // Add another request with medium priority. It should steal the job from the
4575 // lowest priority request with a job.
4576 ClientSocketHandle handle_medium;
4577 TestCompletionCallback callback_medium;
Matt Menkef09e64c2019-04-23 22:16:284578 EXPECT_EQ(
4579 ERR_IO_PENDING,
4580 handle_medium.Init(TestGroupId("a"), params_, base::nullopt, MEDIUM,
4581 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4582 callback_medium.callback(),
4583 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4584 NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434585
Matt Menke9fa17d52019-03-25 19:12:264586 EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4587 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4588 TestGroupId("a")));
4589 EXPECT_EQ(0u,
4590 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394591 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4592 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4593 &handle_highest));
4594 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4595 &handle_medium));
4596 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4597 &handle_low));
4598 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4599 &handle_lowest));
4600 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(
4601 TestGroupId("a"), &handle_lowest2));
Lily Chenecebf932018-11-02 17:15:434602}
4603
4604TEST_F(ClientSocketPoolBaseTest, ReprioritizeRequestStealsJob) {
4605 CreatePool(kDefaultMaxSockets, 1);
4606 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4607
4608 ClientSocketHandle handle1;
4609 TestCompletionCallback callback1;
4610 EXPECT_EQ(
4611 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284612 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4613 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504614 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4615 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434616
Matt Menke9fa17d52019-03-25 19:12:264617 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4618 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4619 TestGroupId("a")));
4620 EXPECT_EQ(0u,
4621 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394622 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434623
4624 ClientSocketHandle handle2;
4625 TestCompletionCallback callback2;
4626 EXPECT_EQ(
4627 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284628 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4629 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504630 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4631 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434632
Matt Menke9fa17d52019-03-25 19:12:264633 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4634 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4635 TestGroupId("a")));
4636 EXPECT_EQ(0u,
4637 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394638 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434639
4640 // The second request doesn't get a job because we are at the limit.
Matt Menkec6b3edf72019-03-19 17:00:394641 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4642 &handle1));
4643 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4644 &handle2));
Lily Chenecebf932018-11-02 17:15:434645
4646 // Reprioritizing the second request places it above the first, and it steals
4647 // the job from the first request.
Matt Menkec6b3edf72019-03-19 17:00:394648 pool_->SetPriority(TestGroupId("a"), &handle2, HIGHEST);
4649 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4650 &handle2));
4651 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4652 &handle1));
Lily Chenecebf932018-11-02 17:15:434653}
4654
4655TEST_F(ClientSocketPoolBaseTest, CancelRequestReassignsJob) {
4656 CreatePool(kDefaultMaxSockets, 1);
4657 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4658
4659 ClientSocketHandle handle1;
4660 TestCompletionCallback callback1;
4661 EXPECT_EQ(
4662 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284663 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4664 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504665 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4666 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434667
Matt Menke9fa17d52019-03-25 19:12:264668 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4669 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4670 TestGroupId("a")));
4671 EXPECT_EQ(0u,
4672 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394673 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434674
Matt Menkec6b3edf72019-03-19 17:00:394675 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4676 &handle1));
Lily Chenecebf932018-11-02 17:15:434677
4678 ClientSocketHandle handle2;
4679 TestCompletionCallback callback2;
4680 EXPECT_EQ(
4681 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284682 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4683 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504684 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4685 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434686
Matt Menke9fa17d52019-03-25 19:12:264687 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4688 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4689 TestGroupId("a")));
4690 EXPECT_EQ(0u,
4691 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394692 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434693
4694 // The second request doesn't get a job because we are the limit.
Matt Menkec6b3edf72019-03-19 17:00:394695 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4696 &handle1));
4697 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4698 &handle2));
Lily Chenecebf932018-11-02 17:15:434699
4700 // The second request should get a job upon cancelling the first request.
4701 handle1.Reset();
Matt Menke9fa17d52019-03-25 19:12:264702 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4703 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4704 TestGroupId("a")));
4705 EXPECT_EQ(0u,
4706 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394707 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434708
Matt Menkec6b3edf72019-03-19 17:00:394709 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4710 &handle2));
Lily Chenecebf932018-11-02 17:15:434711}
4712
4713TEST_F(ClientSocketPoolBaseTest, JobCompletionReassignsJob) {
4714 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4715 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4716
4717 ClientSocketHandle handle1;
4718 TestCompletionCallback callback1;
4719 EXPECT_EQ(
4720 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284721 handle1.Init(TestGroupId("a"), params_, base::nullopt, HIGHEST,
4722 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504723 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4724 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434725
Matt Menke9fa17d52019-03-25 19:12:264726 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4727 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4728 TestGroupId("a")));
4729 EXPECT_EQ(0u,
4730 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394731 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434732
4733 ClientSocketHandle handle2;
4734 TestCompletionCallback callback2;
4735 EXPECT_EQ(
4736 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284737 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4738 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504739 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4740 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434741
Matt Menke9fa17d52019-03-25 19:12:264742 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4743 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4744 TestGroupId("a")));
4745 EXPECT_EQ(0u,
4746 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394747 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434748
Matt Menkec6b3edf72019-03-19 17:00:394749 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4750 &handle1));
4751 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4752 &handle2));
Lily Chenecebf932018-11-02 17:15:434753
4754 // The lower-priority job completes first. The higher-priority request should
4755 // get the socket, and the lower-priority request should get the remaining
4756 // job.
4757 client_socket_factory_.SignalJob(1);
4758 EXPECT_THAT(callback1.WaitForResult(), IsOk());
Matt Menke9fa17d52019-03-25 19:12:264759 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4760 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4761 TestGroupId("a")));
4762 EXPECT_EQ(0u,
4763 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4764 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394765 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434766 EXPECT_TRUE(handle1.socket());
Matt Menkec6b3edf72019-03-19 17:00:394767 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4768 &handle2));
Lily Chenecebf932018-11-02 17:15:434769}
4770
[email protected]043b68c82013-08-22 23:41:524771class MockLayeredPool : public HigherLayeredPool {
[email protected]58e562f2013-04-22 17:32:204772 public:
Matt Menke9fa17d52019-03-25 19:12:264773 MockLayeredPool(TransportClientSocketPool* pool,
Matt Menkec6b3edf72019-03-19 17:00:394774 const ClientSocketPool::GroupId& group_id)
4775 : pool_(pool), group_id_(group_id), can_release_connection_(true) {
[email protected]043b68c82013-08-22 23:41:524776 pool_->AddHigherLayeredPool(this);
[email protected]58e562f2013-04-22 17:32:204777 }
4778
Daniel Cheng4496d0822018-04-26 21:52:154779 ~MockLayeredPool() override { pool_->RemoveHigherLayeredPool(this); }
[email protected]58e562f2013-04-22 17:32:204780
Matt Menke9fa17d52019-03-25 19:12:264781 int RequestSocket(TransportClientSocketPool* pool) {
Matt Menke28ac03e2019-02-25 22:25:504782 return handle_.Init(
Matt Menke870e19ab2019-04-23 16:23:034783 group_id_, ClientSocketPool::SocketParams::CreateForHttpForTesting(),
Matt Menkef09e64c2019-04-23 22:16:284784 base::nullopt, DEFAULT_PRIORITY, SocketTag(),
4785 ClientSocketPool::RespectLimits::ENABLED, callback_.callback(),
4786 ClientSocketPool::ProxyAuthCallback(), pool, NetLogWithSource());
[email protected]58e562f2013-04-22 17:32:204787 }
4788
Matt Menke9fa17d52019-03-25 19:12:264789 int RequestSocketWithoutLimits(TransportClientSocketPool* pool) {
Matt Menke28ac03e2019-02-25 22:25:504790 return handle_.Init(
Matt Menke870e19ab2019-04-23 16:23:034791 group_id_, ClientSocketPool::SocketParams::CreateForHttpForTesting(),
Matt Menkef09e64c2019-04-23 22:16:284792 base::nullopt, MAXIMUM_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:504793 ClientSocketPool::RespectLimits::DISABLED, callback_.callback(),
4794 ClientSocketPool::ProxyAuthCallback(), pool, NetLogWithSource());
[email protected]58e562f2013-04-22 17:32:204795 }
4796
4797 bool ReleaseOneConnection() {
4798 if (!handle_.is_initialized() || !can_release_connection_) {
4799 return false;
4800 }
4801 handle_.socket()->Disconnect();
4802 handle_.Reset();
4803 return true;
4804 }
4805
4806 void set_can_release_connection(bool can_release_connection) {
4807 can_release_connection_ = can_release_connection;
4808 }
4809
4810 MOCK_METHOD0(CloseOneIdleConnection, bool());
4811
4812 private:
Matt Menke9fa17d52019-03-25 19:12:264813 TransportClientSocketPool* const pool_;
[email protected]58e562f2013-04-22 17:32:204814 ClientSocketHandle handle_;
4815 TestCompletionCallback callback_;
Matt Menkec6b3edf72019-03-19 17:00:394816 const ClientSocketPool::GroupId group_id_;
[email protected]58e562f2013-04-22 17:32:204817 bool can_release_connection_;
4818};
4819
[email protected]58e562f2013-04-22 17:32:204820// Tests the basic case of closing an idle socket in a higher layered pool when
4821// a new request is issued and the lower layer pool is stalled.
4822TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsHeldByLayeredPoolWhenNeeded) {
4823 CreatePool(1, 1);
4824 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4825
Matt Menkec6b3edf72019-03-19 17:00:394826 MockLayeredPool mock_layered_pool(pool_.get(), TestGroupId("foo"));
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 .WillOnce(Invoke(&mock_layered_pool,
4830 &MockLayeredPool::ReleaseOneConnection));
4831 ClientSocketHandle handle;
4832 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:504833 EXPECT_EQ(
4834 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284835 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4836 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4837 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
4838 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:014839 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204840}
4841
Matt Menke833678642019-03-05 22:05:514842// Tests the case that trying to close an idle socket in a higher layered pool
4843// fails.
4844TEST_F(ClientSocketPoolBaseTest,
4845 CloseIdleSocketsHeldByLayeredPoolWhenNeededFails) {
4846 CreatePool(1, 1);
4847 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4848
Matt Menkec6b3edf72019-03-19 17:00:394849 MockLayeredPool mock_layered_pool(pool_.get(), TestGroupId("foo"));
Matt Menke833678642019-03-05 22:05:514850 mock_layered_pool.set_can_release_connection(false);
4851 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
4852 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4853 .WillOnce(Invoke(&mock_layered_pool,
4854 &MockLayeredPool::ReleaseOneConnection));
4855 ClientSocketHandle handle;
4856 TestCompletionCallback callback;
4857 EXPECT_EQ(
4858 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284859 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4860 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4861 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
4862 pool_.get(), NetLogWithSource()));
Matt Menke833678642019-03-05 22:05:514863 base::RunLoop().RunUntilIdle();
4864 EXPECT_FALSE(callback.have_result());
4865}
4866
[email protected]58e562f2013-04-22 17:32:204867// Same as above, but the idle socket is in the same group as the stalled
4868// socket, and closes the only other request in its group when closing requests
4869// in higher layered pools. This generally shouldn't happen, but it may be
4870// possible if a higher level pool issues a request and the request is
4871// subsequently cancelled. Even if it's not possible, best not to crash.
4872TEST_F(ClientSocketPoolBaseTest,
4873 CloseIdleSocketsHeldByLayeredPoolWhenNeededSameGroup) {
4874 CreatePool(2, 2);
4875 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4876
4877 // Need a socket in another group for the pool to be stalled (If a group
4878 // has the maximum number of connections already, it's not stalled).
4879 ClientSocketHandle handle1;
4880 TestCompletionCallback callback1;
Matt Menkef09e64c2019-04-23 22:16:284881 EXPECT_EQ(OK, handle1.Init(TestGroupId("group1"), params_, base::nullopt,
4882 DEFAULT_PRIORITY, SocketTag(),
4883 ClientSocketPool::RespectLimits::ENABLED,
4884 callback1.callback(),
4885 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4886 NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:204887
Matt Menkec6b3edf72019-03-19 17:00:394888 MockLayeredPool mock_layered_pool(pool_.get(), TestGroupId("group2"));
robpercival214763f2016-07-01 23:27:014889 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:204890 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4891 .WillOnce(Invoke(&mock_layered_pool,
4892 &MockLayeredPool::ReleaseOneConnection));
4893 ClientSocketHandle handle;
4894 TestCompletionCallback callback2;
Matt Menkef09e64c2019-04-23 22:16:284895 EXPECT_EQ(ERR_IO_PENDING,
4896 handle.Init(
4897 TestGroupId("group2"), params_, base::nullopt, DEFAULT_PRIORITY,
4898 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4899 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4900 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:014901 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204902}
4903
4904// Tests the case when an idle socket can be closed when a new request is
4905// issued, and the new request belongs to a group that was previously stalled.
4906TEST_F(ClientSocketPoolBaseTest,
4907 CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded) {
4908 CreatePool(2, 2);
4909 std::list<TestConnectJob::JobType> job_types;
4910 job_types.push_back(TestConnectJob::kMockJob);
4911 job_types.push_back(TestConnectJob::kMockJob);
4912 job_types.push_back(TestConnectJob::kMockJob);
4913 job_types.push_back(TestConnectJob::kMockJob);
4914 connect_job_factory_->set_job_types(&job_types);
4915
4916 ClientSocketHandle handle1;
4917 TestCompletionCallback callback1;
Matt Menkef09e64c2019-04-23 22:16:284918 EXPECT_EQ(OK, handle1.Init(TestGroupId("group1"), params_, base::nullopt,
4919 DEFAULT_PRIORITY, SocketTag(),
4920 ClientSocketPool::RespectLimits::ENABLED,
4921 callback1.callback(),
4922 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4923 NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:204924
Matt Menkec6b3edf72019-03-19 17:00:394925 MockLayeredPool mock_layered_pool(pool_.get(), TestGroupId("group2"));
robpercival214763f2016-07-01 23:27:014926 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:204927 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4928 .WillRepeatedly(Invoke(&mock_layered_pool,
4929 &MockLayeredPool::ReleaseOneConnection));
4930 mock_layered_pool.set_can_release_connection(false);
4931
4932 // The third request is made when the socket pool is in a stalled state.
4933 ClientSocketHandle handle3;
4934 TestCompletionCallback callback3;
Matt Menkef09e64c2019-04-23 22:16:284935 EXPECT_EQ(ERR_IO_PENDING,
4936 handle3.Init(
4937 TestGroupId("group3"), params_, base::nullopt, DEFAULT_PRIORITY,
4938 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4939 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
4940 pool_.get(), NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:204941
4942 base::RunLoop().RunUntilIdle();
4943 EXPECT_FALSE(callback3.have_result());
4944
4945 // The fourth request is made when the pool is no longer stalled. The third
4946 // request should be serviced first, since it was issued first and has the
4947 // same priority.
4948 mock_layered_pool.set_can_release_connection(true);
4949 ClientSocketHandle handle4;
4950 TestCompletionCallback callback4;
Matt Menkef09e64c2019-04-23 22:16:284951 EXPECT_EQ(ERR_IO_PENDING,
4952 handle4.Init(
4953 TestGroupId("group3"), params_, base::nullopt, DEFAULT_PRIORITY,
4954 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4955 callback4.callback(), ClientSocketPool::ProxyAuthCallback(),
4956 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:014957 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204958 EXPECT_FALSE(callback4.have_result());
4959
4960 // Closing a handle should free up another socket slot.
4961 handle1.Reset();
robpercival214763f2016-07-01 23:27:014962 EXPECT_THAT(callback4.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204963}
4964
4965// Tests the case when an idle socket can be closed when a new request is
4966// issued, and the new request belongs to a group that was previously stalled.
4967//
4968// The two differences from the above test are that the stalled requests are not
4969// in the same group as the layered pool's request, and the the fourth request
4970// has a higher priority than the third one, so gets a socket first.
4971TEST_F(ClientSocketPoolBaseTest,
4972 CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded2) {
4973 CreatePool(2, 2);
4974 std::list<TestConnectJob::JobType> job_types;
4975 job_types.push_back(TestConnectJob::kMockJob);
4976 job_types.push_back(TestConnectJob::kMockJob);
4977 job_types.push_back(TestConnectJob::kMockJob);
4978 job_types.push_back(TestConnectJob::kMockJob);
4979 connect_job_factory_->set_job_types(&job_types);
4980
4981 ClientSocketHandle handle1;
4982 TestCompletionCallback callback1;
Matt Menkef09e64c2019-04-23 22:16:284983 EXPECT_EQ(OK, handle1.Init(TestGroupId("group1"), params_, base::nullopt,
4984 DEFAULT_PRIORITY, SocketTag(),
4985 ClientSocketPool::RespectLimits::ENABLED,
4986 callback1.callback(),
4987 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4988 NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:204989
Matt Menkec6b3edf72019-03-19 17:00:394990 MockLayeredPool mock_layered_pool(pool_.get(), TestGroupId("group2"));
robpercival214763f2016-07-01 23:27:014991 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:204992 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4993 .WillRepeatedly(Invoke(&mock_layered_pool,
4994 &MockLayeredPool::ReleaseOneConnection));
4995 mock_layered_pool.set_can_release_connection(false);
4996
4997 // The third request is made when the socket pool is in a stalled state.
4998 ClientSocketHandle handle3;
4999 TestCompletionCallback callback3;
tfarina428341112016-09-22 13:38:205000 EXPECT_EQ(
5001 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:285002 handle3.Init(TestGroupId("group3"), params_, base::nullopt, MEDIUM,
5003 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:505004 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
5005 pool_.get(), NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:205006
5007 base::RunLoop().RunUntilIdle();
5008 EXPECT_FALSE(callback3.have_result());
5009
5010 // The fourth request is made when the pool is no longer stalled. This
5011 // request has a higher priority than the third request, so is serviced first.
5012 mock_layered_pool.set_can_release_connection(true);
5013 ClientSocketHandle handle4;
5014 TestCompletionCallback callback4;
tfarina428341112016-09-22 13:38:205015 EXPECT_EQ(
5016 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:285017 handle4.Init(TestGroupId("group3"), params_, base::nullopt, HIGHEST,
5018 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:505019 callback4.callback(), ClientSocketPool::ProxyAuthCallback(),
5020 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:015021 EXPECT_THAT(callback4.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:205022 EXPECT_FALSE(callback3.have_result());
5023
5024 // Closing a handle should free up another socket slot.
5025 handle1.Reset();
robpercival214763f2016-07-01 23:27:015026 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:205027}
5028
5029TEST_F(ClientSocketPoolBaseTest,
5030 CloseMultipleIdleSocketsHeldByLayeredPoolWhenNeeded) {
5031 CreatePool(1, 1);
5032 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
5033
Matt Menkec6b3edf72019-03-19 17:00:395034 MockLayeredPool mock_layered_pool1(pool_.get(), TestGroupId("foo"));
robpercival214763f2016-07-01 23:27:015035 EXPECT_THAT(mock_layered_pool1.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:205036 EXPECT_CALL(mock_layered_pool1, CloseOneIdleConnection())
5037 .WillRepeatedly(Invoke(&mock_layered_pool1,
5038 &MockLayeredPool::ReleaseOneConnection));
Matt Menkec6b3edf72019-03-19 17:00:395039 MockLayeredPool mock_layered_pool2(pool_.get(), TestGroupId("bar"));
robpercival214763f2016-07-01 23:27:015040 EXPECT_THAT(mock_layered_pool2.RequestSocketWithoutLimits(pool_.get()),
5041 IsOk());
[email protected]58e562f2013-04-22 17:32:205042 EXPECT_CALL(mock_layered_pool2, CloseOneIdleConnection())
5043 .WillRepeatedly(Invoke(&mock_layered_pool2,
5044 &MockLayeredPool::ReleaseOneConnection));
5045 ClientSocketHandle handle;
5046 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:505047 EXPECT_EQ(
5048 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:285049 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
5050 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5051 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5052 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:015053 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:205054}
5055
[email protected]b021ece62013-06-11 11:06:335056// Test that when a socket pool and group are at their limits, a request
mmenked3641e12016-01-28 16:06:155057// with RespectLimits::DISABLED triggers creation of a new socket, and gets the
5058// socket instead of a request with the same priority that was issued earlier,
5059// but has RespectLimits::ENABLED.
[email protected]b021ece62013-06-11 11:06:335060TEST_F(ClientSocketPoolBaseTest, IgnoreLimits) {
[email protected]b021ece62013-06-11 11:06:335061 CreatePool(1, 1);
5062
5063 // Issue a request to reach the socket pool limit.
Matt Menkec6b3edf72019-03-19 17:00:395064 EXPECT_EQ(OK, StartRequestWithIgnoreLimits(
5065 TestGroupId("a"), MAXIMUM_PRIORITY,
5066 ClientSocketPool::RespectLimits::ENABLED));
Matt Menke9fa17d52019-03-25 19:12:265067 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]b021ece62013-06-11 11:06:335068
5069 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
5070
mmenked3641e12016-01-28 16:06:155071 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
Matt Menkec6b3edf72019-03-19 17:00:395072 TestGroupId("a"), MAXIMUM_PRIORITY,
mmenked3641e12016-01-28 16:06:155073 ClientSocketPool::RespectLimits::ENABLED));
Matt Menke9fa17d52019-03-25 19:12:265074 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]b021ece62013-06-11 11:06:335075
mmenked3641e12016-01-28 16:06:155076 // Issue a request that ignores the limits, so a new ConnectJob is
5077 // created.
5078 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
Matt Menkec6b3edf72019-03-19 17:00:395079 TestGroupId("a"), MAXIMUM_PRIORITY,
mmenked3641e12016-01-28 16:06:155080 ClientSocketPool::RespectLimits::DISABLED));
Matt Menke9fa17d52019-03-25 19:12:265081 ASSERT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]b021ece62013-06-11 11:06:335082
robpercival214763f2016-07-01 23:27:015083 EXPECT_THAT(request(2)->WaitForResult(), IsOk());
[email protected]b021ece62013-06-11 11:06:335084 EXPECT_FALSE(request(1)->have_result());
5085}
5086
[email protected]c55fabd2013-11-04 23:26:565087// Test that when a socket pool and group are at their limits, a ConnectJob
mmenked3641e12016-01-28 16:06:155088// issued for a request with RespectLimits::DISABLED is not cancelled when a
5089// request with RespectLimits::ENABLED issued to the same group is cancelled.
[email protected]c55fabd2013-11-04 23:26:565090TEST_F(ClientSocketPoolBaseTest, IgnoreLimitsCancelOtherJob) {
[email protected]c55fabd2013-11-04 23:26:565091 CreatePool(1, 1);
5092
5093 // Issue a request to reach the socket pool limit.
Matt Menkec6b3edf72019-03-19 17:00:395094 EXPECT_EQ(OK, StartRequestWithIgnoreLimits(
5095 TestGroupId("a"), MAXIMUM_PRIORITY,
5096 ClientSocketPool::RespectLimits::ENABLED));
Matt Menke9fa17d52019-03-25 19:12:265097 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]c55fabd2013-11-04 23:26:565098
5099 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
5100
mmenked3641e12016-01-28 16:06:155101 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
Matt Menkec6b3edf72019-03-19 17:00:395102 TestGroupId("a"), MAXIMUM_PRIORITY,
mmenked3641e12016-01-28 16:06:155103 ClientSocketPool::RespectLimits::ENABLED));
Matt Menke9fa17d52019-03-25 19:12:265104 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]c55fabd2013-11-04 23:26:565105
mmenked3641e12016-01-28 16:06:155106 // Issue a request with RespectLimits::DISABLED, so a new ConnectJob is
5107 // created.
5108 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
Matt Menkec6b3edf72019-03-19 17:00:395109 TestGroupId("a"), MAXIMUM_PRIORITY,
mmenked3641e12016-01-28 16:06:155110 ClientSocketPool::RespectLimits::DISABLED));
Matt Menke9fa17d52019-03-25 19:12:265111 ASSERT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]b021ece62013-06-11 11:06:335112
mmenked3641e12016-01-28 16:06:155113 // Cancel the pending request with RespectLimits::ENABLED. The ConnectJob
[email protected]b021ece62013-06-11 11:06:335114 // should not be cancelled.
5115 request(1)->handle()->Reset();
Matt Menke9fa17d52019-03-25 19:12:265116 ASSERT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]b021ece62013-06-11 11:06:335117
robpercival214763f2016-07-01 23:27:015118 EXPECT_THAT(request(2)->WaitForResult(), IsOk());
[email protected]b021ece62013-06-11 11:06:335119 EXPECT_FALSE(request(1)->have_result());
5120}
5121
Matt Menkeb57663b32019-03-01 17:17:105122TEST_F(ClientSocketPoolBaseTest, ProxyAuthNoAuthCallback) {
5123 CreatePool(1, 1);
5124
5125 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5126
5127 ClientSocketHandle handle;
5128 TestCompletionCallback callback;
5129 EXPECT_EQ(
5130 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:285131 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
5132 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5133 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5134 pool_.get(), NetLogWithSource()));
Matt Menkeb57663b32019-03-01 17:17:105135
Matt Menke9fa17d52019-03-25 19:12:265136 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105137
5138 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_PROXY_AUTH_REQUESTED));
5139 EXPECT_FALSE(handle.is_initialized());
5140 EXPECT_FALSE(handle.socket());
5141
5142 // The group should now be empty, and thus be deleted.
Matt Menke9fa17d52019-03-25 19:12:265143 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105144}
5145
5146class TestAuthHelper {
5147 public:
5148 TestAuthHelper() = default;
5149 ~TestAuthHelper() = default;
5150
Matt Menkec6b3edf72019-03-19 17:00:395151 void InitHandle(
Matt Menke84d11e562019-03-27 00:11:195152 scoped_refptr<ClientSocketPool::SocketParams> params,
Matt Menke9fa17d52019-03-25 19:12:265153 TransportClientSocketPool* pool,
Matt Menkec6b3edf72019-03-19 17:00:395154 RequestPriority priority = DEFAULT_PRIORITY,
5155 ClientSocketPool::RespectLimits respect_limits =
5156 ClientSocketPool::RespectLimits::ENABLED,
5157 const ClientSocketPool::GroupId& group_id_in = TestGroupId("a")) {
Matt Menkeb57663b32019-03-01 17:17:105158 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:285159 handle_.Init(group_id_in, params, base::nullopt, priority,
5160 SocketTag(), respect_limits, callback_.callback(),
Matt Menkeb57663b32019-03-01 17:17:105161 base::BindRepeating(&TestAuthHelper::AuthCallback,
5162 base::Unretained(this)),
5163 pool, NetLogWithSource()));
5164 }
5165
5166 void WaitForAuth() {
5167 run_loop_ = std::make_unique<base::RunLoop>();
5168 run_loop_->Run();
5169 run_loop_.reset();
5170 }
5171
5172 void WaitForAuthAndRestartSync() {
5173 restart_sync_ = true;
5174 WaitForAuth();
5175 restart_sync_ = false;
5176 }
5177
5178 void WaitForAuthAndResetHandleSync() {
5179 reset_handle_sync_ = true;
5180 WaitForAuth();
5181 reset_handle_sync_ = false;
5182 }
5183
5184 void RestartWithAuth() {
5185 DCHECK(restart_with_auth_callback_);
5186 std::move(restart_with_auth_callback_).Run();
5187 }
5188
5189 int WaitForResult() {
5190 int result = callback_.WaitForResult();
5191 // There shouldn't be any callback waiting to be invoked once the request is
5192 // complete.
5193 EXPECT_FALSE(restart_with_auth_callback_);
5194 // The socket should only be initialized on success.
5195 EXPECT_EQ(result == OK, handle_.is_initialized());
5196 EXPECT_EQ(result == OK, handle_.socket() != nullptr);
5197 return result;
5198 }
5199
5200 ClientSocketHandle* handle() { return &handle_; }
5201 int auth_count() const { return auth_count_; }
5202 int have_result() const { return callback_.have_result(); }
5203
5204 private:
5205 void AuthCallback(const HttpResponseInfo& response,
5206 HttpAuthController* auth_controller,
5207 base::OnceClosure restart_with_auth_callback) {
5208 EXPECT_FALSE(restart_with_auth_callback_);
5209 EXPECT_TRUE(restart_with_auth_callback);
5210
5211 // Once there's a result, this method shouldn't be invoked again.
5212 EXPECT_FALSE(callback_.have_result());
5213
5214 ++auth_count_;
5215 run_loop_->Quit();
5216 if (restart_sync_) {
5217 std::move(restart_with_auth_callback).Run();
5218 return;
5219 }
5220
5221 restart_with_auth_callback_ = std::move(restart_with_auth_callback);
5222
5223 if (reset_handle_sync_) {
5224 handle_.Reset();
5225 return;
5226 }
5227 }
5228
5229 std::unique_ptr<base::RunLoop> run_loop_;
5230 base::OnceClosure restart_with_auth_callback_;
5231
5232 bool restart_sync_ = false;
5233 bool reset_handle_sync_ = false;
5234
5235 ClientSocketHandle handle_;
5236 int auth_count_ = 0;
5237 TestCompletionCallback callback_;
5238
5239 DISALLOW_COPY_AND_ASSIGN(TestAuthHelper);
5240};
5241
5242TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnce) {
5243 CreatePool(1, 1);
5244 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5245
5246 TestAuthHelper auth_helper;
5247 auth_helper.InitHandle(params_, pool_.get());
Matt Menke9fa17d52019-03-25 19:12:265248 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menke4b69f932019-03-04 16:20:015249 EXPECT_EQ(LOAD_STATE_CONNECTING,
Matt Menkec6b3edf72019-03-19 17:00:395250 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:105251
5252 auth_helper.WaitForAuth();
Matt Menke9fa17d52019-03-25 19:12:265253 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menke4b69f932019-03-04 16:20:015254 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
Matt Menkec6b3edf72019-03-19 17:00:395255 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:105256
5257 auth_helper.RestartWithAuth();
Matt Menke9fa17d52019-03-25 19:12:265258 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menke4b69f932019-03-04 16:20:015259 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
Matt Menkec6b3edf72019-03-19 17:00:395260 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:105261
5262 EXPECT_THAT(auth_helper.WaitForResult(), IsOk());
5263 EXPECT_EQ(1, auth_helper.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265264 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5265 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:395266 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105267 EXPECT_EQ(0, pool_->IdleSocketCount());
5268}
5269
5270TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceSync) {
5271 CreatePool(1, 1);
5272 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5273
5274 TestAuthHelper auth_helper;
5275 auth_helper.InitHandle(params_, pool_.get());
Matt Menke9fa17d52019-03-25 19:12:265276 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menke4b69f932019-03-04 16:20:015277 EXPECT_EQ(LOAD_STATE_CONNECTING,
Matt Menkec6b3edf72019-03-19 17:00:395278 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:105279
5280 auth_helper.WaitForAuthAndRestartSync();
Matt Menke9fa17d52019-03-25 19:12:265281 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menke4b69f932019-03-04 16:20:015282 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
Matt Menkec6b3edf72019-03-19 17:00:395283 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:105284
5285 EXPECT_THAT(auth_helper.WaitForResult(), IsOk());
5286 EXPECT_EQ(1, auth_helper.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265287 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5288 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:395289 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105290 EXPECT_EQ(0, pool_->IdleSocketCount());
5291}
5292
5293TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceFails) {
5294 CreatePool(1, 1);
5295 connect_job_factory_->set_job_type(
5296 TestConnectJob::kMockAuthChallengeOnceFailingJob);
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 Menkeb57663b32019-03-01 17:17:105301
5302 auth_helper.WaitForAuth();
5303 auth_helper.RestartWithAuth();
5304 EXPECT_THAT(auth_helper.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
5305
5306 EXPECT_EQ(1, auth_helper.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265307 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105308 EXPECT_EQ(0, pool_->IdleSocketCount());
5309}
5310
5311TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceSyncFails) {
5312 CreatePool(1, 1);
5313 connect_job_factory_->set_job_type(
5314 TestConnectJob::kMockAuthChallengeOnceFailingJob);
5315
5316 TestAuthHelper auth_helper;
5317 auth_helper.InitHandle(params_, pool_.get());
Matt Menke9fa17d52019-03-25 19:12:265318 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105319
5320 auth_helper.WaitForAuthAndRestartSync();
5321 EXPECT_THAT(auth_helper.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
5322
5323 EXPECT_EQ(1, auth_helper.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265324 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105325 EXPECT_EQ(0, pool_->IdleSocketCount());
5326}
5327
5328TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceDeleteHandle) {
5329 CreatePool(1, 1);
5330 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5331
5332 TestAuthHelper auth_helper;
5333 auth_helper.InitHandle(params_, pool_.get());
Matt Menke9fa17d52019-03-25 19:12:265334 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105335
5336 auth_helper.WaitForAuth();
Matt Menke9fa17d52019-03-25 19:12:265337 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105338
5339 auth_helper.handle()->Reset();
5340
5341 EXPECT_EQ(1, auth_helper.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265342 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105343 EXPECT_EQ(0, pool_->IdleSocketCount());
5344 EXPECT_FALSE(auth_helper.handle()->is_initialized());
5345 EXPECT_FALSE(auth_helper.handle()->socket());
5346}
5347
5348TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceDeleteHandleSync) {
5349 CreatePool(1, 1);
5350 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5351
5352 TestAuthHelper auth_helper;
5353 auth_helper.InitHandle(params_, pool_.get());
Matt Menke9fa17d52019-03-25 19:12:265354 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105355
5356 auth_helper.WaitForAuthAndResetHandleSync();
5357 EXPECT_EQ(1, auth_helper.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265358 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105359 EXPECT_EQ(0, pool_->IdleSocketCount());
5360 EXPECT_FALSE(auth_helper.handle()->is_initialized());
5361 EXPECT_FALSE(auth_helper.handle()->socket());
5362}
5363
5364TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceFlushWithError) {
5365 CreatePool(1, 1);
5366 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5367
5368 TestAuthHelper auth_helper;
5369 auth_helper.InitHandle(params_, pool_.get());
Matt Menke9fa17d52019-03-25 19:12:265370 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105371
5372 auth_helper.WaitForAuth();
5373
Matt Menke433de6d2020-03-04 00:24:115374 pool_->FlushWithError(ERR_FAILED, "Network changed");
Matt Menkeb57663b32019-03-01 17:17:105375 base::RunLoop().RunUntilIdle();
5376
5377 // When flushing the socket pool, bound sockets should delay returning the
5378 // error until completion.
5379 EXPECT_FALSE(auth_helper.have_result());
Matt Menke9fa17d52019-03-25 19:12:265380 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105381 EXPECT_EQ(0, pool_->IdleSocketCount());
5382
5383 auth_helper.RestartWithAuth();
5384 // The callback should be called asynchronously.
5385 EXPECT_FALSE(auth_helper.have_result());
5386
5387 EXPECT_THAT(auth_helper.WaitForResult(), IsError(ERR_FAILED));
Matt Menke9fa17d52019-03-25 19:12:265388 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105389 EXPECT_EQ(0, pool_->IdleSocketCount());
5390}
5391
5392TEST_F(ClientSocketPoolBaseTest, ProxyAuthTwice) {
5393 CreatePool(1, 1);
5394 connect_job_factory_->set_job_type(
5395 TestConnectJob::kMockAuthChallengeTwiceJob);
5396
5397 TestAuthHelper auth_helper;
5398 auth_helper.InitHandle(params_, pool_.get());
Matt Menke9fa17d52019-03-25 19:12:265399 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menke4b69f932019-03-04 16:20:015400 EXPECT_EQ(LOAD_STATE_CONNECTING,
Matt Menkec6b3edf72019-03-19 17:00:395401 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:105402
5403 auth_helper.WaitForAuth();
5404 auth_helper.RestartWithAuth();
Matt Menke9fa17d52019-03-25 19:12:265405 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105406 EXPECT_EQ(1, auth_helper.auth_count());
Matt Menke4b69f932019-03-04 16:20:015407 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
Matt Menkec6b3edf72019-03-19 17:00:395408 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:105409
5410 auth_helper.WaitForAuth();
Matt Menke9fa17d52019-03-25 19:12:265411 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menke4b69f932019-03-04 16:20:015412 EXPECT_EQ(2, auth_helper.auth_count());
5413 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
Matt Menkec6b3edf72019-03-19 17:00:395414 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
Matt Menke4b69f932019-03-04 16:20:015415
Matt Menkeb57663b32019-03-01 17:17:105416 auth_helper.RestartWithAuth();
Matt Menke9fa17d52019-03-25 19:12:265417 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105418 EXPECT_EQ(2, auth_helper.auth_count());
Matt Menke4b69f932019-03-04 16:20:015419 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
Matt Menkec6b3edf72019-03-19 17:00:395420 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:105421
5422 EXPECT_THAT(auth_helper.WaitForResult(), IsOk());
5423 EXPECT_EQ(2, auth_helper.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265424 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5425 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:395426 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105427 EXPECT_EQ(0, pool_->IdleSocketCount());
5428}
5429
5430TEST_F(ClientSocketPoolBaseTest, ProxyAuthTwiceFails) {
5431 CreatePool(1, 1);
5432 connect_job_factory_->set_job_type(
5433 TestConnectJob::kMockAuthChallengeTwiceFailingJob);
5434
5435 TestAuthHelper auth_helper;
5436 auth_helper.InitHandle(params_, pool_.get());
Matt Menke9fa17d52019-03-25 19:12:265437 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105438
5439 auth_helper.WaitForAuth();
5440 auth_helper.RestartWithAuth();
Matt Menke9fa17d52019-03-25 19:12:265441 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105442 EXPECT_EQ(1, auth_helper.auth_count());
5443
5444 auth_helper.WaitForAuth();
5445 auth_helper.RestartWithAuth();
Matt Menke9fa17d52019-03-25 19:12:265446 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105447 EXPECT_EQ(2, auth_helper.auth_count());
5448
5449 EXPECT_THAT(auth_helper.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
5450 EXPECT_EQ(2, auth_helper.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265451 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105452 EXPECT_EQ(0, pool_->IdleSocketCount());
5453}
5454
5455// Makes sure that when a bound request is destroyed, a new ConnectJob is
5456// created, if needed.
5457TEST_F(ClientSocketPoolBaseTest,
5458 ProxyAuthCreateNewConnectJobOnDestroyBoundRequest) {
5459 CreatePool(1 /* max_sockets */, 1 /* max_sockets_per_group */);
5460 connect_job_factory_->set_job_type(
5461 TestConnectJob::kMockAuthChallengeOnceFailingJob);
5462
5463 // First request creates a ConnectJob.
5464 TestAuthHelper auth_helper1;
5465 auth_helper1.InitHandle(params_, pool_.get());
Matt Menke9fa17d52019-03-25 19:12:265466 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105467
5468 // A second request come in, but no new ConnectJob is needed, since the limit
5469 // has been reached.
5470 TestAuthHelper auth_helper2;
5471 auth_helper2.InitHandle(params_, pool_.get());
Matt Menke9fa17d52019-03-25 19:12:265472 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105473
5474 // Run until the auth callback for the first request is invoked.
5475 auth_helper1.WaitForAuth();
5476 EXPECT_EQ(0, auth_helper2.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265477 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5478 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:395479 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105480
5481 // Make connect jobs succeed, then cancel the first request, which should
5482 // destroy the bound ConnectJob, and cause a new ConnectJob to start.
5483 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
5484 auth_helper1.handle()->Reset();
5485 EXPECT_EQ(0, auth_helper2.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265486 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105487
5488 // The second ConnectJob should succeed.
5489 EXPECT_THAT(auth_helper2.WaitForResult(), IsOk());
5490 EXPECT_EQ(0, auth_helper2.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265491 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105492}
5493
5494// Makes sure that when a bound request is destroyed, a new ConnectJob is
5495// created for another group, if needed.
5496TEST_F(ClientSocketPoolBaseTest,
5497 ProxyAuthCreateNewConnectJobOnDestroyBoundRequestDifferentGroups) {
5498 CreatePool(1 /* max_sockets */, 1 /* max_sockets_per_group */);
5499 connect_job_factory_->set_job_type(
5500 TestConnectJob::kMockAuthChallengeOnceFailingJob);
5501
5502 // First request creates a ConnectJob.
5503 TestAuthHelper auth_helper1;
5504 auth_helper1.InitHandle(params_, pool_.get(), DEFAULT_PRIORITY);
Matt Menke9fa17d52019-03-25 19:12:265505 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105506
5507 // A second request come in, but no new ConnectJob is needed, since the limit
5508 // has been reached.
5509 TestAuthHelper auth_helper2;
5510 auth_helper2.InitHandle(params_, pool_.get(), DEFAULT_PRIORITY,
Matt Menkec6b3edf72019-03-19 17:00:395511 ClientSocketPool::RespectLimits::ENABLED,
5512 TestGroupId("b"));
Matt Menke9fa17d52019-03-25 19:12:265513 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5514 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
Matt Menkeb57663b32019-03-01 17:17:105515
5516 // Run until the auth callback for the first request is invoked.
5517 auth_helper1.WaitForAuth();
5518 EXPECT_EQ(0, auth_helper2.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265519 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5520 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:395521 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menke9fa17d52019-03-25 19:12:265522 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
5523 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("b")));
Matt Menkec6b3edf72019-03-19 17:00:395524 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("b")));
Matt Menkeb57663b32019-03-01 17:17:105525
5526 // Make connect jobs succeed, then cancel the first request, which should
5527 // destroy the bound ConnectJob, and cause a new ConnectJob to start for the
5528 // other group.
5529 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
5530 auth_helper1.handle()->Reset();
5531 EXPECT_EQ(0, auth_helper2.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265532 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
5533 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
Matt Menkeb57663b32019-03-01 17:17:105534
5535 // The second ConnectJob should succeed.
5536 EXPECT_THAT(auth_helper2.WaitForResult(), IsOk());
5537 EXPECT_EQ(0, auth_helper2.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265538 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
5539 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
Matt Menkeb57663b32019-03-01 17:17:105540}
5541
5542// Test that once an auth challenge is bound, that's the request that gets all
5543// subsequent calls and the socket itself.
5544TEST_F(ClientSocketPoolBaseTest, ProxyAuthStaysBound) {
5545 CreatePool(1, 1);
5546 connect_job_factory_->set_job_type(
5547 TestConnectJob::kMockAuthChallengeTwiceJob);
5548
5549 // First request creates a ConnectJob.
5550 TestAuthHelper auth_helper1;
5551 auth_helper1.InitHandle(params_, pool_.get(), LOWEST);
Matt Menke9fa17d52019-03-25 19:12:265552 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105553
5554 // A second, higher priority request is made.
5555 TestAuthHelper auth_helper2;
5556 auth_helper2.InitHandle(params_, pool_.get(), LOW);
Matt Menke9fa17d52019-03-25 19:12:265557 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105558
5559 // Run until the auth callback for the second request is invoked.
5560 auth_helper2.WaitForAuth();
5561 EXPECT_EQ(0, auth_helper1.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265562 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5563 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:395564 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105565
5566 // Start a higher priority job. It shouldn't be able to steal |auth_helper2|'s
5567 // ConnectJob.
5568 TestAuthHelper auth_helper3;
5569 auth_helper3.InitHandle(params_, pool_.get(), HIGHEST);
Matt Menke9fa17d52019-03-25 19:12:265570 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105571
5572 // Start a higher job that ignores limits, creating a hanging socket. It
5573 // shouldn't be able to steal |auth_helper2|'s ConnectJob.
5574 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
5575 TestAuthHelper auth_helper4;
5576 auth_helper4.InitHandle(params_, pool_.get(), HIGHEST,
5577 ClientSocketPool::RespectLimits::DISABLED);
Matt Menke9fa17d52019-03-25 19:12:265578 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105579
5580 // Restart with auth, and |auth_helper2|'s auth method should be invoked
5581 // again.
5582 auth_helper2.RestartWithAuth();
5583 auth_helper2.WaitForAuth();
5584 EXPECT_EQ(0, auth_helper1.auth_count());
5585 EXPECT_FALSE(auth_helper1.have_result());
5586 EXPECT_EQ(2, auth_helper2.auth_count());
5587 EXPECT_FALSE(auth_helper2.have_result());
5588 EXPECT_EQ(0, auth_helper3.auth_count());
5589 EXPECT_FALSE(auth_helper3.have_result());
5590 EXPECT_EQ(0, auth_helper4.auth_count());
5591 EXPECT_FALSE(auth_helper4.have_result());
5592
5593 // Advance auth again, and |auth_helper2| should get the socket.
5594 auth_helper2.RestartWithAuth();
5595 EXPECT_THAT(auth_helper2.WaitForResult(), IsOk());
5596 // The hung ConnectJob for the RespectLimits::DISABLED request is still in the
5597 // socket pool.
Matt Menke9fa17d52019-03-25 19:12:265598 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5599 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105600 EXPECT_EQ(0, auth_helper1.auth_count());
5601 EXPECT_FALSE(auth_helper1.have_result());
5602 EXPECT_EQ(0, auth_helper3.auth_count());
5603 EXPECT_FALSE(auth_helper3.have_result());
5604 EXPECT_EQ(0, auth_helper4.auth_count());
5605 EXPECT_FALSE(auth_helper4.have_result());
5606
5607 // If the socket is returned to the socket pool, the RespectLimits::DISABLED
5608 // socket request should be able to claim it.
5609 auth_helper2.handle()->Reset();
5610 EXPECT_THAT(auth_helper4.WaitForResult(), IsOk());
5611 EXPECT_EQ(0, auth_helper1.auth_count());
5612 EXPECT_FALSE(auth_helper1.have_result());
5613 EXPECT_EQ(0, auth_helper3.auth_count());
5614 EXPECT_FALSE(auth_helper3.have_result());
5615 EXPECT_EQ(0, auth_helper4.auth_count());
5616}
5617
David Benjaminbac8dff2019-08-07 01:30:415618enum class RefreshType {
5619 kServer,
5620 kProxy,
5621};
5622
5623// Common base class to test RefreshGroup() when called from either
5624// OnSSLConfigForServerChanged() matching a specific group or the pool's proxy.
5625//
5626// Tests which test behavior specific to one or the other case should use
5627// ClientSocketPoolBaseTest directly. In particular, there is no "other group"
5628// when the pool's proxy matches.
5629class ClientSocketPoolBaseRefreshTest
5630 : public ClientSocketPoolBaseTest,
5631 public testing::WithParamInterface<RefreshType> {
5632 public:
5633 void CreatePoolForRefresh(int max_sockets,
5634 int max_sockets_per_group,
5635 bool enable_backup_connect_jobs = false) {
5636 switch (GetParam()) {
5637 case RefreshType::kServer:
5638 CreatePool(max_sockets, max_sockets_per_group,
5639 enable_backup_connect_jobs);
5640 break;
5641 case RefreshType::kProxy:
5642 CreatePoolWithIdleTimeouts(
5643 max_sockets, max_sockets_per_group, kUnusedIdleSocketTimeout,
5644 ClientSocketPool::used_idle_socket_timeout(),
5645 enable_backup_connect_jobs,
5646 ProxyServer::FromPacString("HTTPS myproxy:70"));
5647 break;
5648 }
5649 }
5650
5651 static ClientSocketPool::GroupId GetGroupId() {
5652 return TestGroupId("a", 443, ClientSocketPool::SocketType::kSsl);
5653 }
5654
David Benjamin6dd7e882019-10-10 02:35:235655 static ClientSocketPool::GroupId GetGroupIdInPartition() {
5656 // Note this GroupId will match GetGroupId() unless
5657 // kPartitionConnectionsByNetworkIsolationKey is enabled.
5658 const auto kOrigin = url::Origin::Create(GURL("https://b/"));
5659 const NetworkIsolationKey kNetworkIsolationKey(kOrigin, kOrigin);
5660 return TestGroupId("a", 443, ClientSocketPool::SocketType::kSsl,
5661 PrivacyMode::PRIVACY_MODE_DISABLED,
5662 kNetworkIsolationKey);
5663 }
5664
David Benjaminbac8dff2019-08-07 01:30:415665 void OnSSLConfigForServerChanged() {
5666 switch (GetParam()) {
5667 case RefreshType::kServer:
5668 pool_->OnSSLConfigForServerChanged(HostPortPair("a", 443));
5669 break;
5670 case RefreshType::kProxy:
5671 pool_->OnSSLConfigForServerChanged(HostPortPair("myproxy", 70));
5672 break;
5673 }
5674 }
5675};
5676
5677INSTANTIATE_TEST_SUITE_P(RefreshType,
5678 ClientSocketPoolBaseRefreshTest,
5679 ::testing::Values(RefreshType::kServer,
5680 RefreshType::kProxy));
5681
5682TEST_P(ClientSocketPoolBaseRefreshTest, RefreshGroupCreatesNewConnectJobs) {
5683 CreatePoolForRefresh(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
5684 const ClientSocketPool::GroupId kGroupId = GetGroupId();
Matt Menkebf3c767d2019-04-15 23:28:245685
5686 // First job will be waiting until it gets aborted.
5687 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
5688
5689 ClientSocketHandle handle;
5690 TestCompletionCallback callback;
5691 EXPECT_THAT(
Matt Menkef09e64c2019-04-23 22:16:285692 handle.Init(kGroupId, params_, base::nullopt, DEFAULT_PRIORITY,
5693 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5694 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5695 pool_.get(), NetLogWithSource()),
Matt Menkebf3c767d2019-04-15 23:28:245696 IsError(ERR_IO_PENDING));
5697
5698 // Switch connect job types, so creating a new ConnectJob will result in
5699 // success.
5700 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
5701
David Benjaminbac8dff2019-08-07 01:30:415702 OnSSLConfigForServerChanged();
Matt Menkebf3c767d2019-04-15 23:28:245703 EXPECT_EQ(OK, callback.WaitForResult());
5704 ASSERT_TRUE(handle.socket());
5705 EXPECT_EQ(0, pool_->IdleSocketCount());
5706 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId));
5707 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(kGroupId));
5708 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(kGroupId));
5709 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId));
5710}
5711
David Benjaminbac8dff2019-08-07 01:30:415712TEST_P(ClientSocketPoolBaseRefreshTest, RefreshGroupClosesIdleConnectJobs) {
David Benjamin6dd7e882019-10-10 02:35:235713 base::test::ScopedFeatureList feature_list;
5714 feature_list.InitAndEnableFeature(
5715 features::kPartitionConnectionsByNetworkIsolationKey);
5716
David Benjaminbac8dff2019-08-07 01:30:415717 CreatePoolForRefresh(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
5718 const ClientSocketPool::GroupId kGroupId = GetGroupId();
David Benjamin6dd7e882019-10-10 02:35:235719 const ClientSocketPool::GroupId kGroupIdInPartition = GetGroupIdInPartition();
Matt Menkebf3c767d2019-04-15 23:28:245720
Matt Menkef09e64c2019-04-23 22:16:285721 pool_->RequestSockets(kGroupId, params_, base::nullopt, 2,
5722 NetLogWithSource());
David Benjamin6dd7e882019-10-10 02:35:235723 pool_->RequestSockets(kGroupIdInPartition, params_, base::nullopt, 2,
5724 NetLogWithSource());
Matt Menkebf3c767d2019-04-15 23:28:245725 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId));
David Benjamin6dd7e882019-10-10 02:35:235726 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupIdInPartition));
5727 EXPECT_EQ(4, pool_->IdleSocketCount());
Matt Menkebf3c767d2019-04-15 23:28:245728 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(kGroupId));
David Benjamin6dd7e882019-10-10 02:35:235729 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(kGroupIdInPartition));
Matt Menkebf3c767d2019-04-15 23:28:245730
David Benjaminbac8dff2019-08-07 01:30:415731 OnSSLConfigForServerChanged();
Matt Menkebf3c767d2019-04-15 23:28:245732 EXPECT_EQ(0, pool_->IdleSocketCount());
5733 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupId));
David Benjamin6dd7e882019-10-10 02:35:235734 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupIdInPartition));
Matt Menkebf3c767d2019-04-15 23:28:245735}
5736
5737TEST_F(ClientSocketPoolBaseTest,
5738 RefreshGroupDoesNotCloseIdleConnectJobsInOtherGroup) {
5739 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
David Benjaminbac8dff2019-08-07 01:30:415740 const ClientSocketPool::GroupId kGroupId =
5741 TestGroupId("a", 443, ClientSocketPool::SocketType::kSsl);
5742 const ClientSocketPool::GroupId kOtherGroupId =
5743 TestGroupId("b", 443, ClientSocketPool::SocketType::kSsl);
Matt Menkebf3c767d2019-04-15 23:28:245744
Matt Menkef09e64c2019-04-23 22:16:285745 pool_->RequestSockets(kOtherGroupId, params_, base::nullopt, 2,
5746 NetLogWithSource());
Matt Menkebf3c767d2019-04-15 23:28:245747 ASSERT_TRUE(pool_->HasGroupForTesting(kOtherGroupId));
5748 EXPECT_EQ(2, pool_->IdleSocketCount());
5749 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(kOtherGroupId));
5750
David Benjaminbac8dff2019-08-07 01:30:415751 pool_->OnSSLConfigForServerChanged(HostPortPair("a", 443));
Matt Menkebf3c767d2019-04-15 23:28:245752 ASSERT_TRUE(pool_->HasGroupForTesting(kOtherGroupId));
5753 EXPECT_EQ(2, pool_->IdleSocketCount());
5754 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(kOtherGroupId));
5755}
5756
David Benjaminbac8dff2019-08-07 01:30:415757TEST_P(ClientSocketPoolBaseRefreshTest, RefreshGroupPreventsSocketReuse) {
5758 CreatePoolForRefresh(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
5759 const ClientSocketPool::GroupId kGroupId = GetGroupId();
Matt Menkebf3c767d2019-04-15 23:28:245760
5761 ClientSocketHandle handle;
5762 TestCompletionCallback callback;
5763 EXPECT_THAT(
Matt Menkef09e64c2019-04-23 22:16:285764 handle.Init(kGroupId, params_, base::nullopt, DEFAULT_PRIORITY,
5765 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5766 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5767 pool_.get(), NetLogWithSource()),
Matt Menkebf3c767d2019-04-15 23:28:245768 IsOk());
5769 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId));
5770 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId));
5771
David Benjaminbac8dff2019-08-07 01:30:415772 OnSSLConfigForServerChanged();
Matt Menkebf3c767d2019-04-15 23:28:245773
5774 handle.Reset();
5775 EXPECT_EQ(0, pool_->IdleSocketCount());
5776 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupId));
5777}
5778
5779TEST_F(ClientSocketPoolBaseTest,
5780 RefreshGroupDoesNotPreventSocketReuseInOtherGroup) {
5781 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
David Benjaminbac8dff2019-08-07 01:30:415782 const ClientSocketPool::GroupId kGroupId =
5783 TestGroupId("a", 443, ClientSocketPool::SocketType::kSsl);
5784 const ClientSocketPool::GroupId kOtherGroupId =
5785 TestGroupId("b", 443, ClientSocketPool::SocketType::kSsl);
Matt Menkebf3c767d2019-04-15 23:28:245786
5787 ClientSocketHandle handle;
5788 TestCompletionCallback callback;
5789 EXPECT_THAT(
Matt Menkef09e64c2019-04-23 22:16:285790 handle.Init(kOtherGroupId, params_, base::nullopt, DEFAULT_PRIORITY,
5791 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5792 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5793 pool_.get(), NetLogWithSource()),
Matt Menkebf3c767d2019-04-15 23:28:245794 IsOk());
5795 ASSERT_TRUE(pool_->HasGroupForTesting(kOtherGroupId));
5796 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kOtherGroupId));
5797
David Benjaminbac8dff2019-08-07 01:30:415798 pool_->OnSSLConfigForServerChanged(HostPortPair("a", 443));
Matt Menkebf3c767d2019-04-15 23:28:245799
5800 handle.Reset();
5801 EXPECT_EQ(1, pool_->IdleSocketCount());
5802 ASSERT_TRUE(pool_->HasGroupForTesting(kOtherGroupId));
5803 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(kOtherGroupId));
5804}
5805
David Benjaminbac8dff2019-08-07 01:30:415806TEST_P(ClientSocketPoolBaseRefreshTest,
5807 RefreshGroupReplacesBoundConnectJobOnConnect) {
5808 CreatePoolForRefresh(1, 1);
5809 const ClientSocketPool::GroupId kGroupId = GetGroupId();
Matt Menkebf3c767d2019-04-15 23:28:245810 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5811
5812 TestAuthHelper auth_helper;
5813 auth_helper.InitHandle(params_, pool_.get(), DEFAULT_PRIORITY,
5814 ClientSocketPool::RespectLimits::ENABLED, kGroupId);
5815 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(kGroupId));
5816
5817 auth_helper.WaitForAuth();
5818
5819 // This should update the generation, but not cancel the old ConnectJob - it's
5820 // not safe to do anything while waiting on the original ConnectJob.
David Benjaminbac8dff2019-08-07 01:30:415821 OnSSLConfigForServerChanged();
Matt Menkebf3c767d2019-04-15 23:28:245822
5823 // Providing auth credentials and restarting the request with them will cause
5824 // the ConnectJob to complete successfully, but the result will be discarded
5825 // because of the generation mismatch.
5826 auth_helper.RestartWithAuth();
5827
5828 // Despite using ConnectJobs that simulate a single challenge, a second
5829 // challenge will be seen, due to using a new ConnectJob.
5830 auth_helper.WaitForAuth();
5831 auth_helper.RestartWithAuth();
5832
5833 EXPECT_THAT(auth_helper.WaitForResult(), IsOk());
5834 EXPECT_TRUE(auth_helper.handle()->socket());
5835 EXPECT_EQ(2, auth_helper.auth_count());
5836
5837 // When released, the socket will be returned to the socket pool, and
5838 // available for reuse.
5839 auth_helper.handle()->Reset();
5840 EXPECT_EQ(1, pool_->IdleSocketCount());
5841 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId));
5842 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(kGroupId));
5843}
5844
David Benjaminbac8dff2019-08-07 01:30:415845TEST_F(ClientSocketPoolBaseTest, RefreshProxyRefreshesAllGroups) {
5846 CreatePoolWithIdleTimeouts(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
5847 kUnusedIdleSocketTimeout,
5848 ClientSocketPool::used_idle_socket_timeout(),
5849 false /* no backup connect jobs */,
5850 ProxyServer::FromPacString("HTTPS myproxy:70"));
5851
5852 const ClientSocketPool::GroupId kGroupId1 =
5853 TestGroupId("a", 443, ClientSocketPool::SocketType::kSsl);
5854 const ClientSocketPool::GroupId kGroupId2 =
5855 TestGroupId("b", 443, ClientSocketPool::SocketType::kSsl);
5856 const ClientSocketPool::GroupId kGroupId3 =
5857 TestGroupId("c", 443, ClientSocketPool::SocketType::kSsl);
5858
5859 // Make three sockets in three different groups. The third socket is released
5860 // to the pool as idle.
5861 ClientSocketHandle handle1, handle2, handle3;
5862 TestCompletionCallback callback;
5863 EXPECT_THAT(
5864 handle1.Init(kGroupId1, params_, base::nullopt, DEFAULT_PRIORITY,
5865 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5866 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5867 pool_.get(), NetLogWithSource()),
5868 IsOk());
5869 EXPECT_THAT(
5870 handle2.Init(kGroupId2, params_, base::nullopt, DEFAULT_PRIORITY,
5871 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5872 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5873 pool_.get(), NetLogWithSource()),
5874 IsOk());
5875 EXPECT_THAT(
5876 handle3.Init(kGroupId3, params_, base::nullopt, DEFAULT_PRIORITY,
5877 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5878 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5879 pool_.get(), NetLogWithSource()),
5880 IsOk());
5881 handle3.Reset();
5882 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId1));
5883 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId1));
5884 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId2));
5885 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId2));
5886 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId3));
5887 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(kGroupId3));
5888
5889 // Changes to some other proxy do not affect the pool. The idle socket remains
5890 // alive and closing |handle2| makes the socket available for the pool.
5891 pool_->OnSSLConfigForServerChanged(HostPortPair("someotherproxy", 70));
5892
5893 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId1));
5894 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId1));
5895 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId2));
5896 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId2));
5897 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId3));
5898 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(kGroupId3));
5899
5900 handle2.Reset();
5901 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId2));
5902 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(kGroupId2));
5903
5904 // Changes to the matching proxy refreshes all groups.
5905 pool_->OnSSLConfigForServerChanged(HostPortPair("myproxy", 70));
5906
5907 // Idle sockets are closed.
5908 EXPECT_EQ(0, pool_->IdleSocketCount());
5909 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupId2));
5910 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupId3));
5911
5912 // The active socket, however, continues to be active.
5913 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId1));
5914 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId1));
5915
5916 // Closing it does not make it available for the pool.
5917 handle1.Reset();
5918 EXPECT_EQ(0, pool_->IdleSocketCount());
5919 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupId1));
5920}
5921
5922TEST_F(ClientSocketPoolBaseTest, RefreshBothPrivacyAndNormalSockets) {
5923 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
5924
5925 const ClientSocketPool::GroupId kGroupId =
5926 TestGroupId("a", 443, ClientSocketPool::SocketType::kSsl,
5927 PrivacyMode::PRIVACY_MODE_DISABLED);
5928 const ClientSocketPool::GroupId kGroupIdPrivacy =
5929 TestGroupId("a", 443, ClientSocketPool::SocketType::kSsl,
5930 PrivacyMode::PRIVACY_MODE_ENABLED);
5931 const ClientSocketPool::GroupId kOtherGroupId =
5932 TestGroupId("b", 443, ClientSocketPool::SocketType::kSsl);
5933
5934 // Make a socket in each groups.
5935 ClientSocketHandle handle1, handle2, handle3;
5936 TestCompletionCallback callback;
5937 EXPECT_THAT(
5938 handle1.Init(kGroupId, params_, base::nullopt, DEFAULT_PRIORITY,
5939 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5940 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5941 pool_.get(), NetLogWithSource()),
5942 IsOk());
5943 EXPECT_THAT(
5944 handle2.Init(kGroupIdPrivacy, params_, base::nullopt, DEFAULT_PRIORITY,
5945 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5946 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5947 pool_.get(), NetLogWithSource()),
5948 IsOk());
5949 EXPECT_THAT(
5950 handle3.Init(kOtherGroupId, params_, base::nullopt, DEFAULT_PRIORITY,
5951 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5952 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5953 pool_.get(), NetLogWithSource()),
5954 IsOk());
5955 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId));
5956 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId));
5957 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupIdPrivacy));
5958 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupIdPrivacy));
5959 ASSERT_TRUE(pool_->HasGroupForTesting(kOtherGroupId));
5960 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kOtherGroupId));
5961
5962 pool_->OnSSLConfigForServerChanged(HostPortPair("a", 443));
5963
5964 // Active sockets continue to be active.
5965 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId));
5966 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId));
5967 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupIdPrivacy));
5968 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupIdPrivacy));
5969 ASSERT_TRUE(pool_->HasGroupForTesting(kOtherGroupId));
5970 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kOtherGroupId));
5971
5972 // Closing them leaves kOtherGroupId alone, but kGroupId and kGroupIdPrivacy
5973 // are unusable.
5974 handle1.Reset();
5975 handle2.Reset();
5976 handle3.Reset();
5977 EXPECT_EQ(1, pool_->IdleSocketCount());
5978 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupId));
5979 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupIdPrivacy));
5980 EXPECT_TRUE(pool_->HasGroupForTesting(kOtherGroupId));
5981 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(kOtherGroupId));
5982}
5983
[email protected]f6d1d6eb2009-06-24 20:16:095984} // namespace
5985
5986} // namespace net