blob: bcdbd8e555fdd0afccdcbd65bdfbae30bcc0b59e [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"
[email protected]2041cf342010-02-19 03:15:5912#include "base/callback.h"
danakjdb9ae7942020-11-11 16:01:3513#include "base/callback_helpers.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"
Matt Menke4807a9a2020-11-21 00:14:4137#include "net/base/schemeful_site.h"
[email protected]f6d1d6eb2009-06-24 20:16:0938#include "net/base/test_completion_callback.h"
dalykedd30d982019-12-16 15:31:1039#include "net/dns/public/resolve_error_info.h"
[email protected]277d5942010-08-11 21:02:3540#include "net/http/http_response_headers.h"
Matt Menke39b7c5a2019-04-10 19:47:5141#include "net/http/http_response_info.h"
eroman87c53d62015-04-02 06:51:0742#include "net/log/net_log.h"
mikecirone8b85c432016-09-08 19:11:0043#include "net/log/net_log_event_type.h"
mikecironef22f9812016-10-04 03:40:1944#include "net/log/net_log_source.h"
mikecirone8b85c432016-09-08 19:11:0045#include "net/log/net_log_source_type.h"
mmenke16a7cbdd2015-04-24 23:00:5646#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4647#include "net/log/test_net_log_util.h"
[email protected]f6d1d6eb2009-06-24 20:16:0948#include "net/socket/client_socket_factory.h"
49#include "net/socket/client_socket_handle.h"
tfarina5dd13c22016-11-16 12:08:2650#include "net/socket/datagram_client_socket.h"
tbansalca83c002016-04-28 20:56:2851#include "net/socket/socket_performance_watcher.h"
Paul Jensen8d6f87ec2018-01-13 00:46:5452#include "net/socket/socket_tag.h"
[email protected]75439d3b2009-07-23 22:11:1753#include "net/socket/socket_test_util.h"
[email protected]18ccfdb2013-08-15 00:13:4454#include "net/socket/ssl_client_socket.h"
[email protected]3268023f2011-05-05 00:08:1055#include "net/socket/stream_socket.h"
Matt Menke9fa17d52019-03-25 19:12:2656#include "net/socket/transport_connect_job.h"
Matt Menke39b7c5a2019-04-10 19:47:5157#include "net/ssl/ssl_cert_request_info.h"
robpercival214763f2016-07-01 23:27:0158#include "net/test/gtest_util.h"
Gabriel Charettec7108742019-08-23 03:31:4059#include "net/test/test_with_task_environment.h"
Matt Menkef09e64c2019-04-23 22:16:2860#include "net/traffic_annotation/network_traffic_annotation.h"
Ramin Halavati0a08cc82018-02-06 07:46:3861#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
[email protected]51fdc7c2012-04-10 19:19:4862#include "testing/gmock/include/gmock/gmock.h"
[email protected]f6d1d6eb2009-06-24 20:16:0963#include "testing/gtest/include/gtest/gtest.h"
64
robpercival214763f2016-07-01 23:27:0165using net::test::IsError;
66using net::test::IsOk;
67
[email protected]51fdc7c2012-04-10 19:19:4868using ::testing::Invoke;
69using ::testing::Return;
70
[email protected]f6d1d6eb2009-06-24 20:16:0971namespace net {
72
73namespace {
74
[email protected]211d21722009-07-22 15:48:5375const int kDefaultMaxSockets = 4;
[email protected]c9d6a1d2009-07-14 16:15:2076const int kDefaultMaxSocketsPerGroup = 2;
Tarun Bansala7635092019-02-20 10:00:5977constexpr base::TimeDelta kUnusedIdleSocketTimeout =
78 base::TimeDelta::FromSeconds(10);
[email protected]0b7648c2009-07-06 20:14:0179
Matt Menkebdf777802019-04-22 19:38:5980ClientSocketPool::GroupId TestGroupId(
81 const std::string& host,
82 int port = 80,
83 ClientSocketPool::SocketType socket_type =
84 ClientSocketPool::SocketType::kHttp,
Matt Menke166443c2019-05-24 18:45:5985 PrivacyMode privacy_mode = PrivacyMode::PRIVACY_MODE_DISABLED,
86 NetworkIsolationKey network_isolation_key = NetworkIsolationKey()) {
dalyk5f48a132019-10-14 15:20:1987 bool disable_secure_dns = false;
Matt Menkec6b3edf72019-03-19 17:00:3988 return ClientSocketPool::GroupId(HostPortPair(host, port), socket_type,
dalyk5f48a132019-10-14 15:20:1989 privacy_mode, network_isolation_key,
90 disable_secure_dns);
Matt Menkec6b3edf72019-03-19 17:00:3991}
92
[email protected]034df0f32013-01-07 23:17:4893// Make sure |handle| sets load times correctly when it has been assigned a
94// reused socket.
95void TestLoadTimingInfoConnectedReused(const ClientSocketHandle& handle) {
96 LoadTimingInfo load_timing_info;
97 // Only pass true in as |is_reused|, as in general, HttpStream types should
98 // have stricter concepts of reuse than socket pools.
99 EXPECT_TRUE(handle.GetLoadTimingInfo(true, &load_timing_info));
100
101 EXPECT_EQ(true, load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19102 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]034df0f32013-01-07 23:17:48103
[email protected]b258e0792013-01-12 07:11:59104 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
105 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:48106}
107
108// Make sure |handle| sets load times correctly when it has been assigned a
[email protected]b021ece62013-06-11 11:06:33109// fresh socket. Also runs TestLoadTimingInfoConnectedReused, since the owner
[email protected]034df0f32013-01-07 23:17:48110// of a connection where |is_reused| is false may consider the connection
111// reused.
112void TestLoadTimingInfoConnectedNotReused(const ClientSocketHandle& handle) {
113 EXPECT_FALSE(handle.is_reused());
114
115 LoadTimingInfo load_timing_info;
116 EXPECT_TRUE(handle.GetLoadTimingInfo(false, &load_timing_info));
117
118 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19119 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]034df0f32013-01-07 23:17:48120
[email protected]b258e0792013-01-12 07:11:59121 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
122 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
123 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:48124
125 TestLoadTimingInfoConnectedReused(handle);
126}
127
128// Make sure |handle| sets load times correctly, in the case that it does not
129// currently have a socket.
130void TestLoadTimingInfoNotConnected(const ClientSocketHandle& handle) {
131 // Should only be set to true once a socket is assigned, if at all.
132 EXPECT_FALSE(handle.is_reused());
133
134 LoadTimingInfo load_timing_info;
135 EXPECT_FALSE(handle.GetLoadTimingInfo(false, &load_timing_info));
136
137 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19138 EXPECT_EQ(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]034df0f32013-01-07 23:17:48139
[email protected]b258e0792013-01-12 07:11:59140 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
141 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:48142}
143
[email protected]3268023f2011-05-05 00:08:10144class MockClientSocket : public StreamSocket {
[email protected]f6d1d6eb2009-06-24 20:16:09145 public:
[email protected]034df0f32013-01-07 23:17:48146 explicit MockClientSocket(net::NetLog* net_log)
147 : connected_(false),
[email protected]0dc88b32014-03-26 20:12:28148 has_unread_data_(false),
tfarina428341112016-09-22 13:38:20149 net_log_(NetLogWithSource::Make(net_log, NetLogSourceType::SOCKET)),
Charlie Harrison3e4c0622018-05-13 15:44:30150 was_used_to_convey_data_(false) {}
[email protected]f6d1d6eb2009-06-24 20:16:09151
[email protected]0dc88b32014-03-26 20:12:28152 // Sets whether the socket has unread data. If true, the next call to Read()
153 // will return 1 byte and IsConnectedAndIdle() will return false.
154 void set_has_unread_data(bool has_unread_data) {
155 has_unread_data_ = has_unread_data;
156 }
157
[email protected]3f55aa12011-12-07 02:03:33158 // Socket implementation.
dchengb03027d2014-10-21 12:00:20159 int Read(IOBuffer* /* buf */,
160 int len,
Brad Lassey3a814172018-04-26 03:30:21161 CompletionOnceCallback /* callback */) override {
[email protected]0dc88b32014-03-26 20:12:28162 if (has_unread_data_ && len > 0) {
163 has_unread_data_ = false;
164 was_used_to_convey_data_ = true;
165 return 1;
166 }
[email protected]e86df8dc2013-03-30 13:18:28167 return ERR_UNEXPECTED;
[email protected]3f55aa12011-12-07 02:03:33168 }
[email protected]ab838892009-06-30 18:49:05169
[email protected]a2b2cfc2017-12-06 09:06:08170 int Write(
171 IOBuffer* /* buf */,
172 int len,
Brad Lassey3a814172018-04-26 03:30:21173 CompletionOnceCallback /* callback */,
[email protected]a2b2cfc2017-12-06 09:06:08174 const NetworkTrafficAnnotationTag& /*traffic_annotation*/) override {
[email protected]0f873e82010-09-02 16:09:01175 was_used_to_convey_data_ = true;
176 return len;
[email protected]ab838892009-06-30 18:49:05177 }
Avi Drissman13fc8932015-12-20 04:40:46178 int SetReceiveBufferSize(int32_t size) override { return OK; }
179 int SetSendBufferSize(int32_t size) override { return OK; }
[email protected]ab838892009-06-30 18:49:05180
[email protected]dbf036f2011-12-06 23:33:24181 // StreamSocket implementation.
Brad Lassey3a814172018-04-26 03:30:21182 int Connect(CompletionOnceCallback callback) override {
[email protected]dbf036f2011-12-06 23:33:24183 connected_ = true;
184 return OK;
185 }
[email protected]f6d1d6eb2009-06-24 20:16:09186
dchengb03027d2014-10-21 12:00:20187 void Disconnect() override { connected_ = false; }
188 bool IsConnected() const override { return connected_; }
189 bool IsConnectedAndIdle() const override {
[email protected]0dc88b32014-03-26 20:12:28190 return connected_ && !has_unread_data_;
191 }
[email protected]0b7648c2009-07-06 20:14:01192
dchengb03027d2014-10-21 12:00:20193 int GetPeerAddress(IPEndPoint* /* address */) const override {
[email protected]9f864b32010-01-20 15:01:16194 return ERR_UNEXPECTED;
[email protected]f6d1d6eb2009-06-24 20:16:09195 }
[email protected]f6d1d6eb2009-06-24 20:16:09196
dchengb03027d2014-10-21 12:00:20197 int GetLocalAddress(IPEndPoint* /* address */) const override {
[email protected]e7f74da2011-04-19 23:49:35198 return ERR_UNEXPECTED;
199 }
200
tfarina428341112016-09-22 13:38:20201 const NetLogWithSource& NetLog() const override { return net_log_; }
[email protected]a2006ece2010-04-23 16:44:02202
dchengb03027d2014-10-21 12:00:20203 bool WasEverUsed() const override { return was_used_to_convey_data_; }
tfarina2846404c2016-12-25 14:31:37204 bool WasAlpnNegotiated() const override { return false; }
dchengb03027d2014-10-21 12:00:20205 NextProto GetNegotiatedProtocol() const override { return kProtoUnknown; }
206 bool GetSSLInfo(SSLInfo* ssl_info) override { return false; }
ttuttle23fdb7b2015-05-15 01:28:03207 void GetConnectionAttempts(ConnectionAttempts* out) const override {
208 out->clear();
209 }
210 void ClearConnectionAttempts() override {}
211 void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
tbansalf82cc8e2015-10-14 20:05:49212 int64_t GetTotalReceivedBytes() const override {
213 NOTIMPLEMENTED();
214 return 0;
215 }
Paul Jensen0f49dec2017-12-12 23:39:58216 void ApplySocketTag(const SocketTag& tag) override {}
[email protected]9b5614a2010-08-25 20:29:45217
[email protected]f6d1d6eb2009-06-24 20:16:09218 private:
219 bool connected_;
[email protected]0dc88b32014-03-26 20:12:28220 bool has_unread_data_;
tfarina428341112016-09-22 13:38:20221 NetLogWithSource net_log_;
[email protected]0f873e82010-09-02 16:09:01222 bool was_used_to_convey_data_;
[email protected]f6d1d6eb2009-06-24 20:16:09223
[email protected]ab838892009-06-30 18:49:05224 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
[email protected]f6d1d6eb2009-06-24 20:16:09225};
226
[email protected]5fc08e32009-07-15 17:09:57227class TestConnectJob;
228
[email protected]f6d1d6eb2009-06-24 20:16:09229class MockClientSocketFactory : public ClientSocketFactory {
230 public:
[email protected]ab838892009-06-30 18:49:05231 MockClientSocketFactory() : allocation_count_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:09232
danakj655b66c2016-04-16 00:51:38233 std::unique_ptr<DatagramClientSocket> CreateDatagramClientSocket(
[email protected]5370c012011-06-29 03:47:04234 DatagramSocket::BindType bind_type,
[email protected]98b0e582011-06-22 14:31:41235 NetLog* net_log,
mikecironef22f9812016-10-04 03:40:19236 const NetLogSource& source) override {
[email protected]98b0e582011-06-22 14:31:41237 NOTREACHED();
David Benjamin24725be2019-07-24 20:57:18238 return nullptr;
[email protected]98b0e582011-06-22 14:31:41239 }
240
Helen Lid5bb9222018-04-12 15:33:09241 std::unique_ptr<TransportClientSocket> CreateTransportClientSocket(
[email protected]0a0b7682010-08-25 17:08:07242 const AddressList& addresses,
danakj655b66c2016-04-16 00:51:38243 std::unique_ptr<
244 SocketPerformanceWatcher> /* socket_performance_watcher */,
Eric Roman2bc77162020-09-16 18:30:45245 NetworkQualityEstimator* /* network_quality_estimator */,
[email protected]0a0b7682010-08-25 17:08:07246 NetLog* /* net_log */,
mikecironef22f9812016-10-04 03:40:19247 const NetLogSource& /*source*/) override {
[email protected]f6d1d6eb2009-06-24 20:16:09248 allocation_count_++;
Helen Lid5bb9222018-04-12 15:33:09249 return nullptr;
[email protected]f6d1d6eb2009-06-24 20:16:09250 }
251
danakj655b66c2016-04-16 00:51:38252 std::unique_ptr<SSLClientSocket> CreateSSLClientSocket(
David Benjamin24725be2019-07-24 20:57:18253 SSLClientContext* context,
Matt Menke841fc412019-03-05 23:20:12254 std::unique_ptr<StreamSocket> stream_socket,
[email protected]4f4de7e62010-11-12 19:55:27255 const HostPortPair& host_and_port,
David Benjamin24725be2019-07-24 20:57:18256 const SSLConfig& ssl_config) override {
[email protected]f6d1d6eb2009-06-24 20:16:09257 NOTIMPLEMENTED();
David Benjamin24725be2019-07-24 20:57:18258 return nullptr;
[email protected]f6d1d6eb2009-06-24 20:16:09259 }
Matt Menkefd956922019-02-04 23:44:03260
Matt Menke52cd95a2019-02-08 06:16:27261 std::unique_ptr<ProxyClientSocket> CreateProxyClientSocket(
262 std::unique_ptr<StreamSocket> stream_socket,
263 const std::string& user_agent,
264 const HostPortPair& endpoint,
265 const ProxyServer& proxy_server,
266 HttpAuthController* http_auth_controller,
267 bool tunnel,
268 bool using_spdy,
269 NextProto negotiated_protocol,
270 ProxyDelegate* proxy_delegate,
Matt Menke52cd95a2019-02-08 06:16:27271 const NetworkTrafficAnnotationTag& traffic_annotation) override {
272 NOTIMPLEMENTED();
273 return nullptr;
274 }
275
[email protected]5fc08e32009-07-15 17:09:57276 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
[email protected]03b7c8c2013-07-20 04:38:55277
[email protected]5fc08e32009-07-15 17:09:57278 void SignalJobs();
279
[email protected]03b7c8c2013-07-20 04:38:55280 void SignalJob(size_t job);
281
282 void SetJobLoadState(size_t job, LoadState load_state);
283
Matt Menke141b87f22019-01-30 02:43:03284 // Sets the HasConnectionEstablished value of the specified job to true,
285 // without invoking the callback.
286 void SetJobHasEstablishedConnection(size_t job);
287
[email protected]f6d1d6eb2009-06-24 20:16:09288 int allocation_count() const { return allocation_count_; }
289
[email protected]f6d1d6eb2009-06-24 20:16:09290 private:
291 int allocation_count_;
[email protected]5fc08e32009-07-15 17:09:57292 std::vector<TestConnectJob*> waiting_jobs_;
[email protected]f6d1d6eb2009-06-24 20:16:09293};
294
[email protected]ab838892009-06-30 18:49:05295class TestConnectJob : public ConnectJob {
296 public:
297 enum JobType {
298 kMockJob,
299 kMockFailingJob,
300 kMockPendingJob,
301 kMockPendingFailingJob,
[email protected]5fc08e32009-07-15 17:09:57302 kMockWaitingJob,
Matt Menkeb57663b32019-03-01 17:17:10303
304 // Certificate errors return a socket in addition to an error code.
305 kMockCertErrorJob,
306 kMockPendingCertErrorJob,
307
[email protected]e60e47a2010-07-14 03:37:18308 kMockAdditionalErrorStateJob,
309 kMockPendingAdditionalErrorStateJob,
[email protected]0dc88b32014-03-26 20:12:28310 kMockUnreadDataJob,
Matt Menkeb57663b32019-03-01 17:17:10311
312 kMockAuthChallengeOnceJob,
313 kMockAuthChallengeTwiceJob,
314 kMockAuthChallengeOnceFailingJob,
315 kMockAuthChallengeTwiceFailingJob,
[email protected]ab838892009-06-30 18:49:05316 };
317
[email protected]994d4932010-07-12 17:55:13318 // The kMockPendingJob uses a slight delay before allowing the connect
319 // to complete.
320 static const int kPendingConnectDelay = 2;
321
[email protected]ab838892009-06-30 18:49:05322 TestConnectJob(JobType job_type,
Matt Menke16f5c2e52019-03-25 21:50:40323 RequestPriority request_priority,
324 SocketTag socket_tag,
[email protected]974ebd62009-08-03 23:14:34325 base::TimeDelta timeout_duration,
Matt Menkea6f99ad2019-03-08 02:26:43326 const CommonConnectJobParams* common_connect_job_params,
[email protected]ab838892009-06-30 18:49:05327 ConnectJob::Delegate* delegate,
Matt Menkea6f99ad2019-03-08 02:26:43328 MockClientSocketFactory* client_socket_factory)
Matt Menke16f5c2e52019-03-25 21:50:40329 : ConnectJob(request_priority,
330 socket_tag,
Matt Menke1a6c92d2019-02-23 00:25:38331 timeout_duration,
Matt Menkea6f99ad2019-03-08 02:26:43332 common_connect_job_params,
Matt Menke1a6c92d2019-02-23 00:25:38333 delegate,
334 nullptr /* net_log */,
335 NetLogSourceType::TRANSPORT_CONNECT_JOB,
336 NetLogEventType::TRANSPORT_CONNECT_JOB_CONNECT),
[email protected]2ab05b52009-07-01 23:57:58337 job_type_(job_type),
[email protected]ab838892009-06-30 18:49:05338 client_socket_factory_(client_socket_factory),
[email protected]e60e47a2010-07-14 03:37:18339 load_state_(LOAD_STATE_IDLE),
Matt Menke141b87f22019-01-30 02:43:03340 has_established_connection_(false),
Jeremy Romand54000b22019-07-08 18:40:16341 store_additional_error_state_(false) {}
[email protected]ab838892009-06-30 18:49:05342
[email protected]974ebd62009-08-03 23:14:34343 void Signal() {
[email protected]e772db3f2010-07-12 18:11:13344 DoConnect(waiting_success_, true /* async */, false /* recoverable */);
[email protected]974ebd62009-08-03 23:14:34345 }
346
[email protected]03b7c8c2013-07-20 04:38:55347 void set_load_state(LoadState load_state) { load_state_ = load_state; }
348
Matt Menke141b87f22019-01-30 02:43:03349 void set_has_established_connection() {
350 DCHECK(!has_established_connection_);
351 has_established_connection_ = true;
352 }
353
[email protected]03b7c8c2013-07-20 04:38:55354 // From ConnectJob:
355
dchengb03027d2014-10-21 12:00:20356 LoadState GetLoadState() const override { return load_state_; }
[email protected]46451352009-09-01 14:54:21357
Matt Menke141b87f22019-01-30 02:43:03358 bool HasEstablishedConnection() const override {
359 return has_established_connection_;
360 }
361
dalykedd30d982019-12-16 15:31:10362 ResolveErrorInfo GetResolveErrorInfo() const override {
363 return ResolveErrorInfo(OK);
364 }
365
Matt Menke6f84d1f12019-04-11 19:26:47366 bool IsSSLError() const override { return store_additional_error_state_; }
367
368 scoped_refptr<SSLCertRequestInfo> GetCertRequestInfo() override {
369 if (store_additional_error_state_)
370 return base::MakeRefCounted<SSLCertRequestInfo>();
371 return nullptr;
[email protected]e60e47a2010-07-14 03:37:18372 }
373
[email protected]974ebd62009-08-03 23:14:34374 private:
[email protected]03b7c8c2013-07-20 04:38:55375 // From ConnectJob:
[email protected]ab838892009-06-30 18:49:05376
dchengb03027d2014-10-21 12:00:20377 int ConnectInternal() override {
[email protected]ab838892009-06-30 18:49:05378 AddressList ignored;
Raul Tambre94493c652019-03-11 17:18:35379 client_socket_factory_->CreateTransportClientSocket(
Eric Roman2bc77162020-09-16 18:30:45380 ignored, nullptr, nullptr, nullptr, NetLogSource());
[email protected]ab838892009-06-30 18:49:05381 switch (job_type_) {
382 case kMockJob:
[email protected]e772db3f2010-07-12 18:11:13383 return DoConnect(true /* successful */, false /* sync */,
Matt Menkeb57663b32019-03-01 17:17:10384 false /* cert_error */);
[email protected]ab838892009-06-30 18:49:05385 case kMockFailingJob:
[email protected]e772db3f2010-07-12 18:11:13386 return DoConnect(false /* error */, false /* sync */,
Matt Menkeb57663b32019-03-01 17:17:10387 false /* cert_error */);
[email protected]ab838892009-06-30 18:49:05388 case kMockPendingJob:
[email protected]5fc08e32009-07-15 17:09:57389 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47390
391 // Depending on execution timings, posting a delayed task can result
392 // in the task getting executed the at the earliest possible
393 // opportunity or only after returning once from the message loop and
394 // then a second call into the message loop. In order to make behavior
395 // more deterministic, we change the default delay to 2ms. This should
396 // always require us to wait for the second call into the message loop.
397 //
398 // N.B. The correct fix for this and similar timing problems is to
399 // abstract time for the purpose of unittests. Unfortunately, we have
400 // a lot of third-party components that directly call the various
401 // time functions, so this change would be rather invasive.
skyostil4891b25b2015-06-11 11:43:45402 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05403 FROM_HERE,
kylecharf4fe5172019-02-15 18:53:49404 base::BindOnce(base::IgnoreResult(&TestConnectJob::DoConnect),
405 weak_factory_.GetWeakPtr(), true /* successful */,
Matt Menkeb57663b32019-03-01 17:17:10406 true /* async */, false /* cert_error */),
[email protected]5761ab9c2012-02-04 16:44:53407 base::TimeDelta::FromMilliseconds(kPendingConnectDelay));
[email protected]ab838892009-06-30 18:49:05408 return ERR_IO_PENDING;
409 case kMockPendingFailingJob:
[email protected]5fc08e32009-07-15 17:09:57410 set_load_state(LOAD_STATE_CONNECTING);
skyostil4891b25b2015-06-11 11:43:45411 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05412 FROM_HERE,
kylecharf4fe5172019-02-15 18:53:49413 base::BindOnce(base::IgnoreResult(&TestConnectJob::DoConnect),
414 weak_factory_.GetWeakPtr(), false /* error */,
Matt Menkeb57663b32019-03-01 17:17:10415 true /* async */, false /* cert_error */),
[email protected]5761ab9c2012-02-04 16:44:53416 base::TimeDelta::FromMilliseconds(2));
[email protected]ab838892009-06-30 18:49:05417 return ERR_IO_PENDING;
[email protected]5fc08e32009-07-15 17:09:57418 case kMockWaitingJob:
[email protected]03b7c8c2013-07-20 04:38:55419 set_load_state(LOAD_STATE_CONNECTING);
[email protected]5fc08e32009-07-15 17:09:57420 client_socket_factory_->WaitForSignal(this);
421 waiting_success_ = true;
422 return ERR_IO_PENDING;
Matt Menkeb57663b32019-03-01 17:17:10423 case kMockCertErrorJob:
[email protected]e772db3f2010-07-12 18:11:13424 return DoConnect(false /* error */, false /* sync */,
Matt Menkeb57663b32019-03-01 17:17:10425 true /* cert_error */);
426 case kMockPendingCertErrorJob:
[email protected]e772db3f2010-07-12 18:11:13427 set_load_state(LOAD_STATE_CONNECTING);
skyostil4891b25b2015-06-11 11:43:45428 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]e772db3f2010-07-12 18:11:13429 FROM_HERE,
kylecharf4fe5172019-02-15 18:53:49430 base::BindOnce(base::IgnoreResult(&TestConnectJob::DoConnect),
431 weak_factory_.GetWeakPtr(), false /* error */,
Matt Menkeb57663b32019-03-01 17:17:10432 true /* async */, true /* cert_error */),
[email protected]5761ab9c2012-02-04 16:44:53433 base::TimeDelta::FromMilliseconds(2));
[email protected]e772db3f2010-07-12 18:11:13434 return ERR_IO_PENDING;
[email protected]e60e47a2010-07-14 03:37:18435 case kMockAdditionalErrorStateJob:
436 store_additional_error_state_ = true;
437 return DoConnect(false /* error */, false /* sync */,
Matt Menkeb57663b32019-03-01 17:17:10438 false /* cert_error */);
[email protected]e60e47a2010-07-14 03:37:18439 case kMockPendingAdditionalErrorStateJob:
440 set_load_state(LOAD_STATE_CONNECTING);
441 store_additional_error_state_ = true;
skyostil4891b25b2015-06-11 11:43:45442 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]e60e47a2010-07-14 03:37:18443 FROM_HERE,
kylecharf4fe5172019-02-15 18:53:49444 base::BindOnce(base::IgnoreResult(&TestConnectJob::DoConnect),
445 weak_factory_.GetWeakPtr(), false /* error */,
Matt Menkeb57663b32019-03-01 17:17:10446 true /* async */, false /* cert_error */),
[email protected]5761ab9c2012-02-04 16:44:53447 base::TimeDelta::FromMilliseconds(2));
[email protected]e60e47a2010-07-14 03:37:18448 return ERR_IO_PENDING;
[email protected]0dc88b32014-03-26 20:12:28449 case kMockUnreadDataJob: {
450 int ret = DoConnect(true /* successful */, false /* sync */,
Matt Menkeb57663b32019-03-01 17:17:10451 false /* cert_error */);
[email protected]0dc88b32014-03-26 20:12:28452 static_cast<MockClientSocket*>(socket())->set_has_unread_data(true);
453 return ret;
454 }
Matt Menkeb57663b32019-03-01 17:17:10455 case kMockAuthChallengeOnceJob:
Matt Menke4b69f932019-03-04 16:20:01456 set_load_state(LOAD_STATE_CONNECTING);
Matt Menkeb57663b32019-03-01 17:17:10457 DoAdvanceAuthChallenge(1, true /* succeed_after_last_challenge */);
458 return ERR_IO_PENDING;
459 case kMockAuthChallengeTwiceJob:
Matt Menke4b69f932019-03-04 16:20:01460 set_load_state(LOAD_STATE_CONNECTING);
Matt Menkeb57663b32019-03-01 17:17:10461 DoAdvanceAuthChallenge(2, true /* succeed_after_last_challenge */);
462 return ERR_IO_PENDING;
463 case kMockAuthChallengeOnceFailingJob:
Matt Menke4b69f932019-03-04 16:20:01464 set_load_state(LOAD_STATE_CONNECTING);
Matt Menkeb57663b32019-03-01 17:17:10465 DoAdvanceAuthChallenge(1, false /* succeed_after_last_challenge */);
466 return ERR_IO_PENDING;
467 case kMockAuthChallengeTwiceFailingJob:
Matt Menke4b69f932019-03-04 16:20:01468 set_load_state(LOAD_STATE_CONNECTING);
Matt Menkeb57663b32019-03-01 17:17:10469 DoAdvanceAuthChallenge(2, false /* succeed_after_last_challenge */);
470 return ERR_IO_PENDING;
[email protected]ab838892009-06-30 18:49:05471 default:
472 NOTREACHED();
danakj655b66c2016-04-16 00:51:38473 SetSocket(std::unique_ptr<StreamSocket>());
[email protected]ab838892009-06-30 18:49:05474 return ERR_FAILED;
475 }
476 }
477
Lily Chen02ef29a2018-11-30 16:31:43478 void ChangePriorityInternal(RequestPriority priority) override {}
479
Matt Menkeb57663b32019-03-01 17:17:10480 int DoConnect(bool succeed, bool was_async, bool cert_error) {
[email protected]e772db3f2010-07-12 18:11:13481 int result = OK;
Matt Menke141b87f22019-01-30 02:43:03482 has_established_connection_ = true;
[email protected]ab838892009-06-30 18:49:05483 if (succeed) {
Matt Menkeb57663b32019-03-01 17:17:10484 SetSocket(std::make_unique<MockClientSocket>(net_log().net_log()));
Bence Békybdbb0e72018-08-07 21:42:59485 socket()->Connect(CompletionOnceCallback());
Matt Menkeb57663b32019-03-01 17:17:10486 } else if (cert_error) {
487 SetSocket(std::make_unique<MockClientSocket>(net_log().net_log()));
488 result = ERR_CERT_COMMON_NAME_INVALID;
[email protected]6e713f02009-08-06 02:56:40489 } else {
[email protected]e772db3f2010-07-12 18:11:13490 result = ERR_CONNECTION_FAILED;
danakj655b66c2016-04-16 00:51:38491 SetSocket(std::unique_ptr<StreamSocket>());
[email protected]ab838892009-06-30 18:49:05492 }
[email protected]2ab05b52009-07-01 23:57:58493
494 if (was_async)
[email protected]fd7b7c92009-08-20 19:38:30495 NotifyDelegateOfCompletion(result);
[email protected]ab838892009-06-30 18:49:05496 return result;
497 }
498
Matt Menkeb57663b32019-03-01 17:17:10499 void DoAdvanceAuthChallenge(int remaining_challenges,
500 bool succeed_after_last_challenge) {
501 base::ThreadTaskRunnerHandle::Get()->PostTask(
502 FROM_HERE,
503 base::BindOnce(&TestConnectJob::InvokeNextProxyAuthCallback,
504 weak_factory_.GetWeakPtr(), remaining_challenges,
505 succeed_after_last_challenge));
506 }
507
508 void InvokeNextProxyAuthCallback(int remaining_challenges,
509 bool succeed_after_last_challenge) {
Matt Menke4b69f932019-03-04 16:20:01510 set_load_state(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL);
Matt Menkeb57663b32019-03-01 17:17:10511 if (remaining_challenges == 0) {
512 DoConnect(succeed_after_last_challenge, true /* was_async */,
513 false /* cert_error */);
514 return;
515 }
516
517 // Integration tests make sure HttpResponseInfo and HttpAuthController work.
518 // The auth tests here are just focused on ConnectJob bookkeeping.
519 HttpResponseInfo info;
520 NotifyDelegateOfProxyAuth(
521 info, nullptr /* http_auth_controller */,
522 base::BindOnce(&TestConnectJob::DoAdvanceAuthChallenge,
523 weak_factory_.GetWeakPtr(), remaining_challenges - 1,
524 succeed_after_last_challenge));
525 }
526
[email protected]5fc08e32009-07-15 17:09:57527 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05528 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57529 MockClientSocketFactory* const client_socket_factory_;
[email protected]46451352009-09-01 14:54:21530 LoadState load_state_;
Matt Menke141b87f22019-01-30 02:43:03531 bool has_established_connection_;
[email protected]e60e47a2010-07-14 03:37:18532 bool store_additional_error_state_;
[email protected]ab838892009-06-30 18:49:05533
Jeremy Romand54000b22019-07-08 18:40:16534 base::WeakPtrFactory<TestConnectJob> weak_factory_{this};
[email protected]d5492c52013-11-10 20:44:39535
[email protected]ab838892009-06-30 18:49:05536 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
537};
538
[email protected]d80a4322009-08-14 07:07:49539class TestConnectJobFactory
Matt Menke16f5c2e52019-03-25 21:50:40540 : public TransportClientSocketPool::ConnectJobFactory {
[email protected]ab838892009-06-30 18:49:05541 public:
[email protected]034df0f32013-01-07 23:17:48542 TestConnectJobFactory(MockClientSocketFactory* client_socket_factory,
543 NetLog* net_log)
Matt Menkea6f99ad2019-03-08 02:26:43544 : common_connect_job_params_(
545 nullptr /* client_socket_factory */,
546 nullptr /* host_resolver */,
Matt Menkeb88837e2019-03-20 11:50:40547 nullptr /* http_auth_cache */,
548 nullptr /* http_auth_handler_factory */,
549 nullptr /* spdy_session_pool */,
Matt Menkeb5fb42b2019-03-22 17:26:13550 nullptr /* quic_supported_versions */,
Matt Menkeb88837e2019-03-20 11:50:40551 nullptr /* quic_stream_factory */,
Matt Menkea6f99ad2019-03-08 02:26:43552 nullptr /* proxy_delegate */,
Matt Menked732ea42019-03-08 12:05:00553 nullptr /* http_user_agent_settings */,
David Benjamin24725be2019-07-24 20:57:18554 nullptr /* ssl_client_context */,
Matt Menkea6f99ad2019-03-08 02:26:43555 nullptr /* socket_performance_watcher_factory */,
556 nullptr /* network_quality_estimator */,
557 net_log,
558 nullptr /* websocket_endpoint_lock_manager */),
559 job_type_(TestConnectJob::kMockJob),
Raul Tambre94493c652019-03-11 17:18:35560 job_types_(nullptr),
Matt Menkea6f99ad2019-03-08 02:26:43561 client_socket_factory_(client_socket_factory) {}
[email protected]ab838892009-06-30 18:49:05562
Chris Watkins7a41d3552017-12-01 02:13:27563 ~TestConnectJobFactory() override = default;
[email protected]ab838892009-06-30 18:49:05564
565 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
566
[email protected]51fdc7c2012-04-10 19:19:48567 void set_job_types(std::list<TestConnectJob::JobType>* job_types) {
568 job_types_ = job_types;
569 CHECK(!job_types_->empty());
570 }
571
[email protected]974ebd62009-08-03 23:14:34572 void set_timeout_duration(base::TimeDelta timeout_duration) {
573 timeout_duration_ = timeout_duration;
574 }
575
[email protected]3f55aa12011-12-07 02:03:33576 // ConnectJobFactory implementation.
[email protected]83039bb2011-12-09 18:43:55577
danakj655b66c2016-04-16 00:51:38578 std::unique_ptr<ConnectJob> NewConnectJob(
Matt Menkeaafff542019-04-22 22:09:36579 ClientSocketPool::GroupId group_id,
580 scoped_refptr<ClientSocketPool::SocketParams> socket_params,
Matt Menkef09e64c2019-04-23 22:16:28581 const base::Optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
Matt Menke16f5c2e52019-03-25 21:50:40582 RequestPriority request_priority,
583 SocketTag socket_tag,
mostynbba063d6032014-10-09 11:01:13584 ConnectJob::Delegate* delegate) const override {
[email protected]51fdc7c2012-04-10 19:19:48585 EXPECT_TRUE(!job_types_ || !job_types_->empty());
586 TestConnectJob::JobType job_type = job_type_;
587 if (job_types_ && !job_types_->empty()) {
588 job_type = job_types_->front();
589 job_types_->pop_front();
590 }
Matt Menkea6f99ad2019-03-08 02:26:43591 return std::make_unique<TestConnectJob>(
Matt Menke16f5c2e52019-03-25 21:50:40592 job_type, request_priority, socket_tag, timeout_duration_,
593 &common_connect_job_params_, delegate, client_socket_factory_);
[email protected]ab838892009-06-30 18:49:05594 }
595
596 private:
Matt Menkea6f99ad2019-03-08 02:26:43597 const CommonConnectJobParams common_connect_job_params_;
[email protected]ab838892009-06-30 18:49:05598 TestConnectJob::JobType job_type_;
[email protected]51fdc7c2012-04-10 19:19:48599 std::list<TestConnectJob::JobType>* job_types_;
[email protected]974ebd62009-08-03 23:14:34600 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57601 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05602
603 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
604};
605
[email protected]a937a06d2009-08-19 21:19:24606} // namespace
607
[email protected]a937a06d2009-08-19 21:19:24608namespace {
609
[email protected]5fc08e32009-07-15 17:09:57610void MockClientSocketFactory::SignalJobs() {
jdoerrie22a91d8b92018-10-05 08:43:26611 for (auto it = waiting_jobs_.begin(); it != waiting_jobs_.end(); ++it) {
[email protected]5fc08e32009-07-15 17:09:57612 (*it)->Signal();
613 }
614 waiting_jobs_.clear();
615}
616
[email protected]03b7c8c2013-07-20 04:38:55617void MockClientSocketFactory::SignalJob(size_t job) {
618 ASSERT_LT(job, waiting_jobs_.size());
619 waiting_jobs_[job]->Signal();
620 waiting_jobs_.erase(waiting_jobs_.begin() + job);
621}
622
623void MockClientSocketFactory::SetJobLoadState(size_t job,
624 LoadState load_state) {
625 ASSERT_LT(job, waiting_jobs_.size());
626 waiting_jobs_[job]->set_load_state(load_state);
627}
628
Matt Menke141b87f22019-01-30 02:43:03629void MockClientSocketFactory::SetJobHasEstablishedConnection(size_t job) {
630 ASSERT_LT(job, waiting_jobs_.size());
631 waiting_jobs_[job]->set_has_established_connection();
632}
633
Gabriel Charette694c3c332019-08-19 14:53:05634class ClientSocketPoolBaseTest : public TestWithTaskEnvironment {
[email protected]f6d1d6eb2009-06-24 20:16:09635 protected:
Alex Clarke0def2092018-12-10 12:01:45636 ClientSocketPoolBaseTest()
Gabriel Charette694c3c332019-08-19 14:53:05637 : TestWithTaskEnvironment(
638 base::test::TaskEnvironment::TimeSource::MOCK_TIME),
Matt Menke870e19ab2019-04-23 16:23:03639 params_(ClientSocketPool::SocketParams::CreateForHttpForTesting()) {
[email protected]636b8252011-04-08 19:56:54640 connect_backup_jobs_enabled_ =
Matt Menke16f5c2e52019-03-25 21:50:40641 TransportClientSocketPool::connect_backup_jobs_enabled();
642 TransportClientSocketPool::set_connect_backup_jobs_enabled(true);
[email protected]636b8252011-04-08 19:56:54643 }
[email protected]2431756e2010-09-29 20:26:13644
dcheng67be2b1f2014-10-27 21:47:29645 ~ClientSocketPoolBaseTest() override {
Matt Menke16f5c2e52019-03-25 21:50:40646 TransportClientSocketPool::set_connect_backup_jobs_enabled(
[email protected]636b8252011-04-08 19:56:54647 connect_backup_jobs_enabled_);
648 }
[email protected]c9d6a1d2009-07-14 16:15:20649
Matt Menke9fa17d52019-03-25 19:12:26650 void CreatePool(int max_sockets,
651 int max_sockets_per_group,
652 bool enable_backup_connect_jobs = false) {
Tarun Bansala7635092019-02-20 10:00:59653 CreatePoolWithIdleTimeouts(max_sockets, max_sockets_per_group,
654 kUnusedIdleSocketTimeout,
Matt Menke9fa17d52019-03-25 19:12:26655 ClientSocketPool::used_idle_socket_timeout(),
656 enable_backup_connect_jobs);
[email protected]9bf28db2009-08-29 01:35:16657 }
658
David Benjaminbac8dff2019-08-07 01:30:41659 void CreatePoolWithIdleTimeouts(
660 int max_sockets,
661 int max_sockets_per_group,
662 base::TimeDelta unused_idle_socket_timeout,
663 base::TimeDelta used_idle_socket_timeout,
664 bool enable_backup_connect_jobs = false,
665 ProxyServer proxy_server = ProxyServer::Direct()) {
[email protected]c9d6a1d2009-07-14 16:15:20666 DCHECK(!pool_.get());
Matt Menke9fa17d52019-03-25 19:12:26667 std::unique_ptr<TestConnectJobFactory> connect_job_factory =
668 std::make_unique<TestConnectJobFactory>(&client_socket_factory_,
669 &net_log_);
670 connect_job_factory_ = connect_job_factory.get();
671 pool_ = TransportClientSocketPool::CreateForTesting(
672 max_sockets, max_sockets_per_group, unused_idle_socket_timeout,
David Benjaminbac8dff2019-08-07 01:30:41673 used_idle_socket_timeout, proxy_server, std::move(connect_job_factory),
Matt Menke9fa17d52019-03-25 19:12:26674 nullptr /* ssl_config_service */, enable_backup_connect_jobs);
[email protected]c9d6a1d2009-07-14 16:15:20675 }
[email protected]f6d1d6eb2009-06-24 20:16:09676
mmenked3641e12016-01-28 16:06:15677 int StartRequestWithIgnoreLimits(
Matt Menkec6b3edf72019-03-19 17:00:39678 const ClientSocketPool::GroupId& group_id,
[email protected]b021ece62013-06-11 11:06:33679 RequestPriority priority,
mmenked3641e12016-01-28 16:06:15680 ClientSocketPool::RespectLimits respect_limits) {
Matt Menkec6b3edf72019-03-19 17:00:39681 return test_base_.StartRequestUsingPool(pool_.get(), group_id, priority,
mmenked3641e12016-01-28 16:06:15682 respect_limits, params_);
[email protected]b021ece62013-06-11 11:06:33683 }
684
Matt Menkec6b3edf72019-03-19 17:00:39685 int StartRequest(const ClientSocketPool::GroupId& group_id,
686 RequestPriority priority) {
mmenked3641e12016-01-28 16:06:15687 return StartRequestWithIgnoreLimits(
Matt Menkec6b3edf72019-03-19 17:00:39688 group_id, priority, ClientSocketPool::RespectLimits::ENABLED);
[email protected]f6d1d6eb2009-06-24 20:16:09689 }
690
[email protected]2431756e2010-09-29 20:26:13691 int GetOrderOfRequest(size_t index) const {
692 return test_base_.GetOrderOfRequest(index);
[email protected]f6d1d6eb2009-06-24 20:16:09693 }
694
[email protected]2431756e2010-09-29 20:26:13695 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
696 return test_base_.ReleaseOneConnection(keep_alive);
697 }
698
699 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
700 test_base_.ReleaseAllConnections(keep_alive);
701 }
702
Matt Menke433de6d2020-03-04 00:24:11703 // Expects a single NetLogEventType::SOCKET_POOL_CLOSING_SOCKET in |net_log_|.
704 // It should be logged for the provided source and have the indicated reason.
705 void ExpectSocketClosedWithReason(NetLogSource expected_source,
706 const char* expected_reason) {
707 auto entries = net_log_.GetEntriesForSourceWithType(
708 expected_source, NetLogEventType::SOCKET_POOL_CLOSING_SOCKET,
709 NetLogEventPhase::NONE);
710 ASSERT_EQ(1u, entries.size());
711 ASSERT_TRUE(entries[0].HasParams());
712 ASSERT_TRUE(entries[0].params.is_dict());
713 const std::string* reason = entries[0].params.FindStringKey("reason");
714 ASSERT_TRUE(reason);
715 EXPECT_EQ(expected_reason, *reason);
716 }
717
[email protected]2431756e2010-09-29 20:26:13718 TestSocketRequest* request(int i) { return test_base_.request(i); }
719 size_t requests_size() const { return test_base_.requests_size(); }
danakj655b66c2016-04-16 00:51:38720 std::vector<std::unique_ptr<TestSocketRequest>>* requests() {
olli.raula9d66b7d2015-11-23 08:30:42721 return test_base_.requests();
722 }
rdsmith29dbad12017-02-17 02:22:18723 // Only counts the requests that get sockets asynchronously;
724 // synchronous completions are not registered by this count.
[email protected]2431756e2010-09-29 20:26:13725 size_t completion_count() const { return test_base_.completion_count(); }
726
Matt Muellerd9342e3a2019-11-26 01:41:14727 RecordingTestNetLog net_log_;
[email protected]636b8252011-04-08 19:56:54728 bool connect_backup_jobs_enabled_;
[email protected]f6d1d6eb2009-06-24 20:16:09729 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04730 TestConnectJobFactory* connect_job_factory_;
Matt Menke9fa17d52019-03-25 19:12:26731 // These parameters are never actually used to create a TransportConnectJob.
Matt Menke84d11e562019-03-27 00:11:19732 scoped_refptr<ClientSocketPool::SocketParams> params_;
Matt Menke9fa17d52019-03-25 19:12:26733 std::unique_ptr<TransportClientSocketPool> pool_;
[email protected]2431756e2010-09-29 20:26:13734 ClientSocketPoolTest test_base_;
[email protected]f6d1d6eb2009-06-24 20:16:09735};
736
[email protected]5fc08e32009-07-15 17:09:57737TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53738 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20739
[email protected]6ecf2b92011-12-15 01:14:52740 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06741 ClientSocketHandle handle;
Matt Muellerd9342e3a2019-11-26 01:41:14742 RecordingBoundTestNetLog log;
[email protected]034df0f32013-01-07 23:17:48743 TestLoadTimingInfoNotConnected(handle);
[email protected]9e743cd2010-03-16 07:03:53744
Matt Menkef09e64c2019-04-23 22:16:28745 EXPECT_EQ(OK, handle.Init(
746 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
747 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
748 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
749 pool_.get(), log.bound()));
[email protected]f6d1d6eb2009-06-24 20:16:09750 EXPECT_TRUE(handle.is_initialized());
751 EXPECT_TRUE(handle.socket());
[email protected]034df0f32013-01-07 23:17:48752 TestLoadTimingInfoConnectedNotReused(handle);
753
[email protected]f6d1d6eb2009-06-24 20:16:09754 handle.Reset();
[email protected]034df0f32013-01-07 23:17:48755 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:30756
Eric Roman79cc7552019-07-19 02:17:54757 auto entries = log.GetEntries();
[email protected]b2fcd0e2010-12-01 15:19:40758
Matt Menke9fa17d52019-03-25 19:12:26759 EXPECT_EQ(5u, entries.size());
[email protected]9e743cd2010-03-16 07:03:53760 EXPECT_TRUE(LogContainsEvent(
Matt Menke9fa17d52019-03-25 19:12:26761 entries, 0, NetLogEventType::TCP_CLIENT_SOCKET_POOL_REQUESTED_SOCKET,
mikecirone8b85c432016-09-08 19:11:00762 NetLogEventPhase::NONE));
Matt Menke9fa17d52019-03-25 19:12:26763 EXPECT_TRUE(LogContainsBeginEvent(entries, 1, NetLogEventType::SOCKET_POOL));
764 EXPECT_TRUE(LogContainsEvent(
765 entries, 2, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
766 NetLogEventPhase::NONE));
767 EXPECT_TRUE(LogContainsEvent(entries, 3,
mikecirone8b85c432016-09-08 19:11:00768 NetLogEventType::SOCKET_POOL_BOUND_TO_SOCKET,
769 NetLogEventPhase::NONE));
Matt Menke9fa17d52019-03-25 19:12:26770 EXPECT_TRUE(LogContainsEndEvent(entries, 4, NetLogEventType::SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09771}
772
[email protected]ab838892009-06-30 18:49:05773TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53774 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20775
[email protected]ab838892009-06-30 18:49:05776 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
Matt Muellerd9342e3a2019-11-26 01:41:14777 RecordingBoundTestNetLog log;
[email protected]9e743cd2010-03-16 07:03:53778
[email protected]2431756e2010-09-29 20:26:13779 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:52780 TestCompletionCallback callback;
[email protected]e60e47a2010-07-14 03:37:18781 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:13782 handle.set_is_ssl_error(true);
Matt Menke39b7c5a2019-04-10 19:47:51783 handle.set_ssl_cert_request_info(base::MakeRefCounted<SSLCertRequestInfo>());
Matt Menke28ac03e2019-02-25 22:25:50784 EXPECT_EQ(
785 ERR_CONNECTION_FAILED,
Matt Menkef09e64c2019-04-23 22:16:28786 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
787 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
788 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
789 pool_.get(), log.bound()));
[email protected]2431756e2010-09-29 20:26:13790 EXPECT_FALSE(handle.socket());
791 EXPECT_FALSE(handle.is_ssl_error());
Matt Menke39b7c5a2019-04-10 19:47:51792 EXPECT_FALSE(handle.ssl_cert_request_info());
[email protected]034df0f32013-01-07 23:17:48793 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:30794
Eric Roman79cc7552019-07-19 02:17:54795 auto entries = log.GetEntries();
[email protected]b2fcd0e2010-12-01 15:19:40796
Matt Menke9fa17d52019-03-25 19:12:26797 EXPECT_EQ(4u, entries.size());
[email protected]06650c52010-06-03 00:49:17798 EXPECT_TRUE(LogContainsEvent(
Matt Menke9fa17d52019-03-25 19:12:26799 entries, 0, NetLogEventType::TCP_CLIENT_SOCKET_POOL_REQUESTED_SOCKET,
mikecirone8b85c432016-09-08 19:11:00800 NetLogEventPhase::NONE));
Matt Menke9fa17d52019-03-25 19:12:26801 EXPECT_TRUE(LogContainsBeginEvent(entries, 1, NetLogEventType::SOCKET_POOL));
802 EXPECT_TRUE(LogContainsEvent(
803 entries, 2, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
804 NetLogEventPhase::NONE));
805 EXPECT_TRUE(LogContainsEndEvent(entries, 3, NetLogEventType::SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09806}
807
Matt Menke433de6d2020-03-04 00:24:11808// Test releasing an open socket into the socket pool, telling the socket pool
809// to close the socket.
810TEST_F(ClientSocketPoolBaseTest, ReleaseAndCloseConnection) {
811 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
812
813 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(OK));
814 ASSERT_TRUE(request(0)->handle()->socket());
815 net::NetLogSource source = request(0)->handle()->socket()->NetLog().source();
816 ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE);
817
818 EXPECT_EQ(0, pool_->IdleSocketCount());
819 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
820
821 ExpectSocketClosedWithReason(
822 source, TransportClientSocketPool::kClosedConnectionReturnedToPool);
823}
824
825TEST_F(ClientSocketPoolBaseTest, SocketWithUnreadDataReturnedToPool) {
826 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
827 connect_job_factory_->set_job_type(TestConnectJob::kMockUnreadDataJob);
828
829 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(OK));
830 ASSERT_TRUE(request(0)->handle()->socket());
831 net::NetLogSource source = request(0)->handle()->socket()->NetLog().source();
832 EXPECT_TRUE(request(0)->handle()->socket()->IsConnected());
833 EXPECT_FALSE(request(0)->handle()->socket()->IsConnectedAndIdle());
834 ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE);
835
836 EXPECT_EQ(0, pool_->IdleSocketCount());
837 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
838
839 ExpectSocketClosedWithReason(
840 source, TransportClientSocketPool::kDataReceivedUnexpectedly);
841}
842
Matt Menkef6edce752019-03-19 17:21:56843// Make sure different groups do not share sockets.
844TEST_F(ClientSocketPoolBaseTest, GroupSeparation) {
Matt Menke166443c2019-05-24 18:45:59845 base::test::ScopedFeatureList feature_list;
846 feature_list.InitAndEnableFeature(
847 features::kPartitionConnectionsByNetworkIsolationKey);
848
Matt Menkef6edce752019-03-19 17:21:56849 CreatePool(1000 /* max_sockets */, 2 /* max_sockets_per_group */);
850
851 const HostPortPair kHostPortPairs[] = {
852 {"a", 80},
853 {"a", 443},
854 {"b", 80},
855 };
856
857 const ClientSocketPool::SocketType kSocketTypes[] = {
858 ClientSocketPool::SocketType::kHttp,
859 ClientSocketPool::SocketType::kSsl,
Matt Menkef6edce752019-03-19 17:21:56860 };
861
Matt Menkebdf777802019-04-22 19:38:59862 const PrivacyMode kPrivacyModes[] = {PrivacyMode::PRIVACY_MODE_DISABLED,
863 PrivacyMode::PRIVACY_MODE_ENABLED};
Matt Menkef6edce752019-03-19 17:21:56864
Matt Menke4807a9a2020-11-21 00:14:41865 const SchemefulSite kSiteA(GURL("http://a.test/"));
866 const SchemefulSite kSiteB(GURL("http://b.test/"));
Matt Menke166443c2019-05-24 18:45:59867 const NetworkIsolationKey kNetworkIsolationKeys[] = {
Matt Menke4807a9a2020-11-21 00:14:41868 NetworkIsolationKey(kSiteA, kSiteA),
869 NetworkIsolationKey(kSiteB, kSiteB),
Matt Menke166443c2019-05-24 18:45:59870 };
871
dalyk5f48a132019-10-14 15:20:19872 const bool kDisableSecureDnsValues[] = {false, true};
873
Matt Menkef6edce752019-03-19 17:21:56874 int total_idle_sockets = 0;
875
876 // Walk through each GroupId, making sure that requesting a socket for one
877 // group does not return a previously connected socket for another group.
878 for (const auto& host_port_pair : kHostPortPairs) {
879 SCOPED_TRACE(host_port_pair.ToString());
880 for (const auto& socket_type : kSocketTypes) {
881 SCOPED_TRACE(static_cast<int>(socket_type));
882 for (const auto& privacy_mode : kPrivacyModes) {
883 SCOPED_TRACE(privacy_mode);
Matt Menke166443c2019-05-24 18:45:59884 for (const auto& network_isolation_key : kNetworkIsolationKeys) {
885 SCOPED_TRACE(network_isolation_key.ToString());
dalyk5f48a132019-10-14 15:20:19886 for (const auto& disable_secure_dns : kDisableSecureDnsValues) {
887 SCOPED_TRACE(disable_secure_dns);
Matt Menkef6edce752019-03-19 17:21:56888
dalyk5f48a132019-10-14 15:20:19889 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
Matt Menkef6edce752019-03-19 17:21:56890
dalyk5f48a132019-10-14 15:20:19891 ClientSocketPool::GroupId group_id(
892 host_port_pair, socket_type, privacy_mode,
893 network_isolation_key, disable_secure_dns);
Matt Menkef6edce752019-03-19 17:21:56894
dalyk5f48a132019-10-14 15:20:19895 EXPECT_FALSE(pool_->HasGroupForTesting(group_id));
Matt Menkef6edce752019-03-19 17:21:56896
dalyk5f48a132019-10-14 15:20:19897 TestCompletionCallback callback;
898 ClientSocketHandle handle;
Matt Menkef6edce752019-03-19 17:21:56899
dalyk5f48a132019-10-14 15:20:19900 // Since the group is empty, requesting a socket should not complete
901 // synchronously.
902 EXPECT_THAT(handle.Init(group_id, params_, base::nullopt,
903 DEFAULT_PRIORITY, SocketTag(),
904 ClientSocketPool::RespectLimits::ENABLED,
905 callback.callback(),
906 ClientSocketPool::ProxyAuthCallback(),
907 pool_.get(), NetLogWithSource()),
908 IsError(ERR_IO_PENDING));
909 EXPECT_TRUE(pool_->HasGroupForTesting(group_id));
910 EXPECT_EQ(total_idle_sockets, pool_->IdleSocketCount());
Matt Menkef6edce752019-03-19 17:21:56911
dalyk5f48a132019-10-14 15:20:19912 EXPECT_THAT(callback.WaitForResult(), IsOk());
913 EXPECT_TRUE(handle.socket());
914 EXPECT_TRUE(pool_->HasGroupForTesting(group_id));
915 EXPECT_EQ(total_idle_sockets, pool_->IdleSocketCount());
Matt Menkef6edce752019-03-19 17:21:56916
dalyk5f48a132019-10-14 15:20:19917 // Return socket to pool.
918 handle.Reset();
919 EXPECT_EQ(total_idle_sockets + 1, pool_->IdleSocketCount());
Matt Menkef6edce752019-03-19 17:21:56920
dalyk5f48a132019-10-14 15:20:19921 // Requesting a socket again should return the same socket as
922 // before, so should complete synchronously.
923 EXPECT_THAT(handle.Init(group_id, params_, base::nullopt,
924 DEFAULT_PRIORITY, SocketTag(),
925 ClientSocketPool::RespectLimits::ENABLED,
926 callback.callback(),
927 ClientSocketPool::ProxyAuthCallback(),
928 pool_.get(), NetLogWithSource()),
929 IsOk());
930 EXPECT_TRUE(handle.socket());
931 EXPECT_EQ(total_idle_sockets, pool_->IdleSocketCount());
Matt Menkef6edce752019-03-19 17:21:56932
dalyk5f48a132019-10-14 15:20:19933 // Return socket to pool again.
934 handle.Reset();
935 EXPECT_EQ(total_idle_sockets + 1, pool_->IdleSocketCount());
Matt Menkef6edce752019-03-19 17:21:56936
dalyk5f48a132019-10-14 15:20:19937 ++total_idle_sockets;
938 }
Matt Menke166443c2019-05-24 18:45:59939 }
Matt Menkef6edce752019-03-19 17:21:56940 }
941 }
942 }
943}
944
[email protected]211d21722009-07-22 15:48:53945TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
946 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
947
[email protected]9e743cd2010-03-16 07:03:53948 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30949
Matt Menkec6b3edf72019-03-19 17:00:39950 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
951 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
952 EXPECT_THAT(StartRequest(TestGroupId("c"), DEFAULT_PRIORITY), IsOk());
953 EXPECT_THAT(StartRequest(TestGroupId("d"), DEFAULT_PRIORITY), IsOk());
[email protected]211d21722009-07-22 15:48:53954
[email protected]2431756e2010-09-29 20:26:13955 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53956 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13957 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53958
Matt Menkec6b3edf72019-03-19 17:00:39959 EXPECT_THAT(StartRequest(TestGroupId("e"), DEFAULT_PRIORITY),
960 IsError(ERR_IO_PENDING));
961 EXPECT_THAT(StartRequest(TestGroupId("f"), DEFAULT_PRIORITY),
962 IsError(ERR_IO_PENDING));
963 EXPECT_THAT(StartRequest(TestGroupId("g"), DEFAULT_PRIORITY),
964 IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:53965
[email protected]2431756e2010-09-29 20:26:13966 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53967
[email protected]2431756e2010-09-29 20:26:13968 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53969 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13970 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53971
972 EXPECT_EQ(1, GetOrderOfRequest(1));
973 EXPECT_EQ(2, GetOrderOfRequest(2));
974 EXPECT_EQ(3, GetOrderOfRequest(3));
975 EXPECT_EQ(4, GetOrderOfRequest(4));
976 EXPECT_EQ(5, GetOrderOfRequest(5));
977 EXPECT_EQ(6, GetOrderOfRequest(6));
978 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17979
980 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13981 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53982}
983
984TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
985 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
986
[email protected]9e743cd2010-03-16 07:03:53987 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30988
[email protected]211d21722009-07-22 15:48:53989 // Reach all limits: max total sockets, and max sockets per group.
Matt Menkec6b3edf72019-03-19 17:00:39990 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
991 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
992 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
993 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
[email protected]211d21722009-07-22 15:48:53994
[email protected]2431756e2010-09-29 20:26:13995 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53996 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13997 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53998
999 // Now create a new group and verify that we don't starve it.
Matt Menkec6b3edf72019-03-19 17:00:391000 EXPECT_THAT(StartRequest(TestGroupId("c"), DEFAULT_PRIORITY),
1001 IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:531002
[email protected]2431756e2010-09-29 20:26:131003 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:531004
[email protected]2431756e2010-09-29 20:26:131005 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531006 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131007 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:531008
1009 EXPECT_EQ(1, GetOrderOfRequest(1));
1010 EXPECT_EQ(2, GetOrderOfRequest(2));
1011 EXPECT_EQ(3, GetOrderOfRequest(3));
1012 EXPECT_EQ(4, GetOrderOfRequest(4));
1013 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:171014
1015 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131016 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:531017}
1018
1019TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
1020 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1021
Matt Menkec6b3edf72019-03-19 17:00:391022 EXPECT_THAT(StartRequest(TestGroupId("b"), LOWEST), IsOk());
1023 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsOk());
1024 EXPECT_THAT(StartRequest(TestGroupId("b"), HIGHEST), IsOk());
1025 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsOk());
[email protected]211d21722009-07-22 15:48:531026
[email protected]2431756e2010-09-29 20:26:131027 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531028 client_socket_factory_.allocation_count());
1029
Matt Menkec6b3edf72019-03-19 17:00:391030 EXPECT_THAT(StartRequest(TestGroupId("c"), LOWEST), IsError(ERR_IO_PENDING));
1031 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1032 EXPECT_THAT(StartRequest(TestGroupId("b"), HIGHEST), IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:531033
[email protected]2431756e2010-09-29 20:26:131034 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:531035
[email protected]2431756e2010-09-29 20:26:131036 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:531037
1038 // First 4 requests don't have to wait, and finish in order.
1039 EXPECT_EQ(1, GetOrderOfRequest(1));
1040 EXPECT_EQ(2, GetOrderOfRequest(2));
1041 EXPECT_EQ(3, GetOrderOfRequest(3));
1042 EXPECT_EQ(4, GetOrderOfRequest(4));
1043
Matt Menkec6b3edf72019-03-19 17:00:391044 // Request ("b", HIGHEST) has the highest priority, then (TestGroupId("a"),
1045 // MEDIUM), and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:531046 EXPECT_EQ(7, GetOrderOfRequest(5));
1047 EXPECT_EQ(6, GetOrderOfRequest(6));
1048 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171049
1050 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131051 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]211d21722009-07-22 15:48:531052}
1053
rdsmith29dbad12017-02-17 02:22:181054// Test reprioritizing a request before completion doesn't interfere with
1055// its completion.
1056TEST_F(ClientSocketPoolBaseTest, ReprioritizeOne) {
1057 CreatePool(kDefaultMaxSockets, 1);
1058
Matt Menkec6b3edf72019-03-19 17:00:391059 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(OK));
1060 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
rdsmith29dbad12017-02-17 02:22:181061 EXPECT_TRUE(request(0)->handle()->socket());
1062 EXPECT_FALSE(request(1)->handle()->socket());
1063
Lily Chenecebf932018-11-02 17:15:431064 request(1)->handle()->SetPriority(HIGHEST);
rdsmith29dbad12017-02-17 02:22:181065
1066 ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE);
1067
1068 EXPECT_TRUE(request(1)->handle()->socket());
1069}
1070
1071// Reprioritize a request up past another one and make sure that changes the
1072// completion order.
1073TEST_F(ClientSocketPoolBaseTest, ReprioritizeUpReorder) {
1074 CreatePool(kDefaultMaxSockets, 1);
1075
Matt Menkec6b3edf72019-03-19 17:00:391076 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(OK));
1077 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1078 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
rdsmith29dbad12017-02-17 02:22:181079 EXPECT_TRUE(request(0)->handle()->socket());
1080 EXPECT_FALSE(request(1)->handle()->socket());
1081 EXPECT_FALSE(request(2)->handle()->socket());
1082
1083 request(2)->handle()->SetPriority(HIGHEST);
1084
1085 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1086
1087 EXPECT_EQ(1, GetOrderOfRequest(1));
1088 EXPECT_EQ(3, GetOrderOfRequest(2));
1089 EXPECT_EQ(2, GetOrderOfRequest(3));
1090}
1091
1092// Reprioritize a request without changing relative priorities and check
1093// that the order doesn't change.
1094TEST_F(ClientSocketPoolBaseTest, ReprioritizeUpNoReorder) {
1095 CreatePool(kDefaultMaxSockets, 1);
1096
Matt Menkec6b3edf72019-03-19 17:00:391097 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(OK));
1098 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1099 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsError(ERR_IO_PENDING));
rdsmith29dbad12017-02-17 02:22:181100 EXPECT_TRUE(request(0)->handle()->socket());
1101 EXPECT_FALSE(request(1)->handle()->socket());
1102 EXPECT_FALSE(request(2)->handle()->socket());
1103
1104 request(2)->handle()->SetPriority(MEDIUM);
1105
1106 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1107
1108 EXPECT_EQ(1, GetOrderOfRequest(1));
1109 EXPECT_EQ(2, GetOrderOfRequest(2));
1110 EXPECT_EQ(3, GetOrderOfRequest(3));
1111}
1112
1113// Reprioritize a request past down another one and make sure that changes the
1114// completion order.
1115TEST_F(ClientSocketPoolBaseTest, ReprioritizeDownReorder) {
1116 CreatePool(kDefaultMaxSockets, 1);
1117
Matt Menkec6b3edf72019-03-19 17:00:391118 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(OK));
1119 EXPECT_THAT(StartRequest(TestGroupId("a"), HIGHEST), IsError(ERR_IO_PENDING));
1120 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
rdsmith29dbad12017-02-17 02:22:181121 EXPECT_TRUE(request(0)->handle()->socket());
1122 EXPECT_FALSE(request(1)->handle()->socket());
1123 EXPECT_FALSE(request(2)->handle()->socket());
1124
1125 request(1)->handle()->SetPriority(LOW);
1126
1127 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1128
1129 EXPECT_EQ(1, GetOrderOfRequest(1));
1130 EXPECT_EQ(3, GetOrderOfRequest(2));
1131 EXPECT_EQ(2, GetOrderOfRequest(3));
1132}
1133
1134// Reprioritize a request to the same level as another and confirm it is
1135// put after the old request.
1136TEST_F(ClientSocketPoolBaseTest, ReprioritizeResetFIFO) {
1137 CreatePool(kDefaultMaxSockets, 1);
1138
Matt Menkec6b3edf72019-03-19 17:00:391139 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(OK));
1140 EXPECT_THAT(StartRequest(TestGroupId("a"), HIGHEST), IsError(ERR_IO_PENDING));
1141 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
rdsmith29dbad12017-02-17 02:22:181142 EXPECT_TRUE(request(0)->handle()->socket());
1143 EXPECT_FALSE(request(1)->handle()->socket());
1144 EXPECT_FALSE(request(2)->handle()->socket());
1145
1146 request(1)->handle()->SetPriority(MEDIUM);
1147
1148 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1149
1150 EXPECT_EQ(1, GetOrderOfRequest(1));
1151 EXPECT_EQ(3, GetOrderOfRequest(2));
1152 EXPECT_EQ(2, GetOrderOfRequest(3));
1153}
1154
[email protected]211d21722009-07-22 15:48:531155TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
1156 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1157
Matt Menkec6b3edf72019-03-19 17:00:391158 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsOk());
1159 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsOk());
1160 EXPECT_THAT(StartRequest(TestGroupId("b"), HIGHEST), IsOk());
1161 EXPECT_THAT(StartRequest(TestGroupId("b"), MEDIUM), IsOk());
[email protected]211d21722009-07-22 15:48:531162
[email protected]2431756e2010-09-29 20:26:131163 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531164 client_socket_factory_.allocation_count());
1165
Matt Menkec6b3edf72019-03-19 17:00:391166 EXPECT_THAT(StartRequest(TestGroupId("c"), MEDIUM), IsError(ERR_IO_PENDING));
1167 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsError(ERR_IO_PENDING));
1168 EXPECT_THAT(StartRequest(TestGroupId("b"), HIGHEST), IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:531169
[email protected]2431756e2010-09-29 20:26:131170 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:531171
[email protected]2431756e2010-09-29 20:26:131172 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531173 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131174 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:531175
1176 // First 4 requests don't have to wait, and finish in order.
1177 EXPECT_EQ(1, GetOrderOfRequest(1));
1178 EXPECT_EQ(2, GetOrderOfRequest(2));
1179 EXPECT_EQ(3, GetOrderOfRequest(3));
1180 EXPECT_EQ(4, GetOrderOfRequest(4));
1181
1182 // Request ("b", 7) has the highest priority, but we can't make new socket for
1183 // group "b", because it has reached the per-group limit. Then we make
1184 // socket for ("c", 6), because it has higher priority than ("a", 4),
1185 // and we still can't make a socket for group "b".
1186 EXPECT_EQ(5, GetOrderOfRequest(5));
1187 EXPECT_EQ(6, GetOrderOfRequest(6));
1188 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171189
1190 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131191 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:531192}
1193
1194// Make sure that we count connecting sockets against the total limit.
1195TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
1196 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1197
Matt Menkec6b3edf72019-03-19 17:00:391198 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1199 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
1200 EXPECT_THAT(StartRequest(TestGroupId("c"), DEFAULT_PRIORITY), IsOk());
[email protected]211d21722009-07-22 15:48:531201
1202 // Create one asynchronous request.
1203 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
Matt Menkec6b3edf72019-03-19 17:00:391204 EXPECT_THAT(StartRequest(TestGroupId("d"), DEFAULT_PRIORITY),
1205 IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:531206
[email protected]6b175382009-10-13 06:47:471207 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1208 // actually become pending until 2ms after they have been created. In order
1209 // to flush all tasks, we need to wait so that we know there are no
1210 // soon-to-be-pending tasks waiting.
Alex Clarke0def2092018-12-10 12:01:451211 FastForwardBy(base::TimeDelta::FromMilliseconds(10));
[email protected]6b175382009-10-13 06:47:471212
[email protected]211d21722009-07-22 15:48:531213 // The next synchronous request should wait for its turn.
1214 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
Matt Menkec6b3edf72019-03-19 17:00:391215 EXPECT_THAT(StartRequest(TestGroupId("e"), DEFAULT_PRIORITY),
1216 IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:531217
[email protected]2431756e2010-09-29 20:26:131218 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:531219
[email protected]2431756e2010-09-29 20:26:131220 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531221 client_socket_factory_.allocation_count());
1222
1223 EXPECT_EQ(1, GetOrderOfRequest(1));
1224 EXPECT_EQ(2, GetOrderOfRequest(2));
1225 EXPECT_EQ(3, GetOrderOfRequest(3));
1226 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:171227 EXPECT_EQ(5, GetOrderOfRequest(5));
1228
1229 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131230 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:531231}
1232
[email protected]6427fe22010-04-16 22:27:411233TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
1234 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1235 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1236
Matt Menkec6b3edf72019-03-19 17:00:391237 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1238 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());
[email protected]6427fe22010-04-16 22:27:411241
1242 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1243
1244 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1245
Matt Menkec6b3edf72019-03-19 17:00:391246 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY),
1247 IsError(ERR_IO_PENDING));
1248 EXPECT_THAT(StartRequest(TestGroupId("c"), DEFAULT_PRIORITY),
1249 IsError(ERR_IO_PENDING));
[email protected]6427fe22010-04-16 22:27:411250
1251 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1252
[email protected]2431756e2010-09-29 20:26:131253 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411254 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131255 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411256 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131257 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1258 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411259 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
1260}
1261
[email protected]d7027bb2010-05-10 18:58:541262TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
1263 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1264 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1265
1266 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521267 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:501268 EXPECT_EQ(
1269 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:281270 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
1271 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1272 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1273 pool_.get(), NetLogWithSource()));
[email protected]d7027bb2010-05-10 18:58:541274
1275 ClientSocketHandle handles[4];
Avi Drissman4365a4782018-12-28 19:26:241276 for (size_t i = 0; i < base::size(handles); ++i) {
[email protected]6ecf2b92011-12-15 01:14:521277 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:501278 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:391279 handles[i].Init(
Matt Menkef09e64c2019-04-23 22:16:281280 TestGroupId("b"), params_, base::nullopt, DEFAULT_PRIORITY,
1281 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1282 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1283 pool_.get(), NetLogWithSource()));
[email protected]d7027bb2010-05-10 18:58:541284 }
1285
1286 // One will be stalled, cancel all the handles now.
1287 // This should hit the OnAvailableSocketSlot() code where we previously had
1288 // stalled groups, but no longer have any.
Avi Drissman4365a4782018-12-28 19:26:241289 for (size_t i = 0; i < base::size(handles); ++i)
[email protected]d7027bb2010-05-10 18:58:541290 handles[i].Reset();
1291}
1292
[email protected]eb5a99382010-07-11 03:18:261293TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
[email protected]43a21b82010-06-10 21:30:541294 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1295 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1296
[email protected]eb5a99382010-07-11 03:18:261297 {
1298 ClientSocketHandle handles[kDefaultMaxSockets];
[email protected]6ecf2b92011-12-15 01:14:521299 TestCompletionCallback callbacks[kDefaultMaxSockets];
[email protected]eb5a99382010-07-11 03:18:261300 for (int i = 0; i < kDefaultMaxSockets; ++i) {
Matt Menkef09e64c2019-04-23 22:16:281301 EXPECT_EQ(OK,
1302 handles[i].Init(TestGroupId(base::NumberToString(i)), params_,
1303 base::nullopt, DEFAULT_PRIORITY, SocketTag(),
1304 ClientSocketPool::RespectLimits::ENABLED,
1305 callbacks[i].callback(),
1306 ClientSocketPool::ProxyAuthCallback(),
1307 pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261308 }
1309
1310 // Force a stalled group.
1311 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521312 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:201313 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:391314 stalled_handle.Init(
Matt Menkef09e64c2019-04-23 22:16:281315 TestGroupId("foo"), params_, base::nullopt, DEFAULT_PRIORITY,
1316 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1317 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1318 pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261319
1320 // Cancel the stalled request.
1321 stalled_handle.Reset();
1322
1323 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1324 EXPECT_EQ(0, pool_->IdleSocketCount());
1325
1326 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541327 }
1328
[email protected]43a21b82010-06-10 21:30:541329 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1330 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
[email protected]eb5a99382010-07-11 03:18:261331}
[email protected]43a21b82010-06-10 21:30:541332
[email protected]eb5a99382010-07-11 03:18:261333TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
1334 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1335 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1336
1337 {
1338 ClientSocketHandle handles[kDefaultMaxSockets];
1339 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:521340 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:201341 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:391342 handles[i].Init(TestGroupId(base::NumberToString(i)), params_,
Matt Menkef09e64c2019-04-23 22:16:281343 base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menkec6b3edf72019-03-19 17:00:391344 ClientSocketPool::RespectLimits::ENABLED,
1345 callback.callback(),
1346 ClientSocketPool::ProxyAuthCallback(),
1347 pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261348 }
1349
1350 // Force a stalled group.
1351 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1352 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521353 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:201354 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:391355 stalled_handle.Init(
Matt Menkef09e64c2019-04-23 22:16:281356 TestGroupId("foo"), params_, base::nullopt, DEFAULT_PRIORITY,
1357 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1358 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1359 pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261360
1361 // Since it is stalled, it should have no connect jobs.
Matt Menke9fa17d52019-03-25 19:12:261362 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("foo")));
1363 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
1364 TestGroupId("foo")));
1365 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroupForTesting(
1366 TestGroupId("foo")));
[email protected]eb5a99382010-07-11 03:18:261367
1368 // Cancel the stalled request.
1369 handles[0].Reset();
1370
[email protected]eb5a99382010-07-11 03:18:261371 // Now we should have a connect job.
Matt Menke9fa17d52019-03-25 19:12:261372 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("foo")));
1373 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
1374 TestGroupId("foo")));
1375 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroupForTesting(
1376 TestGroupId("foo")));
[email protected]eb5a99382010-07-11 03:18:261377
1378 // The stalled socket should connect.
robpercival214763f2016-07-01 23:27:011379 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:261380
1381 EXPECT_EQ(kDefaultMaxSockets + 1,
1382 client_socket_factory_.allocation_count());
1383 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menke9fa17d52019-03-25 19:12:261384 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("foo")));
1385 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
1386 TestGroupId("foo")));
1387 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroupForTesting(
1388 TestGroupId("foo")));
[email protected]eb5a99382010-07-11 03:18:261389
1390 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541391 }
1392
[email protected]eb5a99382010-07-11 03:18:261393 EXPECT_EQ(1, pool_->IdleSocketCount());
1394}
[email protected]43a21b82010-06-10 21:30:541395
[email protected]eb5a99382010-07-11 03:18:261396TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
1397 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1398 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]43a21b82010-06-10 21:30:541399
[email protected]eb5a99382010-07-11 03:18:261400 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521401 TestCompletionCallback callback;
[email protected]eb5a99382010-07-11 03:18:261402 {
[email protected]51fdc7c2012-04-10 19:19:481403 EXPECT_FALSE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261404 ClientSocketHandle handles[kDefaultMaxSockets];
1405 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:521406 TestCompletionCallback callback;
Matt Menkec6b3edf72019-03-19 17:00:391407 EXPECT_EQ(
Matt Menkef09e64c2019-04-23 22:16:281408 OK, handles[i].Init(
1409 TestGroupId(base::StringPrintf("Take 2: %d", i)), params_,
1410 base::nullopt, DEFAULT_PRIORITY, SocketTag(),
1411 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1412 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
1413 NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261414 }
1415
1416 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1417 EXPECT_EQ(0, pool_->IdleSocketCount());
[email protected]51fdc7c2012-04-10 19:19:481418 EXPECT_FALSE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261419
1420 // Now we will hit the socket limit.
tfarina428341112016-09-22 13:38:201421 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:391422 stalled_handle.Init(
Matt Menkef09e64c2019-04-23 22:16:281423 TestGroupId("foo"), params_, base::nullopt, DEFAULT_PRIORITY,
1424 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1425 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1426 pool_.get(), NetLogWithSource()));
[email protected]51fdc7c2012-04-10 19:19:481427 EXPECT_TRUE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261428
1429 // Dropping out of scope will close all handles and return them to idle.
1430 }
[email protected]43a21b82010-06-10 21:30:541431
1432 // But if we wait for it, the released idle sockets will be closed in
1433 // preference of the waiting request.
robpercival214763f2016-07-01 23:27:011434 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:261435
1436 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1437 EXPECT_EQ(3, pool_->IdleSocketCount());
[email protected]43a21b82010-06-10 21:30:541438}
1439
1440// Regression test for http://crbug.com/40952.
1441TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
Matt Menke9fa17d52019-03-25 19:12:261442 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1443 true /* enable_backup_connect_jobs */);
[email protected]43a21b82010-06-10 21:30:541444 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1445
1446 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1447 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521448 TestCompletionCallback callback;
Matt Menkec6b3edf72019-03-19 17:00:391449 EXPECT_EQ(OK, handle.Init(TestGroupId(base::NumberToString(i)), params_,
Matt Menkef09e64c2019-04-23 22:16:281450 base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menkec6b3edf72019-03-19 17:00:391451 ClientSocketPool::RespectLimits::ENABLED,
1452 callback.callback(),
1453 ClientSocketPool::ProxyAuthCallback(),
1454 pool_.get(), NetLogWithSource()));
[email protected]43a21b82010-06-10 21:30:541455 }
1456
1457 // Flush all the DoReleaseSocket tasks.
fdoray5eeb7642016-06-22 16:11:281458 base::RunLoop().RunUntilIdle();
[email protected]43a21b82010-06-10 21:30:541459
1460 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
1461 // reuse a socket.
1462 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1463 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521464 TestCompletionCallback callback;
[email protected]43a21b82010-06-10 21:30:541465
1466 // "0" is special here, since it should be the first entry in the sorted map,
1467 // which is the one which we would close an idle socket for. We shouldn't
1468 // close an idle socket though, since we should reuse the idle socket.
Matt Menkec6b3edf72019-03-19 17:00:391469 EXPECT_EQ(OK, handle.Init(
Matt Menkef09e64c2019-04-23 22:16:281470 TestGroupId("0"), params_, base::nullopt, DEFAULT_PRIORITY,
1471 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menkec6b3edf72019-03-19 17:00:391472 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1473 pool_.get(), NetLogWithSource()));
[email protected]43a21b82010-06-10 21:30:541474
1475 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1476 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
1477}
1478
[email protected]ab838892009-06-30 18:49:051479TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:531480 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091481
Matt Menkec6b3edf72019-03-19 17:00:391482 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1483 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1484 EXPECT_THAT(StartRequest(TestGroupId("a"), IDLE), IsError(ERR_IO_PENDING));
1485 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
1486 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1487 EXPECT_THAT(StartRequest(TestGroupId("a"), HIGHEST), IsError(ERR_IO_PENDING));
1488 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsError(ERR_IO_PENDING));
1489 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091490
[email protected]2431756e2010-09-29 20:26:131491 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]c9d6a1d2009-07-14 16:15:201492 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1493 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131494 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1495 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091496
[email protected]c9d6a1d2009-07-14 16:15:201497 EXPECT_EQ(1, GetOrderOfRequest(1));
1498 EXPECT_EQ(2, GetOrderOfRequest(2));
[email protected]c9c6f5c2010-07-31 01:30:031499 EXPECT_EQ(8, GetOrderOfRequest(3));
1500 EXPECT_EQ(6, GetOrderOfRequest(4));
1501 EXPECT_EQ(4, GetOrderOfRequest(5));
1502 EXPECT_EQ(3, GetOrderOfRequest(6));
1503 EXPECT_EQ(5, GetOrderOfRequest(7));
1504 EXPECT_EQ(7, GetOrderOfRequest(8));
[email protected]75439d3b2009-07-23 22:11:171505
1506 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131507 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]f6d1d6eb2009-06-24 20:16:091508}
1509
[email protected]ab838892009-06-30 18:49:051510TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:531511 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091512
Matt Menkec6b3edf72019-03-19 17:00:391513 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1514 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1515 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
1516 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1517 EXPECT_THAT(StartRequest(TestGroupId("a"), HIGHEST), IsError(ERR_IO_PENDING));
1518 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsError(ERR_IO_PENDING));
1519 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091520
[email protected]2431756e2010-09-29 20:26:131521 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091522
[email protected]2431756e2010-09-29 20:26:131523 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i)
robpercival214763f2016-07-01 23:27:011524 EXPECT_THAT(request(i)->WaitForResult(), IsOk());
[email protected]c9d6a1d2009-07-14 16:15:201525
[email protected]2431756e2010-09-29 20:26:131526 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]c9d6a1d2009-07-14 16:15:201527 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131528 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1529 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091530}
1531
Matt Menke7eb405e2019-04-25 20:48:211532TEST_F(ClientSocketPoolBaseTest, ResetAndCloseSocket) {
1533 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1534
1535 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1536 ClientSocketHandle handle;
1537 TestCompletionCallback callback;
1538 EXPECT_EQ(
1539 ERR_IO_PENDING,
1540 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
1541 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1542 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1543 pool_.get(), NetLogWithSource()));
1544
1545 EXPECT_THAT(callback.WaitForResult(), IsOk());
1546 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1547 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1548 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
1549 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
1550
1551 handle.ResetAndCloseSocket();
1552 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
1553}
1554
Matt Menke99251ea42019-04-25 22:59:021555// This test will start up a socket request and then call Reset() on the handle.
1556// The pending ConnectJob should not be destroyed.
Matt Menke7eb405e2019-04-25 20:48:211557TEST_F(ClientSocketPoolBaseTest, CancelRequestKeepsConnectJob) {
[email protected]211d21722009-07-22 15:48:531558 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201559
[email protected]ab838892009-06-30 18:49:051560 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131561 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521562 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:501563 EXPECT_EQ(
1564 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:281565 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
1566 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1567 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1568 pool_.get(), NetLogWithSource()));
[email protected]2431756e2010-09-29 20:26:131569 handle.Reset();
Matt Menke7eb405e2019-04-25 20:48:211570 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1571 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1572}
1573
Matt Menke99251ea42019-04-25 22:59:021574// This test will start up a socket request and then call ResetAndCloseSocket()
1575// on the handle. The pending ConnectJob or connected socket should be
1576// destroyed.
Matt Menke7eb405e2019-04-25 20:48:211577TEST_F(ClientSocketPoolBaseTest, CancelRequestAndCloseSocket) {
1578 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1579
Matt Menke99251ea42019-04-25 22:59:021580 // When true, the socket connects before it's canceled.
1581 for (bool cancel_when_callback_pending : {false, true}) {
1582 if (cancel_when_callback_pending) {
1583 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1584 } else {
1585 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1586 }
1587 ClientSocketHandle handle;
1588 TestCompletionCallback callback;
1589 EXPECT_EQ(
1590 ERR_IO_PENDING,
1591 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
1592 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1593 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1594 pool_.get(), NetLogWithSource()));
1595 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1596 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1597
1598 if (cancel_when_callback_pending) {
1599 client_socket_factory_.SignalJobs();
1600 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1601 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
1602 }
1603
1604 handle.ResetAndCloseSocket();
1605 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
1606 }
Matt Menke7eb405e2019-04-25 20:48:211607}
1608
1609TEST_F(ClientSocketPoolBaseTest,
1610 CancelRequestAndCloseSocketWhenMoreRequestsThanConnectJobs) {
1611 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1612
Matt Menke99251ea42019-04-25 22:59:021613 // When true, the sockets connect before they're canceled.
1614 for (bool cancel_when_callback_pending : {false, true}) {
1615 if (cancel_when_callback_pending) {
1616 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1617 } else {
1618 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1619 }
Matt Menke7eb405e2019-04-25 20:48:211620
Matt Menke99251ea42019-04-25 22:59:021621 std::vector<std::unique_ptr<ClientSocketHandle>> handles;
1622 TestCompletionCallback callback;
1623 // Make |kDefaultMaxSockets + 1| socket requests.
1624 for (int i = 0; i < kDefaultMaxSocketsPerGroup + 1; ++i) {
1625 std::unique_ptr<ClientSocketHandle> handle =
1626 std::make_unique<ClientSocketHandle>();
1627 EXPECT_EQ(ERR_IO_PENDING,
1628 handle->Init(
1629 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
1630 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1631 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1632 pool_.get(), NetLogWithSource()));
1633 handles.push_back(std::move(handle));
Matt Menke7eb405e2019-04-25 20:48:211634 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
Matt Menke99251ea42019-04-25 22:59:021635 EXPECT_EQ(
1636 static_cast<size_t>(std::min(i + 1, kDefaultMaxSocketsPerGroup)),
1637 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1638 }
1639
1640 if (cancel_when_callback_pending) {
1641 client_socket_factory_.SignalJobs();
1642 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1643 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1644 pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
1645 }
1646
1647 // Calling ResetAndCloseSocket() on a handle should not cancel a ConnectJob
1648 // or close a socket, since there are more requests than ConnectJobs or
1649 // sockets.
1650 handles[kDefaultMaxSocketsPerGroup]->ResetAndCloseSocket();
1651 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1652 if (cancel_when_callback_pending) {
1653 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1654 pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
1655 } else {
1656 EXPECT_EQ(static_cast<size_t>(kDefaultMaxSocketsPerGroup),
Matt Menke7eb405e2019-04-25 20:48:211657 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1658 }
Matt Menke99251ea42019-04-25 22:59:021659
1660 // Calling ResetAndCloseSocket() on other handles should cancel a ConnectJob
1661 // or close a socket.
1662 for (int i = kDefaultMaxSocketsPerGroup - 1; i >= 0; --i) {
1663 handles[i]->ResetAndCloseSocket();
1664 if (i > 0) {
1665 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1666 if (cancel_when_callback_pending) {
1667 EXPECT_EQ(i,
1668 pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
1669 } else {
1670 EXPECT_EQ(static_cast<size_t>(i),
1671 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1672 }
1673 } else {
1674 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
1675 }
1676 }
Matt Menke7eb405e2019-04-25 20:48:211677 }
[email protected]f6d1d6eb2009-06-24 20:16:091678}
1679
[email protected]ab838892009-06-30 18:49:051680TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531681 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201682
[email protected]ab838892009-06-30 18:49:051683 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061684 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521685 TestCompletionCallback callback;
[email protected]f6d1d6eb2009-06-24 20:16:091686
Matt Menke28ac03e2019-02-25 22:25:501687 EXPECT_EQ(
1688 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:281689 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
1690 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1691 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1692 pool_.get(), NetLogWithSource()));
[email protected]f6d1d6eb2009-06-24 20:16:091693
1694 handle.Reset();
Matt Menke7eb405e2019-04-25 20:48:211695 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1696 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]f6d1d6eb2009-06-24 20:16:091697
Matt Menke7eb405e2019-04-25 20:48:211698 // This will create a second ConnectJob, since the other ConnectJob was
1699 // previously assigned to a request.
[email protected]6ecf2b92011-12-15 01:14:521700 TestCompletionCallback callback2;
Matt Menke28ac03e2019-02-25 22:25:501701 EXPECT_EQ(
1702 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:281703 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
1704 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501705 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
1706 pool_.get(), NetLogWithSource()));
[email protected]f6d1d6eb2009-06-24 20:16:091707
Matt Menke7eb405e2019-04-25 20:48:211708 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1709 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1710
robpercival214763f2016-07-01 23:27:011711 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]f6d1d6eb2009-06-24 20:16:091712 EXPECT_FALSE(callback.have_result());
Matt Menke7eb405e2019-04-25 20:48:211713 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1714 // One ConnectJob completed, and its socket is now assigned to |handle|.
1715 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
1716 // The other ConnectJob should have either completed, or still be connecting.
1717 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")) +
1718 pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]f6d1d6eb2009-06-24 20:16:091719
1720 handle.Reset();
Matt Menke7eb405e2019-04-25 20:48:211721 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1722 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")) +
1723 pool_->IdleSocketCountInGroup(TestGroupId("a")));
1724 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
[email protected]f6d1d6eb2009-06-24 20:16:091725}
1726
[email protected]ab838892009-06-30 18:49:051727TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531728 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091729
Matt Menkec6b3edf72019-03-19 17:00:391730 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1731 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1732 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
1733 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1734 EXPECT_THAT(StartRequest(TestGroupId("a"), HIGHEST), IsError(ERR_IO_PENDING));
1735 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsError(ERR_IO_PENDING));
1736 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091737
1738 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:201739 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]2431756e2010-09-29 20:26:131740 EXPECT_FALSE((*requests())[index_to_cancel]->handle()->is_initialized());
1741 (*requests())[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091742
[email protected]2431756e2010-09-29 20:26:131743 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091744
[email protected]c9d6a1d2009-07-14 16:15:201745 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1746 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131747 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup - 1,
1748 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091749
[email protected]c9d6a1d2009-07-14 16:15:201750 EXPECT_EQ(1, GetOrderOfRequest(1));
1751 EXPECT_EQ(2, GetOrderOfRequest(2));
1752 EXPECT_EQ(5, GetOrderOfRequest(3));
1753 EXPECT_EQ(3, GetOrderOfRequest(4));
[email protected]2431756e2010-09-29 20:26:131754 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
1755 GetOrderOfRequest(5)); // Canceled request.
[email protected]c9d6a1d2009-07-14 16:15:201756 EXPECT_EQ(4, GetOrderOfRequest(6));
1757 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171758
1759 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131760 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:091761}
1762
mmenke33d24423d2015-05-19 19:41:091763// Function to be used as a callback on socket request completion. It first
1764// disconnects the successfully connected socket from the first request, and
1765// then reuses the ClientSocketHandle to request another socket.
1766//
1767// |nested_callback| is called with the result of the second socket request.
1768void RequestSocketOnComplete(ClientSocketHandle* handle,
Matt Menke9fa17d52019-03-25 19:12:261769 TransportClientSocketPool* pool,
mmenke33d24423d2015-05-19 19:41:091770 TestConnectJobFactory* test_connect_job_factory,
1771 TestConnectJob::JobType next_job_type,
Bence Békya4a50932018-08-10 13:39:411772 TestCompletionCallback* nested_callback,
mmenke33d24423d2015-05-19 19:41:091773 int first_request_result) {
robpercival214763f2016-07-01 23:27:011774 EXPECT_THAT(first_request_result, IsOk());
mmenke33d24423d2015-05-19 19:41:091775
1776 test_connect_job_factory->set_job_type(next_job_type);
1777
1778 // Don't allow reuse of the socket. Disconnect it and then release it.
1779 if (handle->socket())
1780 handle->socket()->Disconnect();
1781 handle->Reset();
1782
mmenke33d24423d2015-05-19 19:41:091783 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:501784 int rv = handle->Init(
Matt Menke870e19ab2019-04-23 16:23:031785 TestGroupId("a"),
Matt Menkef09e64c2019-04-23 22:16:281786 ClientSocketPool::SocketParams::CreateForHttpForTesting(), base::nullopt,
1787 LOWEST, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke870e19ab2019-04-23 16:23:031788 nested_callback->callback(), ClientSocketPool::ProxyAuthCallback(), pool,
1789 NetLogWithSource());
mmenke33d24423d2015-05-19 19:41:091790 if (rv != ERR_IO_PENDING) {
1791 DCHECK_EQ(TestConnectJob::kMockJob, next_job_type);
Bence Békya4a50932018-08-10 13:39:411792 nested_callback->callback().Run(rv);
mmenke33d24423d2015-05-19 19:41:091793 } else {
1794 DCHECK_EQ(TestConnectJob::kMockPendingJob, next_job_type);
[email protected]6ecf2b92011-12-15 01:14:521795 }
mmenke33d24423d2015-05-19 19:41:091796}
[email protected]f6d1d6eb2009-06-24 20:16:091797
mmenke33d24423d2015-05-19 19:41:091798// Tests the case where a second socket is requested in a completion callback,
1799// and the second socket connects asynchronously. Reuses the same
1800// ClientSocketHandle for the second socket, after disconnecting the first.
[email protected]2ab05b52009-07-01 23:57:581801TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531802 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201803
[email protected]0b7648c2009-07-06 20:14:011804 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061805 ClientSocketHandle handle;
mmenke33d24423d2015-05-19 19:41:091806 TestCompletionCallback second_result_callback;
1807 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:281808 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Paul Jensen8d6f87ec2018-01-13 00:46:541809 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501810 base::BindOnce(&RequestSocketOnComplete, &handle, pool_.get(),
1811 connect_job_factory_, TestConnectJob::kMockPendingJob,
1812 &second_result_callback),
1813 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011814 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091815
robpercival214763f2016-07-01 23:27:011816 EXPECT_THAT(second_result_callback.WaitForResult(), IsOk());
[email protected]2ab05b52009-07-01 23:57:581817}
[email protected]f6d1d6eb2009-06-24 20:16:091818
mmenke33d24423d2015-05-19 19:41:091819// Tests the case where a second socket is requested in a completion callback,
1820// and the second socket connects synchronously. Reuses the same
1821// ClientSocketHandle for the second socket, after disconnecting the first.
[email protected]2ab05b52009-07-01 23:57:581822TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531823 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201824
[email protected]0b7648c2009-07-06 20:14:011825 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061826 ClientSocketHandle handle;
mmenke33d24423d2015-05-19 19:41:091827 TestCompletionCallback second_result_callback;
1828 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:281829 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Paul Jensen8d6f87ec2018-01-13 00:46:541830 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501831 base::BindOnce(&RequestSocketOnComplete, &handle, pool_.get(),
1832 connect_job_factory_, TestConnectJob::kMockPendingJob,
1833 &second_result_callback),
1834 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011835 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2ab05b52009-07-01 23:57:581836
robpercival214763f2016-07-01 23:27:011837 EXPECT_THAT(second_result_callback.WaitForResult(), IsOk());
[email protected]f6d1d6eb2009-06-24 20:16:091838}
1839
1840// Make sure that pending requests get serviced after active requests get
1841// cancelled.
[email protected]ab838892009-06-30 18:49:051842TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531843 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201844
[email protected]0b7648c2009-07-06 20:14:011845 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091846
Matt Menkec6b3edf72019-03-19 17:00:391847 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1848 IsError(ERR_IO_PENDING));
1849 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1850 IsError(ERR_IO_PENDING));
1851 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1852 IsError(ERR_IO_PENDING));
1853 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1854 IsError(ERR_IO_PENDING));
1855 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1856 IsError(ERR_IO_PENDING));
1857 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1858 IsError(ERR_IO_PENDING));
1859 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1860 IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091861
[email protected]c9d6a1d2009-07-14 16:15:201862 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1863 // Let's cancel them.
1864 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]2431756e2010-09-29 20:26:131865 ASSERT_FALSE(request(i)->handle()->is_initialized());
1866 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091867 }
1868
[email protected]f6d1d6eb2009-06-24 20:16:091869 // Let's wait for the rest to complete now.
[email protected]2431756e2010-09-29 20:26:131870 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i) {
robpercival214763f2016-07-01 23:27:011871 EXPECT_THAT(request(i)->WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:131872 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091873 }
1874
[email protected]2431756e2010-09-29 20:26:131875 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1876 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091877}
1878
1879// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051880TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531881 const size_t kMaxSockets = 5;
1882 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201883
[email protected]0b7648c2009-07-06 20:14:011884 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091885
[email protected]211d21722009-07-22 15:48:531886 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1887 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091888
1889 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531890 for (size_t i = 0; i < kNumberOfRequests; ++i)
Matt Menkec6b3edf72019-03-19 17:00:391891 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1892 IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091893
[email protected]211d21722009-07-22 15:48:531894 for (size_t i = 0; i < kNumberOfRequests; ++i)
robpercival214763f2016-07-01 23:27:011895 EXPECT_THAT(request(i)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]f6d1d6eb2009-06-24 20:16:091896}
1897
mmenke9d72fe42017-05-18 22:36:071898// Make sure that pending requests that complete synchronously get serviced
1899// after active requests fail. See https://crbug.com/723748
1900TEST_F(ClientSocketPoolBaseTest, HandleMultipleSyncFailuresAfterAsyncFailure) {
1901 const size_t kNumberOfRequests = 10;
1902 const size_t kMaxSockets = 1;
1903 CreatePool(kMaxSockets, kMaxSockets);
1904
1905 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1906
Matt Menkec6b3edf72019-03-19 17:00:391907 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1908 IsError(ERR_IO_PENDING));
mmenke9d72fe42017-05-18 22:36:071909
1910 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
1911
1912 // Queue up all the other requests
1913 for (size_t i = 1; i < kNumberOfRequests; ++i)
Matt Menkec6b3edf72019-03-19 17:00:391914 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1915 IsError(ERR_IO_PENDING));
mmenke9d72fe42017-05-18 22:36:071916
1917 // Make sure all requests fail, instead of hanging.
1918 for (size_t i = 0; i < kNumberOfRequests; ++i)
1919 EXPECT_THAT(request(i)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
1920}
1921
[email protected]5fc08e32009-07-15 17:09:571922TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531923 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571924
1925 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1926
[email protected]2431756e2010-09-29 20:26:131927 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521928 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:501929 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:281930 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:501931 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1932 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011933 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:571934
1935 // Cancel the active request.
[email protected]2431756e2010-09-29 20:26:131936 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571937
Matt Menkef09e64c2019-04-23 22:16:281938 rv = handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
1939 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501940 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1941 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011942 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1943 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]5fc08e32009-07-15 17:09:571944
[email protected]2431756e2010-09-29 20:26:131945 EXPECT_FALSE(handle.is_reused());
[email protected]034df0f32013-01-07 23:17:481946 TestLoadTimingInfoConnectedNotReused(handle);
[email protected]5fc08e32009-07-15 17:09:571947 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1948}
1949
xunjieli26619e72016-11-23 19:39:551950TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsForced) {
Matt Menke433de6d2020-03-04 00:24:111951 const char kReason[] = "Really nifty reason";
1952
xunjieli26619e72016-11-23 19:39:551953 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1954 ClientSocketHandle handle;
1955 TestCompletionCallback callback;
Matt Muellerd9342e3a2019-11-26 01:41:141956 RecordingBoundTestNetLog log;
Matt Menke28ac03e2019-02-25 22:25:501957 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:281958 TestGroupId("a"), params_, base::nullopt, LOWEST, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:501959 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1960 ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound());
xunjieli26619e72016-11-23 19:39:551961 EXPECT_THAT(rv, IsOk());
Matt Menke433de6d2020-03-04 00:24:111962 ASSERT_TRUE(handle.socket());
1963 NetLogSource source = handle.socket()->NetLog().source();
xunjieli26619e72016-11-23 19:39:551964 handle.Reset();
1965 EXPECT_EQ(1, pool_->IdleSocketCount());
Matt Menke433de6d2020-03-04 00:24:111966 pool_->CloseIdleSockets(kReason);
1967 ExpectSocketClosedWithReason(source, kReason);
xunjieli26619e72016-11-23 19:39:551968}
1969
xunjieli92feb332017-03-03 17:19:231970TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsInGroupForced) {
xunjieli92feb332017-03-03 17:19:231971 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1972 TestCompletionCallback callback;
Matt Muellerd9342e3a2019-11-26 01:41:141973 RecordingBoundTestNetLog log;
xunjieli92feb332017-03-03 17:19:231974 ClientSocketHandle handle1;
Matt Menke28ac03e2019-02-25 22:25:501975 int rv = handle1.Init(
Matt Menkef09e64c2019-04-23 22:16:281976 TestGroupId("a"), params_, base::nullopt, LOWEST, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:501977 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1978 ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound());
xunjieli92feb332017-03-03 17:19:231979 EXPECT_THAT(rv, IsOk());
1980 ClientSocketHandle handle2;
Matt Menkef09e64c2019-04-23 22:16:281981 rv = handle2.Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
1982 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501983 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1984 pool_.get(), log.bound());
xunjieli92feb332017-03-03 17:19:231985 ClientSocketHandle handle3;
Matt Menkef09e64c2019-04-23 22:16:281986 rv = handle3.Init(TestGroupId("b"), params_, base::nullopt, LOWEST,
1987 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501988 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1989 pool_.get(), log.bound());
xunjieli92feb332017-03-03 17:19:231990 EXPECT_THAT(rv, IsOk());
1991 handle1.Reset();
1992 handle2.Reset();
1993 handle3.Reset();
1994 EXPECT_EQ(3, pool_->IdleSocketCount());
Matt Menke433de6d2020-03-04 00:24:111995 pool_->CloseIdleSocketsInGroup(TestGroupId("a"), "Very good reason");
xunjieli92feb332017-03-03 17:19:231996 EXPECT_EQ(1, pool_->IdleSocketCount());
xunjieli92feb332017-03-03 17:19:231997}
1998
xunjieli26619e72016-11-23 19:39:551999TEST_F(ClientSocketPoolBaseTest, CleanUpUnusableIdleSockets) {
xunjieli26619e72016-11-23 19:39:552000 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2001 ClientSocketHandle handle;
2002 TestCompletionCallback callback;
Matt Muellerd9342e3a2019-11-26 01:41:142003 RecordingBoundTestNetLog log;
Matt Menke28ac03e2019-02-25 22:25:502004 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:282005 TestGroupId("a"), params_, base::nullopt, LOWEST, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502006 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2007 ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound());
xunjieli26619e72016-11-23 19:39:552008 EXPECT_THAT(rv, IsOk());
2009 StreamSocket* socket = handle.socket();
Matt Menke433de6d2020-03-04 00:24:112010 ASSERT_TRUE(socket);
xunjieli26619e72016-11-23 19:39:552011 handle.Reset();
2012 EXPECT_EQ(1, pool_->IdleSocketCount());
2013
2014 // Disconnect socket now to make the socket unusable.
Matt Menke433de6d2020-03-04 00:24:112015 NetLogSource source = socket->NetLog().source();
xunjieli26619e72016-11-23 19:39:552016 socket->Disconnect();
2017 ClientSocketHandle handle2;
Matt Menkef09e64c2019-04-23 22:16:282018 rv = handle2.Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
2019 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502020 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2021 pool_.get(), log.bound());
xunjieli26619e72016-11-23 19:39:552022 EXPECT_THAT(rv, IsOk());
2023 EXPECT_FALSE(handle2.is_reused());
Matt Menke433de6d2020-03-04 00:24:112024
2025 // This is admittedly not an accurate error in this case, but normally code
2026 // doesn't secretly keep a raw pointers to sockets returned to the socket pool
2027 // and close them out of band, so discovering an idle socket was closed when
2028 // trying to reuse it normally means it was closed by the remote side.
2029 ExpectSocketClosedWithReason(
2030 source, TransportClientSocketPool::kRemoteSideClosedConnection);
xunjieli26619e72016-11-23 19:39:552031}
2032
[email protected]2b7523d2009-07-29 20:29:232033// Regression test for http://crbug.com/17985.
2034TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
2035 const int kMaxSockets = 3;
2036 const int kMaxSocketsPerGroup = 2;
2037 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
2038
[email protected]ac790b42009-12-02 04:31:312039 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:232040
Matt Menkec6b3edf72019-03-19 17:00:392041 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
2042 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
[email protected]2b7523d2009-07-29 20:29:232043
2044 // This is going to be a pending request in an otherwise empty group.
Matt Menkec6b3edf72019-03-19 17:00:392045 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2046 IsError(ERR_IO_PENDING));
[email protected]2b7523d2009-07-29 20:29:232047
2048 // Reach the maximum socket limit.
Matt Menkec6b3edf72019-03-19 17:00:392049 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
[email protected]2b7523d2009-07-29 20:29:232050
2051 // Create a stalled group with high priorities.
Matt Menkec6b3edf72019-03-19 17:00:392052 EXPECT_THAT(StartRequest(TestGroupId("c"), kHighPriority),
2053 IsError(ERR_IO_PENDING));
2054 EXPECT_THAT(StartRequest(TestGroupId("c"), kHighPriority),
2055 IsError(ERR_IO_PENDING));
[email protected]2b7523d2009-07-29 20:29:232056
Matt Menkec6b3edf72019-03-19 17:00:392057 // Release the first two sockets from TestGroupId("a"). Because this is a
2058 // keepalive, the first release will unblock the pending request for
2059 // TestGroupId("a"). The second release will unblock a request for "c",
2060 // because it is the next high priority socket.
[email protected]2431756e2010-09-29 20:26:132061 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
2062 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]2b7523d2009-07-29 20:29:232063
2064 // Closing idle sockets should not get us into trouble, but in the bug
2065 // we were hitting a CHECK here.
Matt Menkec6b3edf72019-03-19 17:00:392066 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menke433de6d2020-03-04 00:24:112067 pool_->CloseIdleSockets("Very good reason");
[email protected]eb5a99382010-07-11 03:18:262068
[email protected]2da659e2013-05-23 20:51:342069 // Run the released socket wakeups.
fdoray5eeb7642016-06-22 16:11:282070 base::RunLoop().RunUntilIdle();
[email protected]2b7523d2009-07-29 20:29:232071}
2072
[email protected]4d3b05d2010-01-27 21:27:292073TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:532074 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:572075
2076 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:132077 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522078 TestCompletionCallback callback;
Matt Muellerd9342e3a2019-11-26 01:41:142079 RecordingBoundTestNetLog log;
Matt Menke28ac03e2019-02-25 22:25:502080 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:282081 TestGroupId("a"), params_, base::nullopt, LOWEST, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502082 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2083 ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound());
robpercival214763f2016-07-01 23:27:012084 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Matt Menkec6b3edf72019-03-19 17:00:392085 EXPECT_EQ(LOAD_STATE_CONNECTING,
2086 pool_->GetLoadState(TestGroupId("a"), &handle));
[email protected]034df0f32013-01-07 23:17:482087 TestLoadTimingInfoNotConnected(handle);
2088
robpercival214763f2016-07-01 23:27:012089 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132090 EXPECT_TRUE(handle.is_initialized());
2091 EXPECT_TRUE(handle.socket());
[email protected]034df0f32013-01-07 23:17:482092 TestLoadTimingInfoConnectedNotReused(handle);
2093
[email protected]2431756e2010-09-29 20:26:132094 handle.Reset();
[email protected]034df0f32013-01-07 23:17:482095 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:302096
Eric Roman79cc7552019-07-19 02:17:542097 auto entries = log.GetEntries();
[email protected]b2fcd0e2010-12-01 15:19:402098
Matt Menke9fa17d52019-03-25 19:12:262099 EXPECT_EQ(5u, entries.size());
[email protected]06650c52010-06-03 00:49:172100 EXPECT_TRUE(LogContainsEvent(
Matt Menke9fa17d52019-03-25 19:12:262101 entries, 0, NetLogEventType::TCP_CLIENT_SOCKET_POOL_REQUESTED_SOCKET,
mikecirone8b85c432016-09-08 19:11:002102 NetLogEventPhase::NONE));
Matt Menke9fa17d52019-03-25 19:12:262103 EXPECT_TRUE(LogContainsBeginEvent(entries, 1, NetLogEventType::SOCKET_POOL));
2104 EXPECT_TRUE(LogContainsEvent(
2105 entries, 2, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
2106 NetLogEventPhase::NONE));
2107 EXPECT_TRUE(LogContainsEvent(entries, 3,
mikecirone8b85c432016-09-08 19:11:002108 NetLogEventType::SOCKET_POOL_BOUND_TO_SOCKET,
2109 NetLogEventPhase::NONE));
Matt Menke9fa17d52019-03-25 19:12:262110 EXPECT_TRUE(LogContainsEndEvent(entries, 4, NetLogEventType::SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:572111}
2112
[email protected]4d3b05d2010-01-27 21:27:292113TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:572114 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:532115 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:572116
2117 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]2431756e2010-09-29 20:26:132118 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522119 TestCompletionCallback callback;
Matt Muellerd9342e3a2019-11-26 01:41:142120 RecordingBoundTestNetLog log;
[email protected]e60e47a2010-07-14 03:37:182121 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:132122 handle.set_is_ssl_error(true);
Matt Menke39b7c5a2019-04-10 19:47:512123 handle.set_ssl_cert_request_info(base::MakeRefCounted<SSLCertRequestInfo>());
Matt Menke28ac03e2019-02-25 22:25:502124 EXPECT_EQ(
2125 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:282126 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2127 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2128 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2129 pool_.get(), log.bound()));
Matt Menkec6b3edf72019-03-19 17:00:392130 EXPECT_EQ(LOAD_STATE_CONNECTING,
2131 pool_->GetLoadState(TestGroupId("a"), &handle));
robpercival214763f2016-07-01 23:27:012132 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]2431756e2010-09-29 20:26:132133 EXPECT_FALSE(handle.is_ssl_error());
Matt Menke39b7c5a2019-04-10 19:47:512134 EXPECT_FALSE(handle.ssl_cert_request_info());
[email protected]fd7b7c92009-08-20 19:38:302135
Eric Roman79cc7552019-07-19 02:17:542136 auto entries = log.GetEntries();
[email protected]b2fcd0e2010-12-01 15:19:402137
Matt Menke9fa17d52019-03-25 19:12:262138 EXPECT_EQ(4u, entries.size());
[email protected]06650c52010-06-03 00:49:172139 EXPECT_TRUE(LogContainsEvent(
Matt Menke9fa17d52019-03-25 19:12:262140 entries, 0, NetLogEventType::TCP_CLIENT_SOCKET_POOL_REQUESTED_SOCKET,
mikecirone8b85c432016-09-08 19:11:002141 NetLogEventPhase::NONE));
Matt Menke9fa17d52019-03-25 19:12:262142 EXPECT_TRUE(LogContainsBeginEvent(entries, 1, NetLogEventType::SOCKET_POOL));
2143 EXPECT_TRUE(LogContainsEvent(
2144 entries, 2, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
2145 NetLogEventPhase::NONE));
2146 EXPECT_TRUE(LogContainsEndEvent(entries, 3, NetLogEventType::SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:572147}
2148
mmenke6be122f2015-03-09 22:22:472149// Check that an async ConnectJob failure does not result in creation of a new
2150// ConnectJob when there's another pending request also waiting on its own
2151// ConnectJob. See http://crbug.com/463960.
2152TEST_F(ClientSocketPoolBaseTest, AsyncFailureWithPendingRequestWithJob) {
2153 CreatePool(2, 2);
2154 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2155
Matt Menkec6b3edf72019-03-19 17:00:392156 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2157 IsError(ERR_IO_PENDING));
2158 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2159 IsError(ERR_IO_PENDING));
mmenke6be122f2015-03-09 22:22:472160
robpercival214763f2016-07-01 23:27:012161 EXPECT_THAT(request(0)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
2162 EXPECT_THAT(request(1)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
mmenke6be122f2015-03-09 22:22:472163
2164 EXPECT_EQ(2, client_socket_factory_.allocation_count());
2165}
2166
[email protected]4d3b05d2010-01-27 21:27:292167TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]b22b5162010-03-16 07:53:102168 // TODO(eroman): Add back the log expectations! Removed them because the
2169 // ordering is difficult, and some may fire during destructor.
[email protected]211d21722009-07-22 15:48:532170 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:572171
2172 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:132173 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522174 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132175 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522176 TestCompletionCallback callback2;
[email protected]5fc08e32009-07-15 17:09:572177
Matt Menke28ac03e2019-02-25 22:25:502178 EXPECT_EQ(
2179 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:282180 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2181 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2182 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2183 pool_.get(), NetLogWithSource()));
Matt Muellerd9342e3a2019-11-26 01:41:142184 RecordingBoundTestNetLog log2;
tfarina428341112016-09-22 13:38:202185 EXPECT_EQ(
2186 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:282187 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2188 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502189 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2190 pool_.get(), NetLogWithSource()));
[email protected]5fc08e32009-07-15 17:09:572191
[email protected]2431756e2010-09-29 20:26:132192 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:572193
[email protected]fd7b7c92009-08-20 19:38:302194
2195 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]fd7b7c92009-08-20 19:38:302196
robpercival214763f2016-07-01 23:27:012197 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132198 handle2.Reset();
[email protected]fd7b7c92009-08-20 19:38:302199
2200 // Now request 2 has actually finished.
[email protected]9e743cd2010-03-16 07:03:532201 // TODO(eroman): Add back log expectations.
[email protected]5fc08e32009-07-15 17:09:572202}
2203
[email protected]4d3b05d2010-01-27 21:27:292204TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:342205 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2206
[email protected]17a0c6c2009-08-04 00:07:042207 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2208
Matt Menkec6b3edf72019-03-19 17:00:392209 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
2210 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsError(ERR_IO_PENDING));
2211 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
2212 EXPECT_THAT(StartRequest(TestGroupId("a"), HIGHEST), IsError(ERR_IO_PENDING));
[email protected]974ebd62009-08-03 23:14:342213
Raul Tambre8335a6d2019-02-21 16:57:432214 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
Matt Menke9fa17d52019-03-25 19:12:262215 static_cast<int>(
2216 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))));
[email protected]2431756e2010-09-29 20:26:132217 (*requests())[2]->handle()->Reset();
2218 (*requests())[3]->handle()->Reset();
Raul Tambre8335a6d2019-02-21 16:57:432219 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
Matt Menke9fa17d52019-03-25 19:12:262220 static_cast<int>(
2221 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))));
[email protected]974ebd62009-08-03 23:14:342222
[email protected]2431756e2010-09-29 20:26:132223 (*requests())[1]->handle()->Reset();
Raul Tambre8335a6d2019-02-21 16:57:432224 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
Matt Menke9fa17d52019-03-25 19:12:262225 static_cast<int>(
2226 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))));
[email protected]974ebd62009-08-03 23:14:342227
[email protected]2431756e2010-09-29 20:26:132228 (*requests())[0]->handle()->Reset();
Raul Tambre8335a6d2019-02-21 16:57:432229 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
Matt Menke9fa17d52019-03-25 19:12:262230 static_cast<int>(
2231 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))));
[email protected]974ebd62009-08-03 23:14:342232}
2233
[email protected]5fc08e32009-07-15 17:09:572234// When requests and ConnectJobs are not coupled, the request will get serviced
2235// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:292236TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:532237 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:572238
2239 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:322240 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:572241
[email protected]2431756e2010-09-29 20:26:132242 std::vector<TestSocketRequest*> request_order;
2243 size_t completion_count; // unused
2244 TestSocketRequest req1(&request_order, &completion_count);
Matt Menke28ac03e2019-02-25 22:25:502245 int rv = req1.handle()->Init(
Matt Menkef09e64c2019-04-23 22:16:282246 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502247 ClientSocketPool::RespectLimits::ENABLED, req1.callback(),
2248 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012249 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2250 EXPECT_THAT(req1.WaitForResult(), IsOk());
[email protected]5fc08e32009-07-15 17:09:572251
2252 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
2253 // without a job.
2254 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2255
[email protected]2431756e2010-09-29 20:26:132256 TestSocketRequest req2(&request_order, &completion_count);
Matt Menke28ac03e2019-02-25 22:25:502257 rv = req2.handle()->Init(
Matt Menkef09e64c2019-04-23 22:16:282258 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502259 ClientSocketPool::RespectLimits::ENABLED, req2.callback(),
2260 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012261 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2431756e2010-09-29 20:26:132262 TestSocketRequest req3(&request_order, &completion_count);
Matt Menke28ac03e2019-02-25 22:25:502263 rv = req3.handle()->Init(
Matt Menkef09e64c2019-04-23 22:16:282264 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502265 ClientSocketPool::RespectLimits::ENABLED, req3.callback(),
2266 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012267 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:572268
2269 // Both Requests 2 and 3 are pending. We release socket 1 which should
2270 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:332271 req1.handle()->Reset();
[email protected]2da659e2013-05-23 20:51:342272 // Run the released socket wakeups.
fdoray5eeb7642016-06-22 16:11:282273 base::RunLoop().RunUntilIdle();
[email protected]a6c59f62009-07-29 16:33:332274 ASSERT_TRUE(req2.handle()->socket());
robpercival214763f2016-07-01 23:27:012275 EXPECT_THAT(req2.WaitForResult(), IsOk());
[email protected]a6c59f62009-07-29 16:33:332276 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:572277
2278 // Signal job 2, which should service request 3.
2279
2280 client_socket_factory_.SignalJobs();
robpercival214763f2016-07-01 23:27:012281 EXPECT_THAT(req3.WaitForResult(), IsOk());
[email protected]5fc08e32009-07-15 17:09:572282
Raul Tambre8335a6d2019-02-21 16:57:432283 ASSERT_EQ(3u, request_order.size());
[email protected]2431756e2010-09-29 20:26:132284 EXPECT_EQ(&req1, request_order[0]);
2285 EXPECT_EQ(&req2, request_order[1]);
2286 EXPECT_EQ(&req3, request_order[2]);
Matt Menkec6b3edf72019-03-19 17:00:392287 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]5fc08e32009-07-15 17:09:572288}
2289
2290// The requests are not coupled to the jobs. So, the requests should finish in
2291// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:292292TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:532293 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:572294 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:322295 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:572296
[email protected]2431756e2010-09-29 20:26:132297 std::vector<TestSocketRequest*> request_order;
2298 size_t completion_count; // unused
2299 TestSocketRequest req1(&request_order, &completion_count);
Matt Menke28ac03e2019-02-25 22:25:502300 int rv = req1.handle()->Init(
Matt Menkef09e64c2019-04-23 22:16:282301 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502302 ClientSocketPool::RespectLimits::ENABLED, req1.callback(),
2303 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012304 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:572305
[email protected]2431756e2010-09-29 20:26:132306 TestSocketRequest req2(&request_order, &completion_count);
Matt Menke28ac03e2019-02-25 22:25:502307 rv = req2.handle()->Init(
Matt Menkef09e64c2019-04-23 22:16:282308 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502309 ClientSocketPool::RespectLimits::ENABLED, req2.callback(),
2310 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012311 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:572312
2313 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:322314 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:572315
[email protected]2431756e2010-09-29 20:26:132316 TestSocketRequest req3(&request_order, &completion_count);
Matt Menke28ac03e2019-02-25 22:25:502317 rv = req3.handle()->Init(
Matt Menkef09e64c2019-04-23 22:16:282318 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502319 ClientSocketPool::RespectLimits::ENABLED, req3.callback(),
2320 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012321 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:572322
robpercival214763f2016-07-01 23:27:012323 EXPECT_THAT(req1.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
2324 EXPECT_THAT(req2.WaitForResult(), IsOk());
2325 EXPECT_THAT(req3.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]5fc08e32009-07-15 17:09:572326
Raul Tambre8335a6d2019-02-21 16:57:432327 ASSERT_EQ(3u, request_order.size());
[email protected]2431756e2010-09-29 20:26:132328 EXPECT_EQ(&req1, request_order[0]);
2329 EXPECT_EQ(&req2, request_order[1]);
2330 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:572331}
2332
[email protected]03b7c8c2013-07-20 04:38:552333// Test GetLoadState in the case there's only one socket request.
2334TEST_F(ClientSocketPoolBaseTest, LoadStateOneRequest) {
[email protected]211d21722009-07-22 15:48:532335 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]03b7c8c2013-07-20 04:38:552336 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
[email protected]5fc08e32009-07-15 17:09:572337
[email protected]2431756e2010-09-29 20:26:132338 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522339 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502340 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:282341 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502342 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2343 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012344 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552345 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:572346
[email protected]03b7c8c2013-07-20 04:38:552347 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2348 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
2349
2350 // No point in completing the connection, since ClientSocketHandles only
2351 // expect the LoadState to be checked while connecting.
2352}
2353
2354// Test GetLoadState in the case there are two socket requests.
2355TEST_F(ClientSocketPoolBaseTest, LoadStateTwoRequests) {
2356 CreatePool(2, 2);
2357 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2358
2359 ClientSocketHandle handle;
2360 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502361 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:282362 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502363 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2364 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012365 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
haavardm835c1d62015-04-22 08:18:002366 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_RESOLVING_HOST);
2367
2368 ClientSocketHandle handle2;
2369 TestCompletionCallback callback2;
Matt Menkef09e64c2019-04-23 22:16:282370 rv = handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2371 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502372 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2373 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012374 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
haavardm835c1d62015-04-22 08:18:002375 client_socket_factory_.SetJobLoadState(1, LOAD_STATE_RESOLVING_HOST);
2376
Matt Menke4b69f932019-03-04 16:20:012377 // Each handle should reflect the state of its own job.
haavardm835c1d62015-04-22 08:18:002378 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle.GetLoadState());
2379 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle2.GetLoadState());
2380
Matt Menke4b69f932019-03-04 16:20:012381 // Update the state of the first job.
haavardm835c1d62015-04-22 08:18:002382 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_CONNECTING);
2383
Matt Menke4b69f932019-03-04 16:20:012384 // Only the state of the first request should have changed.
haavardm835c1d62015-04-22 08:18:002385 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
haavardm835c1d62015-04-22 08:18:002386 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle2.GetLoadState());
Matt Menke4b69f932019-03-04 16:20:012387
2388 // Update the state of the second job.
2389 client_socket_factory_.SetJobLoadState(1, LOAD_STATE_SSL_HANDSHAKE);
2390
2391 // Only the state of the second request should have changed.
2392 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2393 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle2.GetLoadState());
2394
2395 // Second job connects and the first request gets the socket. The
2396 // second handle switches to the state of the remaining ConnectJob.
2397 client_socket_factory_.SignalJob(1);
2398 EXPECT_THAT(callback.WaitForResult(), IsOk());
2399 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
[email protected]03b7c8c2013-07-20 04:38:552400}
2401
2402// Test GetLoadState in the case the per-group limit is reached.
2403TEST_F(ClientSocketPoolBaseTest, LoadStateGroupLimit) {
2404 CreatePool(2, 1);
2405 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2406
2407 ClientSocketHandle handle;
2408 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502409 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:282410 TestGroupId("a"), params_, base::nullopt, MEDIUM, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502411 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2412 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012413 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552414 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2415
2416 // Request another socket from the same pool, buth with a higher priority.
2417 // The first request should now be stalled at the socket group limit.
2418 ClientSocketHandle handle2;
2419 TestCompletionCallback callback2;
Matt Menkef09e64c2019-04-23 22:16:282420 rv = handle2.Init(TestGroupId("a"), params_, base::nullopt, HIGHEST,
2421 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502422 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2423 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012424 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552425 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2426 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
2427
2428 // The first handle should remain stalled as the other socket goes through
2429 // the connect process.
2430
2431 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2432 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2433 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle2.GetLoadState());
2434
2435 client_socket_factory_.SignalJob(0);
robpercival214763f2016-07-01 23:27:012436 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]03b7c8c2013-07-20 04:38:552437 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2438
2439 // Closing the second socket should cause the stalled handle to finally get a
2440 // ConnectJob.
2441 handle2.socket()->Disconnect();
2442 handle2.Reset();
2443 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2444}
2445
2446// Test GetLoadState in the case the per-pool limit is reached.
2447TEST_F(ClientSocketPoolBaseTest, LoadStatePoolLimit) {
2448 CreatePool(2, 2);
2449 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2450
2451 ClientSocketHandle handle;
2452 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502453 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:282454 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502455 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2456 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012457 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552458
2459 // Request for socket from another pool.
2460 ClientSocketHandle handle2;
2461 TestCompletionCallback callback2;
Matt Menkef09e64c2019-04-23 22:16:282462 rv = handle2.Init(TestGroupId("b"), params_, base::nullopt, DEFAULT_PRIORITY,
2463 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502464 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2465 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012466 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552467
2468 // Request another socket from the first pool. Request should stall at the
2469 // socket pool limit.
2470 ClientSocketHandle handle3;
2471 TestCompletionCallback callback3;
Matt Menkef09e64c2019-04-23 22:16:282472 rv = handle3.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2473 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502474 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2475 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012476 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552477
2478 // The third handle should remain stalled as the other sockets in its group
2479 // goes through the connect process.
2480
2481 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2482 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2483
2484 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2485 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
2486 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2487
2488 client_socket_factory_.SignalJob(0);
robpercival214763f2016-07-01 23:27:012489 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]03b7c8c2013-07-20 04:38:552490 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2491
2492 // Closing a socket should allow the stalled handle to finally get a new
2493 // ConnectJob.
2494 handle.socket()->Disconnect();
2495 handle.Reset();
2496 EXPECT_EQ(LOAD_STATE_CONNECTING, handle3.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:572497}
2498
Matt Menkeb57663b32019-03-01 17:17:102499TEST_F(ClientSocketPoolBaseTest, CertError) {
[email protected]e772db3f2010-07-12 18:11:132500 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
Matt Menkeb57663b32019-03-01 17:17:102501 connect_job_factory_->set_job_type(TestConnectJob::kMockCertErrorJob);
[email protected]e772db3f2010-07-12 18:11:132502
[email protected]2431756e2010-09-29 20:26:132503 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522504 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502505 EXPECT_EQ(
Matt Menkeb57663b32019-03-01 17:17:102506 ERR_CERT_COMMON_NAME_INVALID,
Matt Menkef09e64c2019-04-23 22:16:282507 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2508 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2509 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2510 pool_.get(), NetLogWithSource()));
[email protected]2431756e2010-09-29 20:26:132511 EXPECT_TRUE(handle.is_initialized());
2512 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:132513}
2514
Matt Menkeb57663b32019-03-01 17:17:102515TEST_F(ClientSocketPoolBaseTest, AsyncCertError) {
[email protected]e772db3f2010-07-12 18:11:132516 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2517
Matt Menkeb57663b32019-03-01 17:17:102518 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingCertErrorJob);
[email protected]2431756e2010-09-29 20:26:132519 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522520 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502521 EXPECT_EQ(
2522 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:282523 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2524 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2525 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2526 pool_.get(), NetLogWithSource()));
Matt Menkec6b3edf72019-03-19 17:00:392527 EXPECT_EQ(LOAD_STATE_CONNECTING,
2528 pool_->GetLoadState(TestGroupId("a"), &handle));
Matt Menkeb57663b32019-03-01 17:17:102529 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CERT_COMMON_NAME_INVALID));
[email protected]2431756e2010-09-29 20:26:132530 EXPECT_TRUE(handle.is_initialized());
2531 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:132532}
2533
[email protected]e60e47a2010-07-14 03:37:182534TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) {
2535 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2536 connect_job_factory_->set_job_type(
2537 TestConnectJob::kMockAdditionalErrorStateJob);
2538
[email protected]2431756e2010-09-29 20:26:132539 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522540 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502541 EXPECT_EQ(
2542 ERR_CONNECTION_FAILED,
Matt Menkef09e64c2019-04-23 22:16:282543 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2544 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2545 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2546 pool_.get(), NetLogWithSource()));
[email protected]2431756e2010-09-29 20:26:132547 EXPECT_FALSE(handle.is_initialized());
2548 EXPECT_FALSE(handle.socket());
2549 EXPECT_TRUE(handle.is_ssl_error());
Matt Menke39b7c5a2019-04-10 19:47:512550 EXPECT_TRUE(handle.ssl_cert_request_info());
[email protected]e60e47a2010-07-14 03:37:182551}
2552
2553TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) {
2554 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2555
2556 connect_job_factory_->set_job_type(
2557 TestConnectJob::kMockPendingAdditionalErrorStateJob);
[email protected]2431756e2010-09-29 20:26:132558 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522559 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502560 EXPECT_EQ(
2561 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:282562 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2563 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2564 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2565 pool_.get(), NetLogWithSource()));
Matt Menkec6b3edf72019-03-19 17:00:392566 EXPECT_EQ(LOAD_STATE_CONNECTING,
2567 pool_->GetLoadState(TestGroupId("a"), &handle));
robpercival214763f2016-07-01 23:27:012568 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]2431756e2010-09-29 20:26:132569 EXPECT_FALSE(handle.is_initialized());
2570 EXPECT_FALSE(handle.socket());
2571 EXPECT_TRUE(handle.is_ssl_error());
Matt Menke39b7c5a2019-04-10 19:47:512572 EXPECT_TRUE(handle.ssl_cert_request_info());
[email protected]e60e47a2010-07-14 03:37:182573}
2574
martijn003cd612016-05-19 22:24:382575// Make sure we can reuse sockets.
2576TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSocketsReuse) {
[email protected]64770b7d2011-11-16 04:30:412577 CreatePoolWithIdleTimeouts(
2578 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
[email protected]e7b1c6d2c2012-05-05 00:54:032579 base::TimeDelta(), // Time out unused sockets immediately.
2580 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2581
2582 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2583
2584 ClientSocketHandle handle;
2585 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502586 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:282587 TestGroupId("a"), params_, base::nullopt, LOWEST, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502588 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2589 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012590 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
Matt Menkec6b3edf72019-03-19 17:00:392591 EXPECT_EQ(LOAD_STATE_CONNECTING,
2592 pool_->GetLoadState(TestGroupId("a"), &handle));
robpercival214763f2016-07-01 23:27:012593 ASSERT_THAT(callback.WaitForResult(), IsOk());
[email protected]e7b1c6d2c2012-05-05 00:54:032594
2595 // Use and release the socket.
Raul Tambre94493c652019-03-11 17:18:352596 EXPECT_EQ(1, handle.socket()->Write(nullptr, 1, CompletionOnceCallback(),
Ramin Halavati0a08cc82018-02-06 07:46:382597 TRAFFIC_ANNOTATION_FOR_TESTS));
[email protected]034df0f32013-01-07 23:17:482598 TestLoadTimingInfoConnectedNotReused(handle);
[email protected]e7b1c6d2c2012-05-05 00:54:032599 handle.Reset();
2600
2601 // Should now have one idle socket.
2602 ASSERT_EQ(1, pool_->IdleSocketCount());
2603
2604 // Request a new socket. This should reuse the old socket and complete
2605 // synchronously.
Matt Muellerd9342e3a2019-11-26 01:41:142606 RecordingBoundTestNetLog log;
Matt Menke28ac03e2019-02-25 22:25:502607 rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:282608 TestGroupId("a"), params_, base::nullopt, LOWEST, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502609 ClientSocketPool::RespectLimits::ENABLED, CompletionOnceCallback(),
2610 ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound());
robpercival214763f2016-07-01 23:27:012611 ASSERT_THAT(rv, IsOk());
[email protected]e7b1c6d2c2012-05-05 00:54:032612 EXPECT_TRUE(handle.is_reused());
[email protected]034df0f32013-01-07 23:17:482613 TestLoadTimingInfoConnectedReused(handle);
[email protected]e7b1c6d2c2012-05-05 00:54:032614
Matt Menke9fa17d52019-03-25 19:12:262615 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:392616 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menke9fa17d52019-03-25 19:12:262617 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
[email protected]e7b1c6d2c2012-05-05 00:54:032618
Eric Roman79cc7552019-07-19 02:17:542619 auto entries = log.GetEntries();
Matt Menke9fa17d52019-03-25 19:12:262620 EXPECT_TRUE(LogContainsEvent(
2621 entries, 0, NetLogEventType::TCP_CLIENT_SOCKET_POOL_REQUESTED_SOCKET,
2622 NetLogEventPhase::NONE));
2623 EXPECT_TRUE(LogContainsBeginEvent(entries, 1, NetLogEventType::SOCKET_POOL));
[email protected]e7b1c6d2c2012-05-05 00:54:032624 EXPECT_TRUE(LogContainsEntryWithType(
Matt Menke9fa17d52019-03-25 19:12:262625 entries, 2, NetLogEventType::SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]e7b1c6d2c2012-05-05 00:54:032626}
2627
martijn003cd612016-05-19 22:24:382628// Make sure we cleanup old unused sockets.
Eric Romanb49715e2018-04-24 22:41:172629TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSocketsNoReuse) {
[email protected]e7b1c6d2c2012-05-05 00:54:032630 CreatePoolWithIdleTimeouts(
2631 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2632 base::TimeDelta(), // Time out unused sockets immediately
2633 base::TimeDelta()); // Time out used sockets immediately
[email protected]64770b7d2011-11-16 04:30:412634
2635 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2636
2637 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
2638
2639 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522640 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502641 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:282642 TestGroupId("a"), params_, base::nullopt, LOWEST, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502643 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2644 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012645 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
Matt Menkec6b3edf72019-03-19 17:00:392646 EXPECT_EQ(LOAD_STATE_CONNECTING,
2647 pool_->GetLoadState(TestGroupId("a"), &handle));
[email protected]64770b7d2011-11-16 04:30:412648
2649 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522650 TestCompletionCallback callback2;
Matt Menkef09e64c2019-04-23 22:16:282651 rv = handle2.Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
2652 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502653 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2654 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012655 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
Matt Menkec6b3edf72019-03-19 17:00:392656 EXPECT_EQ(LOAD_STATE_CONNECTING,
2657 pool_->GetLoadState(TestGroupId("a"), &handle2));
[email protected]64770b7d2011-11-16 04:30:412658
2659 // Cancel one of the requests. Wait for the other, which will get the first
2660 // job. Release the socket. Run the loop again to make sure the second
2661 // socket is sitting idle and the first one is released (since ReleaseSocket()
2662 // just posts a DoReleaseSocket() task).
2663
2664 handle.Reset();
robpercival214763f2016-07-01 23:27:012665 ASSERT_THAT(callback2.WaitForResult(), IsOk());
Matt Menke433de6d2020-03-04 00:24:112666 // Get the NetLogSource for the socket, so the time out reason can be checked
2667 // at the end of the test.
2668 NetLogSource net_log_source2 = handle2.socket()->NetLog().source();
[email protected]64770b7d2011-11-16 04:30:412669 // Use the socket.
Raul Tambre94493c652019-03-11 17:18:352670 EXPECT_EQ(1, handle2.socket()->Write(nullptr, 1, CompletionOnceCallback(),
Ramin Halavati0a08cc82018-02-06 07:46:382671 TRAFFIC_ANNOTATION_FOR_TESTS));
[email protected]64770b7d2011-11-16 04:30:412672 handle2.Reset();
2673
[email protected]e7b1c6d2c2012-05-05 00:54:032674 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
2675 // actually become pending until 2ms after they have been created. In order
2676 // to flush all tasks, we need to wait so that we know there are no
2677 // soon-to-be-pending tasks waiting.
Alex Clarke0def2092018-12-10 12:01:452678 FastForwardBy(base::TimeDelta::FromMilliseconds(10));
[email protected]64770b7d2011-11-16 04:30:412679
[email protected]e7b1c6d2c2012-05-05 00:54:032680 // Both sockets should now be idle.
[email protected]64770b7d2011-11-16 04:30:412681 ASSERT_EQ(2, pool_->IdleSocketCount());
2682
2683 // Request a new socket. This should cleanup the unused and timed out ones.
2684 // A new socket will be created rather than reusing the idle one.
Matt Muellerd9342e3a2019-11-26 01:41:142685 RecordingBoundTestNetLog log;
[email protected]6ecf2b92011-12-15 01:14:522686 TestCompletionCallback callback3;
Matt Menkef09e64c2019-04-23 22:16:282687 rv = handle.Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
2688 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502689 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
2690 pool_.get(), log.bound());
robpercival214763f2016-07-01 23:27:012691 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
2692 ASSERT_THAT(callback3.WaitForResult(), IsOk());
[email protected]64770b7d2011-11-16 04:30:412693 EXPECT_FALSE(handle.is_reused());
2694
[email protected]e7b1c6d2c2012-05-05 00:54:032695 // Make sure the idle socket is closed.
Matt Menke9fa17d52019-03-25 19:12:262696 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:392697 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menke9fa17d52019-03-25 19:12:262698 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
[email protected]64770b7d2011-11-16 04:30:412699
Eric Roman79cc7552019-07-19 02:17:542700 auto entries = log.GetEntries();
[email protected]64770b7d2011-11-16 04:30:412701 EXPECT_FALSE(LogContainsEntryWithType(
mikecirone8b85c432016-09-08 19:11:002702 entries, 1, NetLogEventType::SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
Matt Menke433de6d2020-03-04 00:24:112703 ExpectSocketClosedWithReason(
2704 net_log_source2, TransportClientSocketPool::kIdleTimeLimitExpired);
[email protected]64770b7d2011-11-16 04:30:412705}
2706
[email protected]2041cf342010-02-19 03:15:592707// Make sure that we process all pending requests even when we're stalling
[email protected]4f2abec2010-02-03 18:10:162708// because of multiple releasing disconnected sockets.
2709TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
2710 CreatePoolWithIdleTimeouts(
2711 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2712 base::TimeDelta(), // Time out unused sockets immediately.
2713 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2714
2715 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2716
2717 // Startup 4 connect jobs. Two of them will be pending.
2718
[email protected]2431756e2010-09-29 20:26:132719 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522720 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502721 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:282722 TestGroupId("a"), params_, base::nullopt, LOWEST, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502723 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2724 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012725 EXPECT_THAT(rv, IsOk());
[email protected]4f2abec2010-02-03 18:10:162726
[email protected]2431756e2010-09-29 20:26:132727 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522728 TestCompletionCallback callback2;
Matt Menkef09e64c2019-04-23 22:16:282729 rv = handle2.Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
2730 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502731 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2732 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012733 EXPECT_THAT(rv, IsOk());
[email protected]4f2abec2010-02-03 18:10:162734
[email protected]2431756e2010-09-29 20:26:132735 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:522736 TestCompletionCallback callback3;
Matt Menkef09e64c2019-04-23 22:16:282737 rv = handle3.Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
2738 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502739 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
2740 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012741 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4f2abec2010-02-03 18:10:162742
[email protected]2431756e2010-09-29 20:26:132743 ClientSocketHandle handle4;
[email protected]6ecf2b92011-12-15 01:14:522744 TestCompletionCallback callback4;
Matt Menkef09e64c2019-04-23 22:16:282745 rv = handle4.Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
2746 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502747 callback4.callback(), ClientSocketPool::ProxyAuthCallback(),
2748 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012749 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4f2abec2010-02-03 18:10:162750
2751 // Release two disconnected sockets.
2752
[email protected]2431756e2010-09-29 20:26:132753 handle.socket()->Disconnect();
2754 handle.Reset();
2755 handle2.socket()->Disconnect();
2756 handle2.Reset();
[email protected]4f2abec2010-02-03 18:10:162757
robpercival214763f2016-07-01 23:27:012758 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132759 EXPECT_FALSE(handle3.is_reused());
robpercival214763f2016-07-01 23:27:012760 EXPECT_THAT(callback4.WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132761 EXPECT_FALSE(handle4.is_reused());
[email protected]4f2abec2010-02-03 18:10:162762}
2763
[email protected]d7027bb2010-05-10 18:58:542764// Regression test for http://crbug.com/42267.
2765// When DoReleaseSocket() is processed for one socket, it is blocked because the
2766// other stalled groups all have releasing sockets, so no progress can be made.
2767TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
2768 CreatePoolWithIdleTimeouts(
2769 4 /* socket limit */, 4 /* socket limit per group */,
2770 base::TimeDelta(), // Time out unused sockets immediately.
2771 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2772
2773 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2774
2775 // Max out the socket limit with 2 per group.
2776
[email protected]2431756e2010-09-29 20:26:132777 ClientSocketHandle handle_a[4];
[email protected]6ecf2b92011-12-15 01:14:522778 TestCompletionCallback callback_a[4];
[email protected]2431756e2010-09-29 20:26:132779 ClientSocketHandle handle_b[4];
[email protected]6ecf2b92011-12-15 01:14:522780 TestCompletionCallback callback_b[4];
[email protected]d7027bb2010-05-10 18:58:542781
2782 for (int i = 0; i < 2; ++i) {
Matt Menkef09e64c2019-04-23 22:16:282783 EXPECT_EQ(OK, handle_a[i].Init(TestGroupId("a"), params_, base::nullopt,
2784 LOWEST, SocketTag(),
2785 ClientSocketPool::RespectLimits::ENABLED,
2786 callback_a[i].callback(),
2787 ClientSocketPool::ProxyAuthCallback(),
2788 pool_.get(), NetLogWithSource()));
2789 EXPECT_EQ(OK, handle_b[i].Init(TestGroupId("b"), params_, base::nullopt,
2790 LOWEST, SocketTag(),
2791 ClientSocketPool::RespectLimits::ENABLED,
2792 callback_b[i].callback(),
2793 ClientSocketPool::ProxyAuthCallback(),
2794 pool_.get(), NetLogWithSource()));
[email protected]d7027bb2010-05-10 18:58:542795 }
[email protected]b89f7e42010-05-20 20:37:002796
[email protected]d7027bb2010-05-10 18:58:542797 // Make 4 pending requests, 2 per group.
2798
2799 for (int i = 2; i < 4; ++i) {
Matt Menkef09e64c2019-04-23 22:16:282800 EXPECT_EQ(
2801 ERR_IO_PENDING,
2802 handle_a[i].Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
2803 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2804 callback_a[i].callback(),
2805 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2806 NetLogWithSource()));
2807 EXPECT_EQ(
2808 ERR_IO_PENDING,
2809 handle_b[i].Init(TestGroupId("b"), params_, base::nullopt, LOWEST,
2810 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2811 callback_b[i].callback(),
2812 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2813 NetLogWithSource()));
[email protected]d7027bb2010-05-10 18:58:542814 }
2815
2816 // Release b's socket first. The order is important, because in
2817 // DoReleaseSocket(), we'll process b's released socket, and since both b and
2818 // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
2819 // first, which has a releasing socket, so it refuses to start up another
2820 // ConnectJob. So, we used to infinite loop on this.
[email protected]2431756e2010-09-29 20:26:132821 handle_b[0].socket()->Disconnect();
2822 handle_b[0].Reset();
2823 handle_a[0].socket()->Disconnect();
2824 handle_a[0].Reset();
[email protected]d7027bb2010-05-10 18:58:542825
2826 // Used to get stuck here.
fdoray5eeb7642016-06-22 16:11:282827 base::RunLoop().RunUntilIdle();
[email protected]d7027bb2010-05-10 18:58:542828
[email protected]2431756e2010-09-29 20:26:132829 handle_b[1].socket()->Disconnect();
2830 handle_b[1].Reset();
2831 handle_a[1].socket()->Disconnect();
2832 handle_a[1].Reset();
[email protected]d7027bb2010-05-10 18:58:542833
2834 for (int i = 2; i < 4; ++i) {
robpercival214763f2016-07-01 23:27:012835 EXPECT_THAT(callback_b[i].WaitForResult(), IsOk());
2836 EXPECT_THAT(callback_a[i].WaitForResult(), IsOk());
[email protected]d7027bb2010-05-10 18:58:542837 }
2838}
2839
[email protected]fd4fe0b2010-02-08 23:02:152840TEST_F(ClientSocketPoolBaseTest,
2841 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
2842 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2843
2844 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2845
Matt Menkec6b3edf72019-03-19 17:00:392846 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2847 IsError(ERR_IO_PENDING));
2848 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2849 IsError(ERR_IO_PENDING));
2850 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2851 IsError(ERR_IO_PENDING));
2852 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2853 IsError(ERR_IO_PENDING));
[email protected]fd4fe0b2010-02-08 23:02:152854
robpercival214763f2016-07-01 23:27:012855 EXPECT_THAT((*requests())[0]->WaitForResult(), IsOk());
2856 EXPECT_THAT((*requests())[1]->WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132857 EXPECT_EQ(2u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152858
2859 // Releases one connection.
[email protected]2431756e2010-09-29 20:26:132860 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
robpercival214763f2016-07-01 23:27:012861 EXPECT_THAT((*requests())[2]->WaitForResult(), IsOk());
[email protected]fd4fe0b2010-02-08 23:02:152862
[email protected]2431756e2010-09-29 20:26:132863 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
robpercival214763f2016-07-01 23:27:012864 EXPECT_THAT((*requests())[3]->WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132865 EXPECT_EQ(4u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152866
2867 EXPECT_EQ(1, GetOrderOfRequest(1));
2868 EXPECT_EQ(2, GetOrderOfRequest(2));
2869 EXPECT_EQ(3, GetOrderOfRequest(3));
2870 EXPECT_EQ(4, GetOrderOfRequest(4));
2871
2872 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:132873 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(5));
[email protected]fd4fe0b2010-02-08 23:02:152874}
2875
[email protected]6ecf2b92011-12-15 01:14:522876class TestReleasingSocketRequest : public TestCompletionCallbackBase {
[email protected]4f1e4982010-03-02 18:31:042877 public:
Matt Menke9fa17d52019-03-25 19:12:262878 TestReleasingSocketRequest(TransportClientSocketPool* pool,
[email protected]2431756e2010-09-29 20:26:132879 int expected_result,
[email protected]e60e47a2010-07-14 03:37:182880 bool reset_releasing_handle)
2881 : pool_(pool),
2882 expected_result_(expected_result),
Bence Béky8ddc2492018-06-13 01:02:042883 reset_releasing_handle_(reset_releasing_handle) {}
[email protected]6ecf2b92011-12-15 01:14:522884
Chris Watkins7a41d3552017-12-01 02:13:272885 ~TestReleasingSocketRequest() override = default;
[email protected]4f1e4982010-03-02 18:31:042886
2887 ClientSocketHandle* handle() { return &handle_; }
2888
Bence Béky8ddc2492018-06-13 01:02:042889 CompletionOnceCallback callback() {
2890 return base::BindOnce(&TestReleasingSocketRequest::OnComplete,
2891 base::Unretained(this));
2892 }
[email protected]4f1e4982010-03-02 18:31:042893
2894 private:
[email protected]6ecf2b92011-12-15 01:14:522895 void OnComplete(int result) {
2896 SetResult(result);
2897 if (reset_releasing_handle_)
2898 handle_.Reset();
2899
Matt Menkec6b3edf72019-03-19 17:00:392900 EXPECT_EQ(
2901 expected_result_,
Matt Menke870e19ab2019-04-23 16:23:032902 handle2_.Init(
2903 TestGroupId("a"),
2904 ClientSocketPool::SocketParams::CreateForHttpForTesting(),
Matt Menkef09e64c2019-04-23 22:16:282905 base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menke870e19ab2019-04-23 16:23:032906 ClientSocketPool::RespectLimits::ENABLED, CompletionOnceCallback(),
2907 ClientSocketPool::ProxyAuthCallback(), pool_, NetLogWithSource()));
[email protected]6ecf2b92011-12-15 01:14:522908 }
2909
Matt Menke9fa17d52019-03-25 19:12:262910 TransportClientSocketPool* const pool_;
[email protected]e60e47a2010-07-14 03:37:182911 int expected_result_;
2912 bool reset_releasing_handle_;
[email protected]4f1e4982010-03-02 18:31:042913 ClientSocketHandle handle_;
2914 ClientSocketHandle handle2_;
[email protected]4f1e4982010-03-02 18:31:042915};
2916
[email protected]e60e47a2010-07-14 03:37:182917
2918TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) {
2919 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2920
Matt Menkec6b3edf72019-03-19 17:00:392921 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
2922 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
2923 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
[email protected]e60e47a2010-07-14 03:37:182924
[email protected]2431756e2010-09-29 20:26:132925 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]e60e47a2010-07-14 03:37:182926 client_socket_factory_.allocation_count());
2927
2928 connect_job_factory_->set_job_type(
2929 TestConnectJob::kMockPendingAdditionalErrorStateJob);
2930 TestReleasingSocketRequest req(pool_.get(), OK, false);
Matt Menkef09e64c2019-04-23 22:16:282931 EXPECT_EQ(ERR_IO_PENDING,
2932 req.handle()->Init(
2933 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2934 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2935 req.callback(), ClientSocketPool::ProxyAuthCallback(),
2936 pool_.get(), NetLogWithSource()));
[email protected]e60e47a2010-07-14 03:37:182937 // The next job should complete synchronously
2938 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2939
robpercival214763f2016-07-01 23:27:012940 EXPECT_THAT(req.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:182941 EXPECT_FALSE(req.handle()->is_initialized());
2942 EXPECT_FALSE(req.handle()->socket());
2943 EXPECT_TRUE(req.handle()->is_ssl_error());
Matt Menke39b7c5a2019-04-10 19:47:512944 EXPECT_TRUE(req.handle()->ssl_cert_request_info());
[email protected]e60e47a2010-07-14 03:37:182945}
2946
[email protected]b6501d3d2010-06-03 23:53:342947// http://crbug.com/44724 regression test.
2948// We start releasing the pool when we flush on network change. When that
2949// happens, the only active references are in the ClientSocketHandles. When a
2950// ConnectJob completes and calls back into the last ClientSocketHandle, that
2951// callback can release the last reference and delete the pool. After the
2952// callback finishes, we go back to the stack frame within the now-deleted pool.
2953// Executing any code that refers to members of the now-deleted pool can cause
2954// crashes.
2955TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
2956 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2957 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2958
2959 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522960 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502961 EXPECT_EQ(
2962 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:282963 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2964 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2965 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2966 pool_.get(), NetLogWithSource()));
[email protected]b6501d3d2010-06-03 23:53:342967
Matt Menke433de6d2020-03-04 00:24:112968 pool_->FlushWithError(ERR_NETWORK_CHANGED, "Network changed");
[email protected]b6501d3d2010-06-03 23:53:342969
2970 // We'll call back into this now.
2971 callback.WaitForResult();
2972}
2973
[email protected]a7e38572010-06-07 18:22:242974TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
2975 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2976 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2977
2978 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522979 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502980 EXPECT_EQ(
2981 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:282982 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2983 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2984 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2985 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:012986 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]a7e38572010-06-07 18:22:242987 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
Matt Menke433de6d2020-03-04 00:24:112988 NetLogSource source = handle.socket()->NetLog().source();
[email protected]a7e38572010-06-07 18:22:242989
Matt Menke433de6d2020-03-04 00:24:112990 pool_->FlushWithError(ERR_NETWORK_CHANGED, "Network changed");
[email protected]a7e38572010-06-07 18:22:242991
2992 handle.Reset();
fdoray5eeb7642016-06-22 16:11:282993 base::RunLoop().RunUntilIdle();
[email protected]a7e38572010-06-07 18:22:242994
Matt Menke28ac03e2019-02-25 22:25:502995 EXPECT_EQ(
2996 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:282997 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2998 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2999 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3000 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013001 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]a7e38572010-06-07 18:22:243002 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
Matt Menke433de6d2020-03-04 00:24:113003
3004 ExpectSocketClosedWithReason(
3005 source, TransportClientSocketPool::kSocketGenerationOutOfDate);
[email protected]a7e38572010-06-07 18:22:243006}
3007
[email protected]6ecf2b92011-12-15 01:14:523008class ConnectWithinCallback : public TestCompletionCallbackBase {
[email protected]06f92462010-08-31 19:24:143009 public:
Matt Menke9fa17d52019-03-25 19:12:263010 ConnectWithinCallback(
3011 const ClientSocketPool::GroupId& group_id,
Matt Menke84d11e562019-03-27 00:11:193012 const scoped_refptr<ClientSocketPool::SocketParams>& params,
Matt Menke9fa17d52019-03-25 19:12:263013 TransportClientSocketPool* pool)
Matt Menkec6b3edf72019-03-19 17:00:393014 : group_id_(group_id), params_(params), pool_(pool) {}
[email protected]06f92462010-08-31 19:24:143015
Chris Watkins7a41d3552017-12-01 02:13:273016 ~ConnectWithinCallback() override = default;
[email protected]06f92462010-08-31 19:24:143017
3018 int WaitForNestedResult() {
3019 return nested_callback_.WaitForResult();
3020 }
3021
Bence Béky8ddc2492018-06-13 01:02:043022 CompletionOnceCallback callback() {
3023 return base::BindOnce(&ConnectWithinCallback::OnComplete,
3024 base::Unretained(this));
3025 }
[email protected]6ecf2b92011-12-15 01:14:523026
[email protected]06f92462010-08-31 19:24:143027 private:
[email protected]6ecf2b92011-12-15 01:14:523028 void OnComplete(int result) {
3029 SetResult(result);
Matt Menkef09e64c2019-04-23 22:16:283030 EXPECT_EQ(
3031 ERR_IO_PENDING,
3032 handle_.Init(group_id_, params_, base::nullopt, DEFAULT_PRIORITY,
3033 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3034 nested_callback_.callback(),
3035 ClientSocketPool::ProxyAuthCallback(), pool_,
3036 NetLogWithSource()));
[email protected]6ecf2b92011-12-15 01:14:523037 }
3038
Matt Menkec6b3edf72019-03-19 17:00:393039 const ClientSocketPool::GroupId group_id_;
Matt Menke84d11e562019-03-27 00:11:193040 const scoped_refptr<ClientSocketPool::SocketParams> params_;
Matt Menke9fa17d52019-03-25 19:12:263041 TransportClientSocketPool* const pool_;
[email protected]06f92462010-08-31 19:24:143042 ClientSocketHandle handle_;
[email protected]6ecf2b92011-12-15 01:14:523043 TestCompletionCallback nested_callback_;
3044
3045 DISALLOW_COPY_AND_ASSIGN(ConnectWithinCallback);
[email protected]06f92462010-08-31 19:24:143046};
3047
3048TEST_F(ClientSocketPoolBaseTest, AbortAllRequestsOnFlush) {
3049 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3050
3051 // First job will be waiting until it gets aborted.
3052 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3053
3054 ClientSocketHandle handle;
Matt Menkec6b3edf72019-03-19 17:00:393055 ConnectWithinCallback callback(TestGroupId("a"), params_, pool_.get());
Matt Menke28ac03e2019-02-25 22:25:503056 EXPECT_EQ(
3057 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283058 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3059 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3060 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3061 pool_.get(), NetLogWithSource()));
[email protected]06f92462010-08-31 19:24:143062
3063 // Second job will be started during the first callback, and will
3064 // asynchronously complete with OK.
3065 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
Matt Menke433de6d2020-03-04 00:24:113066 pool_->FlushWithError(ERR_NETWORK_CHANGED, "Network changed");
robpercival214763f2016-07-01 23:27:013067 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NETWORK_CHANGED));
3068 EXPECT_THAT(callback.WaitForNestedResult(), IsOk());
[email protected]06f92462010-08-31 19:24:143069}
3070
Matt Menke141b87f22019-01-30 02:43:033071TEST_F(ClientSocketPoolBaseTest, BackupSocketWaitsForHostResolution) {
Matt Menke9fa17d52019-03-25 19:12:263072 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets,
3073 true /* enable_backup_connect_jobs */);
Matt Menke141b87f22019-01-30 02:43:033074
3075 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3076 ClientSocketHandle handle;
3077 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:503078 EXPECT_EQ(
3079 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283080 handle.Init(TestGroupId("bar"), params_, base::nullopt, DEFAULT_PRIORITY,
3081 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3082 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3083 pool_.get(), NetLogWithSource()));
Matt Menke141b87f22019-01-30 02:43:033084 // The backup timer fires but doesn't start a new ConnectJob while resolving
3085 // the hostname.
3086 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_RESOLVING_HOST);
3087 FastForwardBy(base::TimeDelta::FromMilliseconds(
3088 ClientSocketPool::kMaxConnectRetryIntervalMs * 100));
3089 EXPECT_EQ(1, client_socket_factory_.allocation_count());
3090
3091 // Once the ConnectJob has finished resolving the hostname, the backup timer
3092 // will create a ConnectJob when it fires.
3093 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_CONNECTING);
3094 FastForwardBy(base::TimeDelta::FromMilliseconds(
3095 ClientSocketPool::kMaxConnectRetryIntervalMs));
3096 EXPECT_EQ(2, client_socket_factory_.allocation_count());
3097}
3098
3099// Test that no backup socket is created when a ConnectJob connects before it
3100// completes.
3101TEST_F(ClientSocketPoolBaseTest, NoBackupSocketWhenConnected) {
Matt Menke9fa17d52019-03-25 19:12:263102 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets,
3103 true /* enable_backup_connect_jobs */);
Matt Menke141b87f22019-01-30 02:43:033104
3105 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3106 ClientSocketHandle handle;
3107 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:503108 EXPECT_EQ(
3109 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283110 handle.Init(TestGroupId("bar"), params_, base::nullopt, DEFAULT_PRIORITY,
3111 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3112 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3113 pool_.get(), NetLogWithSource()));
Matt Menke141b87f22019-01-30 02:43:033114 // The backup timer fires but doesn't start a new ConnectJob while resolving
3115 // the hostname.
3116 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_RESOLVING_HOST);
3117 FastForwardBy(base::TimeDelta::FromMilliseconds(
3118 ClientSocketPool::kMaxConnectRetryIntervalMs * 100));
3119 EXPECT_EQ(1, client_socket_factory_.allocation_count());
3120
3121 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
3122 client_socket_factory_.SetJobHasEstablishedConnection(0);
3123 FastForwardBy(base::TimeDelta::FromMilliseconds(
3124 ClientSocketPool::kMaxConnectRetryIntervalMs * 100));
3125 EXPECT_EQ(1, client_socket_factory_.allocation_count());
3126}
3127
[email protected]25eea382010-07-10 23:55:263128// Cancel a pending socket request while we're at max sockets,
3129// and verify that the backup socket firing doesn't cause a crash.
3130TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
3131 // Max 4 sockets globally, max 4 sockets per group.
Matt Menke9fa17d52019-03-25 19:12:263132 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets,
3133 true /* enable_backup_connect_jobs */);
[email protected]25eea382010-07-10 23:55:263134
[email protected]4baaf9d2010-08-31 15:15:443135 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
3136 // timer.
[email protected]25eea382010-07-10 23:55:263137 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3138 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:523139 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:503140 EXPECT_EQ(
3141 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283142 handle.Init(TestGroupId("bar"), params_, base::nullopt, DEFAULT_PRIORITY,
3143 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3144 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3145 pool_.get(), NetLogWithSource()));
[email protected]25eea382010-07-10 23:55:263146
3147 // Start (MaxSockets - 1) connected sockets to reach max sockets.
3148 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3149 ClientSocketHandle handles[kDefaultMaxSockets];
3150 for (int i = 1; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:523151 TestCompletionCallback callback;
Matt Menkef09e64c2019-04-23 22:16:283152 EXPECT_EQ(OK, handles[i].Init(TestGroupId("bar"), params_, base::nullopt,
3153 DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203154 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503155 callback.callback(),
3156 ClientSocketPool::ProxyAuthCallback(),
3157 pool_.get(), NetLogWithSource()));
[email protected]25eea382010-07-10 23:55:263158 }
3159
fdoray5eeb7642016-06-22 16:11:283160 base::RunLoop().RunUntilIdle();
[email protected]25eea382010-07-10 23:55:263161
3162 // Cancel the pending request.
3163 handle.Reset();
3164
3165 // Wait for the backup timer to fire (add some slop to ensure it fires)
Alex Clarke0def2092018-12-10 12:01:453166 FastForwardBy(base::TimeDelta::FromMilliseconds(
[email protected]26b9973962012-01-28 00:57:003167 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]25eea382010-07-10 23:55:263168
[email protected]25eea382010-07-10 23:55:263169 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
3170}
3171
[email protected]3f00be82010-09-27 19:50:023172TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterCancelingAllRequests) {
Matt Menke9fa17d52019-03-25 19:12:263173 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets,
3174 true /* enable_backup_connect_jobs */);
[email protected]4baaf9d2010-08-31 15:15:443175
3176 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
3177 // timer.
3178 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3179 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:523180 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:503181 EXPECT_EQ(
3182 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283183 handle.Init(TestGroupId("bar"), params_, base::nullopt, DEFAULT_PRIORITY,
3184 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3185 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3186 pool_.get(), NetLogWithSource()));
Matt Menke9fa17d52019-03-25 19:12:263187 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("bar")));
3188 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("bar")));
3189 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3190 TestGroupId("bar")));
3191 EXPECT_EQ(
3192 0u, pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("bar")));
[email protected]4baaf9d2010-08-31 15:15:443193
3194 // Cancel the socket request. This should cancel the backup timer. Wait for
3195 // the backup time to see if it indeed got canceled.
3196 handle.Reset();
3197 // Wait for the backup timer to fire (add some slop to ensure it fires)
Alex Clarke0def2092018-12-10 12:01:453198 FastForwardBy(base::TimeDelta::FromMilliseconds(
[email protected]26b9973962012-01-28 00:57:003199 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
Matt Menke9fa17d52019-03-25 19:12:263200 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("bar")));
3201 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("bar")));
[email protected]4baaf9d2010-08-31 15:15:443202}
3203
[email protected]3f00be82010-09-27 19:50:023204TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterFinishingAllRequests) {
Matt Menke9fa17d52019-03-25 19:12:263205 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets,
3206 true /* enable_backup_connect_jobs */);
[email protected]3f00be82010-09-27 19:50:023207
3208 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
3209 // timer.
3210 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3211 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:523212 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:503213 EXPECT_EQ(
3214 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283215 handle.Init(TestGroupId("bar"), params_, base::nullopt, DEFAULT_PRIORITY,
3216 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3217 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3218 pool_.get(), NetLogWithSource()));
[email protected]3f00be82010-09-27 19:50:023219 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3220 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523221 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203222 EXPECT_EQ(
3223 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283224 handle2.Init(TestGroupId("bar"), params_, base::nullopt, DEFAULT_PRIORITY,
3225 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503226 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3227 pool_.get(), NetLogWithSource()));
Matt Menke9fa17d52019-03-25 19:12:263228 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("bar")));
3229 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("bar")));
[email protected]3f00be82010-09-27 19:50:023230
3231 // Cancel request 1 and then complete request 2. With the requests finished,
3232 // the backup timer should be cancelled.
3233 handle.Reset();
robpercival214763f2016-07-01 23:27:013234 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]3f00be82010-09-27 19:50:023235 // Wait for the backup timer to fire (add some slop to ensure it fires)
Alex Clarke0def2092018-12-10 12:01:453236 FastForwardBy(base::TimeDelta::FromMilliseconds(
[email protected]26b9973962012-01-28 00:57:003237 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]3f00be82010-09-27 19:50:023238}
3239
[email protected]eb5a99382010-07-11 03:18:263240// Test delayed socket binding for the case where we have two connects,
3241// and while one is waiting on a connect, the other frees up.
3242// The socket waiting on a connect should switch immediately to the freed
3243// up socket.
3244TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
3245 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3246 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3247
3248 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523249 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:503250 EXPECT_EQ(
3251 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283252 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3253 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503254 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3255 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013256 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:263257
3258 // No idle sockets, no pending jobs.
3259 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menke9fa17d52019-03-25 19:12:263260 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263261
3262 // Create a second socket to the same host, but this one will wait.
3263 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3264 ClientSocketHandle handle2;
Matt Menke28ac03e2019-02-25 22:25:503265 EXPECT_EQ(
3266 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283267 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3268 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503269 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3270 pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:263271 // No idle sockets, and one connecting job.
3272 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menke9fa17d52019-03-25 19:12:263273 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263274
3275 // Return the first handle to the pool. This will initiate the delayed
3276 // binding.
3277 handle1.Reset();
3278
fdoray5eeb7642016-06-22 16:11:283279 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263280
3281 // Still no idle sockets, still one pending connect job.
3282 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menke9fa17d52019-03-25 19:12:263283 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263284
3285 // The second socket connected, even though it was a Waiting Job.
robpercival214763f2016-07-01 23:27:013286 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:263287
3288 // And we can see there is still one job waiting.
Matt Menke9fa17d52019-03-25 19:12:263289 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263290
3291 // Finally, signal the waiting Connect.
3292 client_socket_factory_.SignalJobs();
Matt Menke9fa17d52019-03-25 19:12:263293 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263294
fdoray5eeb7642016-06-22 16:11:283295 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263296}
3297
3298// Test delayed socket binding when a group is at capacity and one
3299// of the group's sockets frees up.
3300TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
3301 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3302 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3303
3304 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523305 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:503306 EXPECT_EQ(
3307 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283308 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3309 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503310 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3311 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013312 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:263313
3314 // No idle sockets, no pending jobs.
3315 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menke9fa17d52019-03-25 19:12:263316 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263317
3318 // Create a second socket to the same host, but this one will wait.
3319 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3320 ClientSocketHandle handle2;
Matt Menke28ac03e2019-02-25 22:25:503321 EXPECT_EQ(
3322 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283323 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3324 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503325 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3326 pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:263327 // No idle sockets, and one connecting job.
3328 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menke9fa17d52019-03-25 19:12:263329 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263330
3331 // Return the first handle to the pool. This will initiate the delayed
3332 // binding.
3333 handle1.Reset();
3334
fdoray5eeb7642016-06-22 16:11:283335 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263336
3337 // Still no idle sockets, still one pending connect job.
3338 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menke9fa17d52019-03-25 19:12:263339 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263340
3341 // The second socket connected, even though it was a Waiting Job.
robpercival214763f2016-07-01 23:27:013342 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:263343
3344 // And we can see there is still one job waiting.
Matt Menke9fa17d52019-03-25 19:12:263345 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263346
3347 // Finally, signal the waiting Connect.
3348 client_socket_factory_.SignalJobs();
Matt Menke9fa17d52019-03-25 19:12:263349 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263350
fdoray5eeb7642016-06-22 16:11:283351 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263352}
3353
3354// Test out the case where we have one socket connected, one
3355// connecting, when the first socket finishes and goes idle.
[email protected]2abfe90a2010-08-25 17:49:513356// Although the second connection is pending, the second request
[email protected]eb5a99382010-07-11 03:18:263357// should complete, by taking the first socket's idle socket.
3358TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
3359 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3360 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3361
3362 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523363 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:503364 EXPECT_EQ(
3365 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283366 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3367 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503368 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3369 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013370 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:263371
3372 // No idle sockets, no pending jobs.
3373 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menke9fa17d52019-03-25 19:12:263374 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263375
3376 // Create a second socket to the same host, but this one will wait.
3377 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3378 ClientSocketHandle handle2;
Matt Menke28ac03e2019-02-25 22:25:503379 EXPECT_EQ(
3380 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283381 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3382 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503383 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3384 pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:263385 // No idle sockets, and one connecting job.
3386 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menke9fa17d52019-03-25 19:12:263387 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263388
3389 // Return the first handle to the pool. This will initiate the delayed
3390 // binding.
3391 handle1.Reset();
3392
fdoray5eeb7642016-06-22 16:11:283393 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263394
3395 // Still no idle sockets, still one pending connect job.
3396 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menke9fa17d52019-03-25 19:12:263397 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263398
3399 // The second socket connected, even though it was a Waiting Job.
robpercival214763f2016-07-01 23:27:013400 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:263401
3402 // And we can see there is still one job waiting.
Matt Menke9fa17d52019-03-25 19:12:263403 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263404
3405 // Finally, signal the waiting Connect.
3406 client_socket_factory_.SignalJobs();
Matt Menke9fa17d52019-03-25 19:12:263407 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263408
fdoray5eeb7642016-06-22 16:11:283409 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263410}
3411
[email protected]2abfe90a2010-08-25 17:49:513412// Cover the case where on an available socket slot, we have one pending
3413// request that completes synchronously, thereby making the Group empty.
3414TEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) {
3415 const int kUnlimitedSockets = 100;
3416 const int kOneSocketPerGroup = 1;
3417 CreatePool(kUnlimitedSockets, kOneSocketPerGroup);
3418
3419 // Make the first request asynchronous fail.
3420 // This will free up a socket slot later.
3421 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
3422
3423 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523424 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203425 EXPECT_EQ(
3426 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283427 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3428 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503429 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3430 pool_.get(), NetLogWithSource()));
Matt Menke9fa17d52019-03-25 19:12:263431 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]2abfe90a2010-08-25 17:49:513432
3433 // Make the second request synchronously fail. This should make the Group
3434 // empty.
3435 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3436 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523437 TestCompletionCallback callback2;
[email protected]2abfe90a2010-08-25 17:49:513438 // It'll be ERR_IO_PENDING now, but the TestConnectJob will synchronously fail
3439 // when created.
tfarina428341112016-09-22 13:38:203440 EXPECT_EQ(
3441 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283442 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3443 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503444 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3445 pool_.get(), NetLogWithSource()));
[email protected]2abfe90a2010-08-25 17:49:513446
Matt Menke9fa17d52019-03-25 19:12:263447 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]2abfe90a2010-08-25 17:49:513448
robpercival214763f2016-07-01 23:27:013449 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
3450 EXPECT_THAT(callback2.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
Matt Menke9fa17d52019-03-25 19:12:263451 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
[email protected]2abfe90a2010-08-25 17:49:513452}
3453
[email protected]e1b54dc2010-10-06 21:27:223454TEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) {
3455 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3456
3457 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3458
3459 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523460 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203461 EXPECT_EQ(
3462 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283463 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3464 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503465 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3466 pool_.get(), NetLogWithSource()));
[email protected]e1b54dc2010-10-06 21:27:223467
3468 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523469 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203470 EXPECT_EQ(
3471 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283472 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3473 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503474 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3475 pool_.get(), NetLogWithSource()));
[email protected]e1b54dc2010-10-06 21:27:223476 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:523477 TestCompletionCallback callback3;
tfarina428341112016-09-22 13:38:203478 EXPECT_EQ(
3479 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283480 handle3.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3481 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503482 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
3483 pool_.get(), NetLogWithSource()));
[email protected]e1b54dc2010-10-06 21:27:223484
robpercival214763f2016-07-01 23:27:013485 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3486 EXPECT_THAT(callback2.WaitForResult(), IsOk());
3487 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]e1b54dc2010-10-06 21:27:223488
3489 // Use the socket.
Raul Tambre94493c652019-03-11 17:18:353490 EXPECT_EQ(1, handle1.socket()->Write(nullptr, 1, CompletionOnceCallback(),
Ramin Halavati0a08cc82018-02-06 07:46:383491 TRAFFIC_ANNOTATION_FOR_TESTS));
Raul Tambre94493c652019-03-11 17:18:353492 EXPECT_EQ(1, handle3.socket()->Write(nullptr, 1, CompletionOnceCallback(),
Ramin Halavati0a08cc82018-02-06 07:46:383493 TRAFFIC_ANNOTATION_FOR_TESTS));
[email protected]e1b54dc2010-10-06 21:27:223494
3495 handle1.Reset();
3496 handle2.Reset();
3497 handle3.Reset();
3498
Matt Menkec6b3edf72019-03-19 17:00:393499 EXPECT_EQ(OK, handle1.Init(
Matt Menkef09e64c2019-04-23 22:16:283500 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3501 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menkec6b3edf72019-03-19 17:00:393502 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3503 pool_.get(), NetLogWithSource()));
3504 EXPECT_EQ(OK, handle2.Init(
Matt Menkef09e64c2019-04-23 22:16:283505 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3506 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menkec6b3edf72019-03-19 17:00:393507 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3508 pool_.get(), NetLogWithSource()));
3509 EXPECT_EQ(OK, handle3.Init(
Matt Menkef09e64c2019-04-23 22:16:283510 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3511 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menkec6b3edf72019-03-19 17:00:393512 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
3513 pool_.get(), NetLogWithSource()));
[email protected]e1b54dc2010-10-06 21:27:223514
3515 EXPECT_TRUE(handle1.socket()->WasEverUsed());
3516 EXPECT_TRUE(handle2.socket()->WasEverUsed());
3517 EXPECT_FALSE(handle3.socket()->WasEverUsed());
3518}
3519
[email protected]2c2bef152010-10-13 00:55:033520TEST_F(ClientSocketPoolBaseTest, RequestSockets) {
3521 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3522 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3523
Matt Menkef09e64c2019-04-23 22:16:283524 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
3525 NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033526
Matt Menke9fa17d52019-03-25 19:12:263527 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3528 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3529 EXPECT_EQ(2u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3530 TestGroupId("a")));
3531 EXPECT_EQ(2u,
3532 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393533 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033534
3535 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523536 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203537 EXPECT_EQ(
3538 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283539 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3540 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503541 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3542 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033543
3544 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523545 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203546 EXPECT_EQ(
3547 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283548 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3549 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503550 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3551 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033552
Matt Menke9fa17d52019-03-25 19:12:263553 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3554 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3555 TestGroupId("a")));
3556 EXPECT_EQ(0u,
3557 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393558 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033559
robpercival214763f2016-07-01 23:27:013560 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3561 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033562 handle1.Reset();
3563 handle2.Reset();
3564
Matt Menke9fa17d52019-03-25 19:12:263565 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3566 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3567 TestGroupId("a")));
3568 EXPECT_EQ(0u,
3569 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393570 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033571}
3572
3573TEST_F(ClientSocketPoolBaseTest, RequestSocketsWhenAlreadyHaveAConnectJob) {
3574 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3575 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3576
3577 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523578 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203579 EXPECT_EQ(
3580 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283581 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3582 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503583 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3584 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033585
Matt Menke9fa17d52019-03-25 19:12:263586 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3587 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3588 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3589 TestGroupId("a")));
3590 EXPECT_EQ(0u,
3591 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393592 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033593
Matt Menkef09e64c2019-04-23 22:16:283594 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
3595 NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033596
Matt Menke9fa17d52019-03-25 19:12:263597 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3598 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3599 TestGroupId("a")));
3600 EXPECT_EQ(1u,
3601 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393602 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033603
3604 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523605 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203606 EXPECT_EQ(
3607 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283608 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3609 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503610 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3611 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033612
Matt Menke9fa17d52019-03-25 19:12:263613 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3614 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3615 TestGroupId("a")));
3616 EXPECT_EQ(0u,
3617 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393618 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033619
robpercival214763f2016-07-01 23:27:013620 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3621 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033622 handle1.Reset();
3623 handle2.Reset();
3624
Matt Menke9fa17d52019-03-25 19:12:263625 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3626 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3627 TestGroupId("a")));
3628 EXPECT_EQ(0u,
3629 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393630 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033631}
3632
3633TEST_F(ClientSocketPoolBaseTest,
3634 RequestSocketsWhenAlreadyHaveMultipleConnectJob) {
3635 CreatePool(4, 4);
3636 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3637
3638 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523639 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203640 EXPECT_EQ(
3641 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283642 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3643 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503644 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3645 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033646
3647 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523648 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203649 EXPECT_EQ(
3650 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283651 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3652 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503653 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3654 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033655
3656 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:523657 TestCompletionCallback callback3;
tfarina428341112016-09-22 13:38:203658 EXPECT_EQ(
3659 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283660 handle3.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3661 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503662 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
3663 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033664
Matt Menke9fa17d52019-03-25 19:12:263665 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3666 EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3667 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3668 TestGroupId("a")));
3669 EXPECT_EQ(0u,
3670 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393671 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033672
Matt Menkef09e64c2019-04-23 22:16:283673 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
3674 NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033675
Matt Menke9fa17d52019-03-25 19:12:263676 EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3677 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3678 TestGroupId("a")));
3679 EXPECT_EQ(0u,
3680 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393681 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033682
robpercival214763f2016-07-01 23:27:013683 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3684 EXPECT_THAT(callback2.WaitForResult(), IsOk());
3685 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033686 handle1.Reset();
3687 handle2.Reset();
3688 handle3.Reset();
3689
Matt Menke9fa17d52019-03-25 19:12:263690 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3691 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3692 TestGroupId("a")));
3693 EXPECT_EQ(0u,
3694 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393695 EXPECT_EQ(3u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033696}
3697
3698TEST_F(ClientSocketPoolBaseTest, RequestSocketsAtMaxSocketLimit) {
3699 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3700 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3701
Matt Menke9fa17d52019-03-25 19:12:263702 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033703
Matt Menkef09e64c2019-04-23 22:16:283704 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt,
3705 kDefaultMaxSockets, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033706
Matt Menke9fa17d52019-03-25 19:12:263707 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
Raul Tambre8335a6d2019-02-21 16:57:433708 EXPECT_EQ(kDefaultMaxSockets,
Matt Menkec6b3edf72019-03-19 17:00:393709 static_cast<int>(
Matt Menke9fa17d52019-03-25 19:12:263710 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))));
3711 EXPECT_EQ(
3712 kDefaultMaxSockets,
3713 static_cast<int>(pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3714 TestGroupId("a"))));
Raul Tambre8335a6d2019-02-21 16:57:433715 EXPECT_EQ(kDefaultMaxSockets,
Matt Menke9fa17d52019-03-25 19:12:263716 static_cast<int>(pool_->NumUnassignedConnectJobsInGroupForTesting(
3717 TestGroupId("a"))));
[email protected]2c2bef152010-10-13 00:55:033718
Matt Menke9fa17d52019-03-25 19:12:263719 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("b")));
[email protected]2c2bef152010-10-13 00:55:033720
Matt Menkef09e64c2019-04-23 22:16:283721 pool_->RequestSockets(TestGroupId("b"), params_, base::nullopt,
3722 kDefaultMaxSockets, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033723
Matt Menke9fa17d52019-03-25 19:12:263724 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("b")));
[email protected]2c2bef152010-10-13 00:55:033725}
3726
3727TEST_F(ClientSocketPoolBaseTest, RequestSocketsHitMaxSocketLimit) {
3728 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3729 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3730
Matt Menke9fa17d52019-03-25 19:12:263731 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033732
Matt Menkef09e64c2019-04-23 22:16:283733 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt,
3734 kDefaultMaxSockets - 1, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033735
Matt Menke9fa17d52019-03-25 19:12:263736 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:433737 EXPECT_EQ(kDefaultMaxSockets - 1,
Matt Menkec6b3edf72019-03-19 17:00:393738 static_cast<int>(
Matt Menke9fa17d52019-03-25 19:12:263739 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))));
3740 EXPECT_EQ(
3741 kDefaultMaxSockets - 1,
3742 static_cast<int>(pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3743 TestGroupId("a"))));
Raul Tambre8335a6d2019-02-21 16:57:433744 EXPECT_EQ(kDefaultMaxSockets - 1,
Matt Menke9fa17d52019-03-25 19:12:263745 static_cast<int>(pool_->NumUnassignedConnectJobsInGroupForTesting(
3746 TestGroupId("a"))));
[email protected]51fdc7c2012-04-10 19:19:483747 EXPECT_FALSE(pool_->IsStalled());
[email protected]2c2bef152010-10-13 00:55:033748
Matt Menke9fa17d52019-03-25 19:12:263749 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("b")));
[email protected]2c2bef152010-10-13 00:55:033750
Matt Menkef09e64c2019-04-23 22:16:283751 pool_->RequestSockets(TestGroupId("b"), params_, base::nullopt,
3752 kDefaultMaxSockets, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033753
Matt Menke9fa17d52019-03-25 19:12:263754 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("b")));
3755 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
[email protected]51fdc7c2012-04-10 19:19:483756 EXPECT_FALSE(pool_->IsStalled());
[email protected]2c2bef152010-10-13 00:55:033757}
3758
3759TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) {
3760 CreatePool(4, 4);
3761 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3762
3763 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523764 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203765 EXPECT_EQ(
3766 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283767 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3768 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503769 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3770 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013771 ASSERT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033772 handle1.Reset();
3773
Matt Menke9fa17d52019-03-25 19:12:263774 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3775 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3776 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3777 TestGroupId("a")));
3778 EXPECT_EQ(0u,
3779 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393780 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033781
Matt Menkef09e64c2019-04-23 22:16:283782 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
3783 NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033784
Matt Menke9fa17d52019-03-25 19:12:263785 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3786 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3787 TestGroupId("a")));
3788 EXPECT_EQ(1u,
3789 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393790 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033791}
3792
3793TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountActiveSockets) {
3794 CreatePool(4, 4);
3795 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3796
3797 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523798 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203799 EXPECT_EQ(
3800 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283801 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3802 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503803 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3804 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013805 ASSERT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033806
Matt Menke9fa17d52019-03-25 19:12:263807 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3808 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3809 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3810 TestGroupId("a")));
3811 EXPECT_EQ(0u,
3812 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393813 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menke9fa17d52019-03-25 19:12:263814 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033815
Matt Menkef09e64c2019-04-23 22:16:283816 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
3817 NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033818
Matt Menke9fa17d52019-03-25 19:12:263819 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3820 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3821 TestGroupId("a")));
3822 EXPECT_EQ(1u,
3823 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393824 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menke9fa17d52019-03-25 19:12:263825 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033826}
3827
3828TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronous) {
3829 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3830 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3831
Matt Menkef09e64c2019-04-23 22:16:283832 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt,
3833 kDefaultMaxSocketsPerGroup, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033834
Matt Menke9fa17d52019-03-25 19:12:263835 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3836 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3837 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3838 TestGroupId("a")));
3839 EXPECT_EQ(0u,
3840 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Raul Tambre8335a6d2019-02-21 16:57:433841 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
Matt Menkec6b3edf72019-03-19 17:00:393842 static_cast<int>(pool_->IdleSocketCountInGroup(TestGroupId("a"))));
[email protected]2c2bef152010-10-13 00:55:033843
Matt Menkef09e64c2019-04-23 22:16:283844 pool_->RequestSockets(TestGroupId("b"), params_, base::nullopt,
3845 kDefaultMaxSocketsPerGroup, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033846
Matt Menke9fa17d52019-03-25 19:12:263847 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
3848 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3849 TestGroupId("b")));
3850 EXPECT_EQ(0u,
3851 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("b")));
Raul Tambre8335a6d2019-02-21 16:57:433852 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
Matt Menkec6b3edf72019-03-19 17:00:393853 static_cast<int>(pool_->IdleSocketCountInGroup(TestGroupId("b"))));
[email protected]2c2bef152010-10-13 00:55:033854}
3855
[email protected]3c819f522010-12-02 02:03:123856TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronousError) {
3857 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3858 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3859
Matt Menkef09e64c2019-04-23 22:16:283860 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt,
3861 kDefaultMaxSocketsPerGroup, NetLogWithSource());
[email protected]3c819f522010-12-02 02:03:123862
Matt Menke9fa17d52019-03-25 19:12:263863 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
[email protected]fd2e53e2011-01-14 20:40:523864
3865 connect_job_factory_->set_job_type(
3866 TestConnectJob::kMockAdditionalErrorStateJob);
Matt Menkef09e64c2019-04-23 22:16:283867 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt,
3868 kDefaultMaxSocketsPerGroup, NetLogWithSource());
[email protected]fd2e53e2011-01-14 20:40:523869
Matt Menke9fa17d52019-03-25 19:12:263870 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
[email protected]3c819f522010-12-02 02:03:123871}
3872
[email protected]8159a1c2012-06-07 00:00:103873TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) {
[email protected]2c2bef152010-10-13 00:55:033874 CreatePool(4, 4);
Lily Chenecebf932018-11-02 17:15:433875 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
[email protected]2c2bef152010-10-13 00:55:033876
Matt Menkef09e64c2019-04-23 22:16:283877 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
3878 NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033879
Matt Menke9fa17d52019-03-25 19:12:263880 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3881 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3882 EXPECT_EQ(2u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3883 TestGroupId("a")));
3884 EXPECT_EQ(2u,
3885 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3886 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393887 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033888
Matt Menkef09e64c2019-04-23 22:16:283889 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
3890 NetLogWithSource());
Matt Menke9fa17d52019-03-25 19:12:263891 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3892 EXPECT_EQ(2u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3893 TestGroupId("a")));
3894 EXPECT_EQ(2u,
3895 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3896 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393897 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033898
3899 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523900 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203901 EXPECT_EQ(
3902 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283903 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3904 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503905 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3906 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:433907
3908 client_socket_factory_.SignalJob(0);
3909 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3910
Matt Menke9fa17d52019-03-25 19:12:263911 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3912 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3913 TestGroupId("a")));
3914 EXPECT_EQ(1u,
3915 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3916 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393917 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033918
3919 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523920 TestCompletionCallback callback2;
Lily Chenecebf932018-11-02 17:15:433921 EXPECT_EQ(
3922 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283923 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3924 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503925 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3926 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:433927 client_socket_factory_.SignalJob(0);
3928 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033929
Matt Menke9fa17d52019-03-25 19:12:263930 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3931 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3932 TestGroupId("a")));
3933 EXPECT_EQ(0u,
3934 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3935 EXPECT_EQ(2, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393936 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]8159a1c2012-06-07 00:00:103937
[email protected]2c2bef152010-10-13 00:55:033938 handle1.Reset();
3939 handle2.Reset();
3940
Matt Menke9fa17d52019-03-25 19:12:263941 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3942 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3943 TestGroupId("a")));
3944 EXPECT_EQ(0u,
3945 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3946 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393947 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033948
Matt Menkef09e64c2019-04-23 22:16:283949 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
3950 NetLogWithSource());
Matt Menke9fa17d52019-03-25 19:12:263951 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3952 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3953 TestGroupId("a")));
3954 EXPECT_EQ(0u,
3955 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3956 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393957 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033958}
3959
3960TEST_F(ClientSocketPoolBaseTest, RequestSocketsDifferentNumSockets) {
3961 CreatePool(4, 4);
3962 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3963
Matt Menkef09e64c2019-04-23 22:16:283964 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 1,
3965 NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033966
Matt Menke9fa17d52019-03-25 19:12:263967 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3968 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3969 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3970 TestGroupId("a")));
3971 EXPECT_EQ(1u,
3972 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393973 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033974
Matt Menkef09e64c2019-04-23 22:16:283975 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
3976 NetLogWithSource());
Matt Menke9fa17d52019-03-25 19:12:263977 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3978 EXPECT_EQ(2u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3979 TestGroupId("a")));
3980 EXPECT_EQ(2u,
3981 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393982 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033983
Matt Menkef09e64c2019-04-23 22:16:283984 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 3,
3985 NetLogWithSource());
Matt Menke9fa17d52019-03-25 19:12:263986 EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3987 EXPECT_EQ(3u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3988 TestGroupId("a")));
3989 EXPECT_EQ(3u,
3990 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393991 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033992
Matt Menkef09e64c2019-04-23 22:16:283993 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 1,
3994 NetLogWithSource());
Matt Menke9fa17d52019-03-25 19:12:263995 EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3996 EXPECT_EQ(3u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3997 TestGroupId("a")));
3998 EXPECT_EQ(3u,
3999 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394000 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:034001}
4002
4003TEST_F(ClientSocketPoolBaseTest, PreconnectJobsTakenByNormalRequests) {
4004 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
Lily Chenecebf932018-11-02 17:15:434005 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
[email protected]2c2bef152010-10-13 00:55:034006
Matt Menkef09e64c2019-04-23 22:16:284007 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 1,
4008 NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:034009
Matt Menke9fa17d52019-03-25 19:12:264010 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
4011 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4012 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4013 TestGroupId("a")));
4014 EXPECT_EQ(1u,
4015 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394016 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:034017
4018 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:524019 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:204020 EXPECT_EQ(
4021 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284022 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4023 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504024 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4025 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:034026
Matt Menke9fa17d52019-03-25 19:12:264027 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4028 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4029 TestGroupId("a")));
4030 EXPECT_EQ(0u,
4031 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394032 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:034033
Lily Chenecebf932018-11-02 17:15:434034 client_socket_factory_.SignalJobs();
4035 EXPECT_THAT(callback1.WaitForResult(), IsOk());
4036
Matt Menke9fa17d52019-03-25 19:12:264037 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4038 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4039 TestGroupId("a")));
4040 EXPECT_EQ(0u,
4041 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394042 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menke9fa17d52019-03-25 19:12:264043 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:034044
[email protected]0dc88b32014-03-26 20:12:284045 // Make sure if a preconnected socket is not fully connected when a request
[email protected]034df0f32013-01-07 23:17:484046 // starts, it has a connect start time.
4047 TestLoadTimingInfoConnectedNotReused(handle1);
[email protected]2c2bef152010-10-13 00:55:034048 handle1.Reset();
4049
Matt Menkec6b3edf72019-03-19 17:00:394050 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:034051}
4052
[email protected]034df0f32013-01-07 23:17:484053// Checks that fully connected preconnect jobs have no connect times, and are
4054// marked as reused.
4055TEST_F(ClientSocketPoolBaseTest, ConnectedPreconnectJobsHaveNoConnectTimes) {
4056 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4057 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
Matt Menkef09e64c2019-04-23 22:16:284058 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 1,
4059 NetLogWithSource());
[email protected]034df0f32013-01-07 23:17:484060
Matt Menke9fa17d52019-03-25 19:12:264061 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
4062 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4063 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4064 TestGroupId("a")));
4065 EXPECT_EQ(0u,
4066 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394067 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]034df0f32013-01-07 23:17:484068
4069 ClientSocketHandle handle;
4070 TestCompletionCallback callback;
Matt Menkec6b3edf72019-03-19 17:00:394071 EXPECT_EQ(OK, handle.Init(
Matt Menkef09e64c2019-04-23 22:16:284072 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4073 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menkec6b3edf72019-03-19 17:00:394074 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
4075 pool_.get(), NetLogWithSource()));
[email protected]034df0f32013-01-07 23:17:484076
4077 // Make sure the idle socket was used.
Matt Menkec6b3edf72019-03-19 17:00:394078 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]034df0f32013-01-07 23:17:484079
4080 TestLoadTimingInfoConnectedReused(handle);
4081 handle.Reset();
4082 TestLoadTimingInfoNotConnected(handle);
4083}
4084
[email protected]dcbe168a2010-12-02 03:14:464085// http://crbug.com/64940 regression test.
4086TEST_F(ClientSocketPoolBaseTest, PreconnectClosesIdleSocketRemovesGroup) {
4087 const int kMaxTotalSockets = 3;
4088 const int kMaxSocketsPerGroup = 2;
4089 CreatePool(kMaxTotalSockets, kMaxSocketsPerGroup);
Lily Chenecebf932018-11-02 17:15:434090 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
[email protected]dcbe168a2010-12-02 03:14:464091
Matt Menkef6edce752019-03-19 17:21:564092 // Note that group id ordering matters here. "a" comes before "b", so
[email protected]dcbe168a2010-12-02 03:14:464093 // CloseOneIdleSocket() will try to close "a"'s idle socket.
4094
4095 // Set up one idle socket in "a".
4096 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:524097 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:204098 EXPECT_EQ(
4099 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284100 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4101 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504102 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4103 pool_.get(), NetLogWithSource()));
Matt Menke9fa17d52019-03-25 19:12:264104 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
4105 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4106 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4107 TestGroupId("a")));
4108 EXPECT_EQ(0u,
4109 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394110 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]dcbe168a2010-12-02 03:14:464111
Lily Chenecebf932018-11-02 17:15:434112 client_socket_factory_.SignalJobs();
robpercival214763f2016-07-01 23:27:014113 ASSERT_THAT(callback1.WaitForResult(), IsOk());
Matt Menke9fa17d52019-03-25 19:12:264114 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4115 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4116 TestGroupId("a")));
4117 EXPECT_EQ(0u,
4118 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4119 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434120
[email protected]dcbe168a2010-12-02 03:14:464121 handle1.Reset();
Matt Menkec6b3edf72019-03-19 17:00:394122 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]dcbe168a2010-12-02 03:14:464123
4124 // Set up two active sockets in "b".
4125 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:524126 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:204127 EXPECT_EQ(
4128 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284129 handle1.Init(TestGroupId("b"), params_, base::nullopt, DEFAULT_PRIORITY,
4130 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504131 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4132 pool_.get(), NetLogWithSource()));
tfarina428341112016-09-22 13:38:204133 EXPECT_EQ(
4134 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284135 handle2.Init(TestGroupId("b"), params_, base::nullopt, DEFAULT_PRIORITY,
4136 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504137 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4138 pool_.get(), NetLogWithSource()));
[email protected]dcbe168a2010-12-02 03:14:464139
Matt Menke9fa17d52019-03-25 19:12:264140 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("b")));
4141 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
4142 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4143 TestGroupId("b")));
4144 EXPECT_EQ(0u,
4145 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("b")));
Matt Menkec6b3edf72019-03-19 17:00:394146 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("b")));
Lily Chenecebf932018-11-02 17:15:434147
4148 client_socket_factory_.SignalJobs();
robpercival214763f2016-07-01 23:27:014149 ASSERT_THAT(callback1.WaitForResult(), IsOk());
4150 ASSERT_THAT(callback2.WaitForResult(), IsOk());
Matt Menkec6b3edf72019-03-19 17:00:394151 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("b")));
Matt Menke9fa17d52019-03-25 19:12:264152 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4153 TestGroupId("b")));
4154 EXPECT_EQ(0u,
4155 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("b")));
4156 EXPECT_EQ(2, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("b")));
[email protected]dcbe168a2010-12-02 03:14:464157
4158 // Now we have 1 idle socket in "a" and 2 active sockets in "b". This means
4159 // we've maxed out on sockets, since we set |kMaxTotalSockets| to 3.
4160 // Requesting 2 preconnected sockets for "a" should fail to allocate any more
4161 // sockets for "a", and "b" should still have 2 active sockets.
4162
Matt Menkef09e64c2019-04-23 22:16:284163 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
4164 NetLogWithSource());
Matt Menke9fa17d52019-03-25 19:12:264165 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4166 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4167 TestGroupId("a")));
4168 EXPECT_EQ(0u,
4169 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394170 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menke9fa17d52019-03-25 19:12:264171 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
4172 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
4173 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4174 TestGroupId("b")));
4175 EXPECT_EQ(0u,
4176 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("b")));
Matt Menkec6b3edf72019-03-19 17:00:394177 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("b")));
Matt Menke9fa17d52019-03-25 19:12:264178 EXPECT_EQ(2, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("b")));
[email protected]dcbe168a2010-12-02 03:14:464179
4180 // Now release the 2 active sockets for "b". This will give us 1 idle socket
4181 // in "a" and 2 idle sockets in "b". Requesting 2 preconnected sockets for
4182 // "a" should result in closing 1 for "b".
4183 handle1.Reset();
4184 handle2.Reset();
Matt Menkec6b3edf72019-03-19 17:00:394185 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(TestGroupId("b")));
Matt Menke9fa17d52019-03-25 19:12:264186 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("b")));
[email protected]dcbe168a2010-12-02 03:14:464187
Matt Menkef09e64c2019-04-23 22:16:284188 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
4189 NetLogWithSource());
Matt Menke9fa17d52019-03-25 19:12:264190 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4191 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4192 TestGroupId("a")));
4193 EXPECT_EQ(1u,
4194 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394195 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menke9fa17d52019-03-25 19:12:264196 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
4197 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
4198 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4199 TestGroupId("b")));
4200 EXPECT_EQ(0u,
4201 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("b")));
Matt Menkec6b3edf72019-03-19 17:00:394202 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("b")));
Matt Menke9fa17d52019-03-25 19:12:264203 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("b")));
[email protected]dcbe168a2010-12-02 03:14:464204}
4205
[email protected]b7b8be42011-07-12 12:46:414206TEST_F(ClientSocketPoolBaseTest, PreconnectWithoutBackupJob) {
Matt Menke9fa17d52019-03-25 19:12:264207 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
4208 true /* enable_backup_connect_jobs */);
[email protected]a9fc8fc2011-05-10 02:41:074209
4210 // Make the ConnectJob hang until it times out, shorten the timeout.
4211 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4212 connect_job_factory_->set_timeout_duration(
4213 base::TimeDelta::FromMilliseconds(500));
Matt Menkef09e64c2019-04-23 22:16:284214 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 1,
4215 NetLogWithSource());
Matt Menke9fa17d52019-03-25 19:12:264216 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4217 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4218 TestGroupId("a")));
4219 EXPECT_EQ(1u,
4220 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394221 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]a9fc8fc2011-05-10 02:41:074222
[email protected]b7b8be42011-07-12 12:46:414223 // Verify the backup timer doesn't create a backup job, by making
4224 // the backup job a pending job instead of a waiting job, so it
4225 // *would* complete if it were created.
Lukasz Krakowiak28dcf9d62020-06-04 09:46:594226 base::RunLoop loop;
[email protected]a9fc8fc2011-05-10 02:41:074227 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
skyostil4891b25b2015-06-11 11:43:454228 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
Lukasz Krakowiak855292082020-06-19 12:43:584229 FROM_HERE, loop.QuitClosure(), base::TimeDelta::FromSeconds(1));
Lukasz Krakowiak28dcf9d62020-06-04 09:46:594230 loop.Run();
Matt Menke9fa17d52019-03-25 19:12:264231 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
[email protected]a9fc8fc2011-05-10 02:41:074232}
4233
[email protected]b7b8be42011-07-12 12:46:414234TEST_F(ClientSocketPoolBaseTest, PreconnectWithBackupJob) {
Matt Menke9fa17d52019-03-25 19:12:264235 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
4236 true /* enable_backup_connect_jobs */);
[email protected]a9fc8fc2011-05-10 02:41:074237
4238 // Make the ConnectJob hang forever.
4239 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
Matt Menkef09e64c2019-04-23 22:16:284240 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 1,
4241 NetLogWithSource());
Matt Menke9fa17d52019-03-25 19:12:264242 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4243 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4244 TestGroupId("a")));
4245 EXPECT_EQ(1u,
4246 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394247 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
fdoray5eeb7642016-06-22 16:11:284248 base::RunLoop().RunUntilIdle();
[email protected]a9fc8fc2011-05-10 02:41:074249
4250 // Make the backup job be a pending job, so it completes normally.
4251 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
4252 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:524253 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:504254 EXPECT_EQ(
4255 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284256 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4257 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4258 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
4259 pool_.get(), NetLogWithSource()));
[email protected]b7b8be42011-07-12 12:46:414260 // Timer has started, but the backup connect job shouldn't be created yet.
Matt Menke9fa17d52019-03-25 19:12:264261 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4262 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4263 TestGroupId("a")));
4264 EXPECT_EQ(0u,
4265 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394266 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menke9fa17d52019-03-25 19:12:264267 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
robpercival214763f2016-07-01 23:27:014268 ASSERT_THAT(callback.WaitForResult(), IsOk());
[email protected]a9fc8fc2011-05-10 02:41:074269
4270 // The hung connect job should still be there, but everything else should be
4271 // complete.
Matt Menke9fa17d52019-03-25 19:12:264272 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4273 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4274 TestGroupId("a")));
4275 EXPECT_EQ(1u,
4276 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394277 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menke9fa17d52019-03-25 19:12:264278 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
[email protected]a9fc8fc2011-05-10 02:41:074279}
4280
[email protected]0dc88b32014-03-26 20:12:284281// Tests that a preconnect that starts out with unread data can still be used.
4282// http://crbug.com/334467
4283TEST_F(ClientSocketPoolBaseTest, PreconnectWithUnreadData) {
4284 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4285 connect_job_factory_->set_job_type(TestConnectJob::kMockUnreadDataJob);
4286
Matt Menkef09e64c2019-04-23 22:16:284287 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 1,
4288 NetLogWithSource());
[email protected]0dc88b32014-03-26 20:12:284289
Matt Menke9fa17d52019-03-25 19:12:264290 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
4291 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4292 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4293 TestGroupId("a")));
4294 EXPECT_EQ(0u,
4295 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394296 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]0dc88b32014-03-26 20:12:284297
4298 // Fail future jobs to be sure that handle receives the preconnected socket
4299 // rather than closing it and making a new one.
4300 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
4301 ClientSocketHandle handle;
4302 TestCompletionCallback callback;
Matt Menkec6b3edf72019-03-19 17:00:394303 EXPECT_EQ(OK, handle.Init(
Matt Menkef09e64c2019-04-23 22:16:284304 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4305 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menkec6b3edf72019-03-19 17:00:394306 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
4307 pool_.get(), NetLogWithSource()));
[email protected]0dc88b32014-03-26 20:12:284308
Matt Menke9fa17d52019-03-25 19:12:264309 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
4310 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4311 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4312 TestGroupId("a")));
4313 EXPECT_EQ(0u,
4314 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394315 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menke9fa17d52019-03-25 19:12:264316 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
[email protected]0dc88b32014-03-26 20:12:284317
4318 // Drain the pending read.
Raul Tambre94493c652019-03-11 17:18:354319 EXPECT_EQ(1, handle.socket()->Read(nullptr, 1, CompletionOnceCallback()));
[email protected]0dc88b32014-03-26 20:12:284320
4321 TestLoadTimingInfoConnectedReused(handle);
4322 handle.Reset();
4323
4324 // The socket should be usable now that it's idle again.
Matt Menkec6b3edf72019-03-19 17:00:394325 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]0dc88b32014-03-26 20:12:284326}
4327
Lily Chenecebf932018-11-02 17:15:434328TEST_F(ClientSocketPoolBaseTest, RequestGetsAssignedJob) {
4329 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4330 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4331
4332 ClientSocketHandle handle1;
4333 TestCompletionCallback callback1;
4334 EXPECT_EQ(
4335 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284336 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4337 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504338 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4339 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434340
Matt Menke9fa17d52019-03-25 19:12:264341 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4342 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4343 TestGroupId("a")));
4344 EXPECT_EQ(0u,
4345 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394346 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434347
Matt Menkec6b3edf72019-03-19 17:00:394348 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4349 &handle1));
Lily Chenecebf932018-11-02 17:15:434350}
4351
4352TEST_F(ClientSocketPoolBaseTest, MultipleRequestsGetAssignedJobs) {
4353 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4354 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4355
4356 ClientSocketHandle handle1;
4357 TestCompletionCallback callback1;
4358 EXPECT_EQ(
4359 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284360 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4361 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504362 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4363 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434364
Matt Menke9fa17d52019-03-25 19:12:264365 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4366 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4367 TestGroupId("a")));
4368 EXPECT_EQ(0u,
4369 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394370 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434371
4372 ClientSocketHandle handle2;
4373 TestCompletionCallback callback2;
4374 EXPECT_EQ(
4375 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284376 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4377 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504378 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4379 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434380
Matt Menke9fa17d52019-03-25 19:12:264381 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4382 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4383 TestGroupId("a")));
4384 EXPECT_EQ(0u,
4385 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394386 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434387
Matt Menkec6b3edf72019-03-19 17:00:394388 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4389 &handle1));
4390 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4391 &handle2));
Lily Chenecebf932018-11-02 17:15:434392
4393 // One job completes. The other request should still have its job.
4394 client_socket_factory_.SignalJob(0);
4395 EXPECT_THAT(callback1.WaitForResult(), IsOk());
4396
Matt Menke9fa17d52019-03-25 19:12:264397 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4398 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4399 TestGroupId("a")));
4400 EXPECT_EQ(0u,
4401 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4402 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394403 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434404
Matt Menkec6b3edf72019-03-19 17:00:394405 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4406 &handle2));
Lily Chenecebf932018-11-02 17:15:434407}
4408
4409TEST_F(ClientSocketPoolBaseTest, PreconnectJobGetsAssignedToRequest) {
4410 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4411 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4412
Matt Menkef09e64c2019-04-23 22:16:284413 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 1,
4414 NetLogWithSource());
Lily Chenecebf932018-11-02 17:15:434415
Matt Menke9fa17d52019-03-25 19:12:264416 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
4417 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4418 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4419 TestGroupId("a")));
4420 EXPECT_EQ(1u,
4421 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394422 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434423
4424 ClientSocketHandle handle1;
4425 TestCompletionCallback callback1;
4426 EXPECT_EQ(
4427 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284428 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4429 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504430 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4431 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434432
Matt Menke9fa17d52019-03-25 19:12:264433 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4434 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4435 TestGroupId("a")));
4436 EXPECT_EQ(0u,
4437 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394438 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434439
Matt Menkec6b3edf72019-03-19 17:00:394440 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4441 &handle1));
Lily Chenecebf932018-11-02 17:15:434442}
4443
4444TEST_F(ClientSocketPoolBaseTest, HigherPriorityRequestStealsJob) {
4445 CreatePool(kDefaultMaxSockets, 1);
4446 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4447
4448 ClientSocketHandle handle1;
4449 TestCompletionCallback callback1;
4450 EXPECT_EQ(
4451 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284452 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4453 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504454 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4455 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434456
Matt Menke9fa17d52019-03-25 19:12:264457 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4458 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4459 TestGroupId("a")));
4460 EXPECT_EQ(0u,
4461 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394462 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434463
Matt Menkec6b3edf72019-03-19 17:00:394464 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4465 &handle1));
Lily Chenecebf932018-11-02 17:15:434466
4467 // Insert a higher priority request
4468 ClientSocketHandle handle2;
4469 TestCompletionCallback callback2;
4470 EXPECT_EQ(
4471 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284472 handle2.Init(TestGroupId("a"), params_, base::nullopt, HIGHEST,
4473 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504474 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4475 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434476
Matt Menke9fa17d52019-03-25 19:12:264477 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4478 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4479 TestGroupId("a")));
4480 EXPECT_EQ(0u,
4481 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394482 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434483
4484 // The highest priority request should steal the job from the default priority
4485 // request.
Matt Menkec6b3edf72019-03-19 17:00:394486 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4487 &handle2));
4488 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4489 &handle1));
Lily Chenecebf932018-11-02 17:15:434490}
4491
4492TEST_F(ClientSocketPoolBaseTest, RequestStealsJobFromLowestRequestWithJob) {
4493 CreatePool(3, 3);
4494 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4495
4496 ClientSocketHandle handle_lowest;
4497 TestCompletionCallback callback_lowest;
Matt Menkef09e64c2019-04-23 22:16:284498 EXPECT_EQ(
4499 ERR_IO_PENDING,
4500 handle_lowest.Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
4501 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4502 callback_lowest.callback(),
4503 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4504 NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434505
Matt Menke9fa17d52019-03-25 19:12:264506 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4507 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4508 TestGroupId("a")));
4509 EXPECT_EQ(0u,
4510 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394511 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434512
4513 ClientSocketHandle handle_highest;
4514 TestCompletionCallback callback_highest;
Matt Menkef09e64c2019-04-23 22:16:284515 EXPECT_EQ(
4516 ERR_IO_PENDING,
4517 handle_highest.Init(TestGroupId("a"), params_, base::nullopt, HIGHEST,
4518 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4519 callback_highest.callback(),
4520 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4521 NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434522
Matt Menke9fa17d52019-03-25 19:12:264523 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4524 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4525 TestGroupId("a")));
4526 EXPECT_EQ(0u,
4527 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394528 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434529
4530 ClientSocketHandle handle_low;
4531 TestCompletionCallback callback_low;
4532 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284533 handle_low.Init(
4534 TestGroupId("a"), params_, base::nullopt, LOW, SocketTag(),
4535 ClientSocketPool::RespectLimits::ENABLED,
4536 callback_low.callback(), ClientSocketPool::ProxyAuthCallback(),
4537 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434538
Matt Menke9fa17d52019-03-25 19:12:264539 EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4540 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4541 TestGroupId("a")));
4542 EXPECT_EQ(0u,
4543 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394544 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434545
4546 ClientSocketHandle handle_lowest2;
4547 TestCompletionCallback callback_lowest2;
Matt Menkef09e64c2019-04-23 22:16:284548 EXPECT_EQ(
4549 ERR_IO_PENDING,
4550 handle_lowest2.Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
4551 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4552 callback_lowest2.callback(),
4553 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4554 NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434555
Matt Menke9fa17d52019-03-25 19:12:264556 EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4557 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4558 TestGroupId("a")));
4559 EXPECT_EQ(0u,
4560 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394561 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434562
4563 // The top three requests in the queue should have jobs.
Matt Menkec6b3edf72019-03-19 17:00:394564 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4565 &handle_highest));
4566 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4567 &handle_low));
4568 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4569 &handle_lowest));
4570 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(
4571 TestGroupId("a"), &handle_lowest2));
Lily Chenecebf932018-11-02 17:15:434572
4573 // Add another request with medium priority. It should steal the job from the
4574 // lowest priority request with a job.
4575 ClientSocketHandle handle_medium;
4576 TestCompletionCallback callback_medium;
Matt Menkef09e64c2019-04-23 22:16:284577 EXPECT_EQ(
4578 ERR_IO_PENDING,
4579 handle_medium.Init(TestGroupId("a"), params_, base::nullopt, MEDIUM,
4580 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4581 callback_medium.callback(),
4582 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4583 NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434584
Matt Menke9fa17d52019-03-25 19:12:264585 EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4586 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4587 TestGroupId("a")));
4588 EXPECT_EQ(0u,
4589 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394590 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4591 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4592 &handle_highest));
4593 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4594 &handle_medium));
4595 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4596 &handle_low));
4597 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4598 &handle_lowest));
4599 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(
4600 TestGroupId("a"), &handle_lowest2));
Lily Chenecebf932018-11-02 17:15:434601}
4602
4603TEST_F(ClientSocketPoolBaseTest, ReprioritizeRequestStealsJob) {
4604 CreatePool(kDefaultMaxSockets, 1);
4605 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4606
4607 ClientSocketHandle handle1;
4608 TestCompletionCallback callback1;
4609 EXPECT_EQ(
4610 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284611 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4612 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504613 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4614 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434615
Matt Menke9fa17d52019-03-25 19:12:264616 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4617 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4618 TestGroupId("a")));
4619 EXPECT_EQ(0u,
4620 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394621 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434622
4623 ClientSocketHandle handle2;
4624 TestCompletionCallback callback2;
4625 EXPECT_EQ(
4626 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284627 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4628 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504629 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4630 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434631
Matt Menke9fa17d52019-03-25 19:12:264632 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4633 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4634 TestGroupId("a")));
4635 EXPECT_EQ(0u,
4636 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394637 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434638
4639 // The second request doesn't get a job because we are at the limit.
Matt Menkec6b3edf72019-03-19 17:00:394640 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4641 &handle1));
4642 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4643 &handle2));
Lily Chenecebf932018-11-02 17:15:434644
4645 // Reprioritizing the second request places it above the first, and it steals
4646 // the job from the first request.
Matt Menkec6b3edf72019-03-19 17:00:394647 pool_->SetPriority(TestGroupId("a"), &handle2, HIGHEST);
4648 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4649 &handle2));
4650 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4651 &handle1));
Lily Chenecebf932018-11-02 17:15:434652}
4653
4654TEST_F(ClientSocketPoolBaseTest, CancelRequestReassignsJob) {
4655 CreatePool(kDefaultMaxSockets, 1);
4656 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4657
4658 ClientSocketHandle handle1;
4659 TestCompletionCallback callback1;
4660 EXPECT_EQ(
4661 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284662 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4663 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504664 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4665 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434666
Matt Menke9fa17d52019-03-25 19:12:264667 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4668 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4669 TestGroupId("a")));
4670 EXPECT_EQ(0u,
4671 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394672 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434673
Matt Menkec6b3edf72019-03-19 17:00:394674 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4675 &handle1));
Lily Chenecebf932018-11-02 17:15:434676
4677 ClientSocketHandle handle2;
4678 TestCompletionCallback callback2;
4679 EXPECT_EQ(
4680 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284681 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4682 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504683 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4684 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434685
Matt Menke9fa17d52019-03-25 19:12:264686 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4687 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4688 TestGroupId("a")));
4689 EXPECT_EQ(0u,
4690 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394691 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434692
4693 // The second request doesn't get a job because we are the limit.
Matt Menkec6b3edf72019-03-19 17:00:394694 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4695 &handle1));
4696 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4697 &handle2));
Lily Chenecebf932018-11-02 17:15:434698
4699 // The second request should get a job upon cancelling the first request.
4700 handle1.Reset();
Matt Menke9fa17d52019-03-25 19:12:264701 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4702 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4703 TestGroupId("a")));
4704 EXPECT_EQ(0u,
4705 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394706 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434707
Matt Menkec6b3edf72019-03-19 17:00:394708 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4709 &handle2));
Lily Chenecebf932018-11-02 17:15:434710}
4711
4712TEST_F(ClientSocketPoolBaseTest, JobCompletionReassignsJob) {
4713 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4714 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4715
4716 ClientSocketHandle handle1;
4717 TestCompletionCallback callback1;
4718 EXPECT_EQ(
4719 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284720 handle1.Init(TestGroupId("a"), params_, base::nullopt, HIGHEST,
4721 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504722 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4723 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434724
Matt Menke9fa17d52019-03-25 19:12:264725 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4726 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4727 TestGroupId("a")));
4728 EXPECT_EQ(0u,
4729 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394730 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434731
4732 ClientSocketHandle handle2;
4733 TestCompletionCallback callback2;
4734 EXPECT_EQ(
4735 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284736 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4737 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504738 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4739 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434740
Matt Menke9fa17d52019-03-25 19:12:264741 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4742 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4743 TestGroupId("a")));
4744 EXPECT_EQ(0u,
4745 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394746 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434747
Matt Menkec6b3edf72019-03-19 17:00:394748 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4749 &handle1));
4750 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4751 &handle2));
Lily Chenecebf932018-11-02 17:15:434752
4753 // The lower-priority job completes first. The higher-priority request should
4754 // get the socket, and the lower-priority request should get the remaining
4755 // job.
4756 client_socket_factory_.SignalJob(1);
4757 EXPECT_THAT(callback1.WaitForResult(), IsOk());
Matt Menke9fa17d52019-03-25 19:12:264758 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4759 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4760 TestGroupId("a")));
4761 EXPECT_EQ(0u,
4762 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4763 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394764 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434765 EXPECT_TRUE(handle1.socket());
Matt Menkec6b3edf72019-03-19 17:00:394766 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4767 &handle2));
Lily Chenecebf932018-11-02 17:15:434768}
4769
[email protected]043b68c82013-08-22 23:41:524770class MockLayeredPool : public HigherLayeredPool {
[email protected]58e562f2013-04-22 17:32:204771 public:
Matt Menke9fa17d52019-03-25 19:12:264772 MockLayeredPool(TransportClientSocketPool* pool,
Matt Menkec6b3edf72019-03-19 17:00:394773 const ClientSocketPool::GroupId& group_id)
4774 : pool_(pool), group_id_(group_id), can_release_connection_(true) {
[email protected]043b68c82013-08-22 23:41:524775 pool_->AddHigherLayeredPool(this);
[email protected]58e562f2013-04-22 17:32:204776 }
4777
Daniel Cheng4496d0822018-04-26 21:52:154778 ~MockLayeredPool() override { pool_->RemoveHigherLayeredPool(this); }
[email protected]58e562f2013-04-22 17:32:204779
Matt Menke9fa17d52019-03-25 19:12:264780 int RequestSocket(TransportClientSocketPool* pool) {
Matt Menke28ac03e2019-02-25 22:25:504781 return handle_.Init(
Matt Menke870e19ab2019-04-23 16:23:034782 group_id_, ClientSocketPool::SocketParams::CreateForHttpForTesting(),
Matt Menkef09e64c2019-04-23 22:16:284783 base::nullopt, DEFAULT_PRIORITY, SocketTag(),
4784 ClientSocketPool::RespectLimits::ENABLED, callback_.callback(),
4785 ClientSocketPool::ProxyAuthCallback(), pool, NetLogWithSource());
[email protected]58e562f2013-04-22 17:32:204786 }
4787
Matt Menke9fa17d52019-03-25 19:12:264788 int RequestSocketWithoutLimits(TransportClientSocketPool* pool) {
Matt Menke28ac03e2019-02-25 22:25:504789 return handle_.Init(
Matt Menke870e19ab2019-04-23 16:23:034790 group_id_, ClientSocketPool::SocketParams::CreateForHttpForTesting(),
Matt Menkef09e64c2019-04-23 22:16:284791 base::nullopt, MAXIMUM_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:504792 ClientSocketPool::RespectLimits::DISABLED, callback_.callback(),
4793 ClientSocketPool::ProxyAuthCallback(), pool, NetLogWithSource());
[email protected]58e562f2013-04-22 17:32:204794 }
4795
4796 bool ReleaseOneConnection() {
4797 if (!handle_.is_initialized() || !can_release_connection_) {
4798 return false;
4799 }
4800 handle_.socket()->Disconnect();
4801 handle_.Reset();
4802 return true;
4803 }
4804
4805 void set_can_release_connection(bool can_release_connection) {
4806 can_release_connection_ = can_release_connection;
4807 }
4808
4809 MOCK_METHOD0(CloseOneIdleConnection, bool());
4810
4811 private:
Matt Menke9fa17d52019-03-25 19:12:264812 TransportClientSocketPool* const pool_;
[email protected]58e562f2013-04-22 17:32:204813 ClientSocketHandle handle_;
4814 TestCompletionCallback callback_;
Matt Menkec6b3edf72019-03-19 17:00:394815 const ClientSocketPool::GroupId group_id_;
[email protected]58e562f2013-04-22 17:32:204816 bool can_release_connection_;
4817};
4818
[email protected]58e562f2013-04-22 17:32:204819// Tests the basic case of closing an idle socket in a higher layered pool when
4820// a new request is issued and the lower layer pool is stalled.
4821TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsHeldByLayeredPoolWhenNeeded) {
4822 CreatePool(1, 1);
4823 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4824
Matt Menkec6b3edf72019-03-19 17:00:394825 MockLayeredPool mock_layered_pool(pool_.get(), TestGroupId("foo"));
robpercival214763f2016-07-01 23:27:014826 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:204827 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4828 .WillOnce(Invoke(&mock_layered_pool,
4829 &MockLayeredPool::ReleaseOneConnection));
4830 ClientSocketHandle handle;
4831 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:504832 EXPECT_EQ(
4833 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284834 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4835 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4836 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
4837 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:014838 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204839}
4840
Matt Menke833678642019-03-05 22:05:514841// Tests the case that trying to close an idle socket in a higher layered pool
4842// fails.
4843TEST_F(ClientSocketPoolBaseTest,
4844 CloseIdleSocketsHeldByLayeredPoolWhenNeededFails) {
4845 CreatePool(1, 1);
4846 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4847
Matt Menkec6b3edf72019-03-19 17:00:394848 MockLayeredPool mock_layered_pool(pool_.get(), TestGroupId("foo"));
Matt Menke833678642019-03-05 22:05:514849 mock_layered_pool.set_can_release_connection(false);
4850 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
4851 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4852 .WillOnce(Invoke(&mock_layered_pool,
4853 &MockLayeredPool::ReleaseOneConnection));
4854 ClientSocketHandle handle;
4855 TestCompletionCallback callback;
4856 EXPECT_EQ(
4857 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284858 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4859 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4860 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
4861 pool_.get(), NetLogWithSource()));
Matt Menke833678642019-03-05 22:05:514862 base::RunLoop().RunUntilIdle();
4863 EXPECT_FALSE(callback.have_result());
4864}
4865
[email protected]58e562f2013-04-22 17:32:204866// Same as above, but the idle socket is in the same group as the stalled
4867// socket, and closes the only other request in its group when closing requests
4868// in higher layered pools. This generally shouldn't happen, but it may be
4869// possible if a higher level pool issues a request and the request is
4870// subsequently cancelled. Even if it's not possible, best not to crash.
4871TEST_F(ClientSocketPoolBaseTest,
4872 CloseIdleSocketsHeldByLayeredPoolWhenNeededSameGroup) {
4873 CreatePool(2, 2);
4874 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4875
4876 // Need a socket in another group for the pool to be stalled (If a group
4877 // has the maximum number of connections already, it's not stalled).
4878 ClientSocketHandle handle1;
4879 TestCompletionCallback callback1;
Matt Menkef09e64c2019-04-23 22:16:284880 EXPECT_EQ(OK, handle1.Init(TestGroupId("group1"), params_, base::nullopt,
4881 DEFAULT_PRIORITY, SocketTag(),
4882 ClientSocketPool::RespectLimits::ENABLED,
4883 callback1.callback(),
4884 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4885 NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:204886
Matt Menkec6b3edf72019-03-19 17:00:394887 MockLayeredPool mock_layered_pool(pool_.get(), TestGroupId("group2"));
robpercival214763f2016-07-01 23:27:014888 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:204889 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4890 .WillOnce(Invoke(&mock_layered_pool,
4891 &MockLayeredPool::ReleaseOneConnection));
4892 ClientSocketHandle handle;
4893 TestCompletionCallback callback2;
Matt Menkef09e64c2019-04-23 22:16:284894 EXPECT_EQ(ERR_IO_PENDING,
4895 handle.Init(
4896 TestGroupId("group2"), params_, base::nullopt, DEFAULT_PRIORITY,
4897 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4898 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4899 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:014900 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204901}
4902
4903// Tests the case when an idle socket can be closed when a new request is
4904// issued, and the new request belongs to a group that was previously stalled.
4905TEST_F(ClientSocketPoolBaseTest,
4906 CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded) {
4907 CreatePool(2, 2);
4908 std::list<TestConnectJob::JobType> job_types;
4909 job_types.push_back(TestConnectJob::kMockJob);
4910 job_types.push_back(TestConnectJob::kMockJob);
4911 job_types.push_back(TestConnectJob::kMockJob);
4912 job_types.push_back(TestConnectJob::kMockJob);
4913 connect_job_factory_->set_job_types(&job_types);
4914
4915 ClientSocketHandle handle1;
4916 TestCompletionCallback callback1;
Matt Menkef09e64c2019-04-23 22:16:284917 EXPECT_EQ(OK, handle1.Init(TestGroupId("group1"), params_, base::nullopt,
4918 DEFAULT_PRIORITY, SocketTag(),
4919 ClientSocketPool::RespectLimits::ENABLED,
4920 callback1.callback(),
4921 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4922 NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:204923
Matt Menkec6b3edf72019-03-19 17:00:394924 MockLayeredPool mock_layered_pool(pool_.get(), TestGroupId("group2"));
robpercival214763f2016-07-01 23:27:014925 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:204926 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4927 .WillRepeatedly(Invoke(&mock_layered_pool,
4928 &MockLayeredPool::ReleaseOneConnection));
4929 mock_layered_pool.set_can_release_connection(false);
4930
4931 // The third request is made when the socket pool is in a stalled state.
4932 ClientSocketHandle handle3;
4933 TestCompletionCallback callback3;
Matt Menkef09e64c2019-04-23 22:16:284934 EXPECT_EQ(ERR_IO_PENDING,
4935 handle3.Init(
4936 TestGroupId("group3"), params_, base::nullopt, DEFAULT_PRIORITY,
4937 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4938 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
4939 pool_.get(), NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:204940
4941 base::RunLoop().RunUntilIdle();
4942 EXPECT_FALSE(callback3.have_result());
4943
4944 // The fourth request is made when the pool is no longer stalled. The third
4945 // request should be serviced first, since it was issued first and has the
4946 // same priority.
4947 mock_layered_pool.set_can_release_connection(true);
4948 ClientSocketHandle handle4;
4949 TestCompletionCallback callback4;
Matt Menkef09e64c2019-04-23 22:16:284950 EXPECT_EQ(ERR_IO_PENDING,
4951 handle4.Init(
4952 TestGroupId("group3"), params_, base::nullopt, DEFAULT_PRIORITY,
4953 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4954 callback4.callback(), ClientSocketPool::ProxyAuthCallback(),
4955 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:014956 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204957 EXPECT_FALSE(callback4.have_result());
4958
4959 // Closing a handle should free up another socket slot.
4960 handle1.Reset();
robpercival214763f2016-07-01 23:27:014961 EXPECT_THAT(callback4.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204962}
4963
4964// Tests the case when an idle socket can be closed when a new request is
4965// issued, and the new request belongs to a group that was previously stalled.
4966//
4967// The two differences from the above test are that the stalled requests are not
4968// in the same group as the layered pool's request, and the the fourth request
4969// has a higher priority than the third one, so gets a socket first.
4970TEST_F(ClientSocketPoolBaseTest,
4971 CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded2) {
4972 CreatePool(2, 2);
4973 std::list<TestConnectJob::JobType> job_types;
4974 job_types.push_back(TestConnectJob::kMockJob);
4975 job_types.push_back(TestConnectJob::kMockJob);
4976 job_types.push_back(TestConnectJob::kMockJob);
4977 job_types.push_back(TestConnectJob::kMockJob);
4978 connect_job_factory_->set_job_types(&job_types);
4979
4980 ClientSocketHandle handle1;
4981 TestCompletionCallback callback1;
Matt Menkef09e64c2019-04-23 22:16:284982 EXPECT_EQ(OK, handle1.Init(TestGroupId("group1"), params_, base::nullopt,
4983 DEFAULT_PRIORITY, SocketTag(),
4984 ClientSocketPool::RespectLimits::ENABLED,
4985 callback1.callback(),
4986 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4987 NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:204988
Matt Menkec6b3edf72019-03-19 17:00:394989 MockLayeredPool mock_layered_pool(pool_.get(), TestGroupId("group2"));
robpercival214763f2016-07-01 23:27:014990 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:204991 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4992 .WillRepeatedly(Invoke(&mock_layered_pool,
4993 &MockLayeredPool::ReleaseOneConnection));
4994 mock_layered_pool.set_can_release_connection(false);
4995
4996 // The third request is made when the socket pool is in a stalled state.
4997 ClientSocketHandle handle3;
4998 TestCompletionCallback callback3;
tfarina428341112016-09-22 13:38:204999 EXPECT_EQ(
5000 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:285001 handle3.Init(TestGroupId("group3"), params_, base::nullopt, MEDIUM,
5002 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:505003 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
5004 pool_.get(), NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:205005
5006 base::RunLoop().RunUntilIdle();
5007 EXPECT_FALSE(callback3.have_result());
5008
5009 // The fourth request is made when the pool is no longer stalled. This
5010 // request has a higher priority than the third request, so is serviced first.
5011 mock_layered_pool.set_can_release_connection(true);
5012 ClientSocketHandle handle4;
5013 TestCompletionCallback callback4;
tfarina428341112016-09-22 13:38:205014 EXPECT_EQ(
5015 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:285016 handle4.Init(TestGroupId("group3"), params_, base::nullopt, HIGHEST,
5017 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:505018 callback4.callback(), ClientSocketPool::ProxyAuthCallback(),
5019 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:015020 EXPECT_THAT(callback4.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:205021 EXPECT_FALSE(callback3.have_result());
5022
5023 // Closing a handle should free up another socket slot.
5024 handle1.Reset();
robpercival214763f2016-07-01 23:27:015025 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:205026}
5027
5028TEST_F(ClientSocketPoolBaseTest,
5029 CloseMultipleIdleSocketsHeldByLayeredPoolWhenNeeded) {
5030 CreatePool(1, 1);
5031 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
5032
Matt Menkec6b3edf72019-03-19 17:00:395033 MockLayeredPool mock_layered_pool1(pool_.get(), TestGroupId("foo"));
robpercival214763f2016-07-01 23:27:015034 EXPECT_THAT(mock_layered_pool1.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:205035 EXPECT_CALL(mock_layered_pool1, CloseOneIdleConnection())
5036 .WillRepeatedly(Invoke(&mock_layered_pool1,
5037 &MockLayeredPool::ReleaseOneConnection));
Matt Menkec6b3edf72019-03-19 17:00:395038 MockLayeredPool mock_layered_pool2(pool_.get(), TestGroupId("bar"));
robpercival214763f2016-07-01 23:27:015039 EXPECT_THAT(mock_layered_pool2.RequestSocketWithoutLimits(pool_.get()),
5040 IsOk());
[email protected]58e562f2013-04-22 17:32:205041 EXPECT_CALL(mock_layered_pool2, CloseOneIdleConnection())
5042 .WillRepeatedly(Invoke(&mock_layered_pool2,
5043 &MockLayeredPool::ReleaseOneConnection));
5044 ClientSocketHandle handle;
5045 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:505046 EXPECT_EQ(
5047 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:285048 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
5049 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5050 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5051 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:015052 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:205053}
5054
[email protected]b021ece62013-06-11 11:06:335055// Test that when a socket pool and group are at their limits, a request
mmenked3641e12016-01-28 16:06:155056// with RespectLimits::DISABLED triggers creation of a new socket, and gets the
5057// socket instead of a request with the same priority that was issued earlier,
5058// but has RespectLimits::ENABLED.
[email protected]b021ece62013-06-11 11:06:335059TEST_F(ClientSocketPoolBaseTest, IgnoreLimits) {
[email protected]b021ece62013-06-11 11:06:335060 CreatePool(1, 1);
5061
5062 // Issue a request to reach the socket pool limit.
Matt Menkec6b3edf72019-03-19 17:00:395063 EXPECT_EQ(OK, StartRequestWithIgnoreLimits(
5064 TestGroupId("a"), MAXIMUM_PRIORITY,
5065 ClientSocketPool::RespectLimits::ENABLED));
Matt Menke9fa17d52019-03-25 19:12:265066 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]b021ece62013-06-11 11:06:335067
5068 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
5069
mmenked3641e12016-01-28 16:06:155070 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
Matt Menkec6b3edf72019-03-19 17:00:395071 TestGroupId("a"), MAXIMUM_PRIORITY,
mmenked3641e12016-01-28 16:06:155072 ClientSocketPool::RespectLimits::ENABLED));
Matt Menke9fa17d52019-03-25 19:12:265073 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]b021ece62013-06-11 11:06:335074
mmenked3641e12016-01-28 16:06:155075 // Issue a request that ignores the limits, so a new ConnectJob is
5076 // created.
5077 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
Matt Menkec6b3edf72019-03-19 17:00:395078 TestGroupId("a"), MAXIMUM_PRIORITY,
mmenked3641e12016-01-28 16:06:155079 ClientSocketPool::RespectLimits::DISABLED));
Matt Menke9fa17d52019-03-25 19:12:265080 ASSERT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]b021ece62013-06-11 11:06:335081
robpercival214763f2016-07-01 23:27:015082 EXPECT_THAT(request(2)->WaitForResult(), IsOk());
[email protected]b021ece62013-06-11 11:06:335083 EXPECT_FALSE(request(1)->have_result());
5084}
5085
[email protected]c55fabd2013-11-04 23:26:565086// Test that when a socket pool and group are at their limits, a ConnectJob
mmenked3641e12016-01-28 16:06:155087// issued for a request with RespectLimits::DISABLED is not cancelled when a
5088// request with RespectLimits::ENABLED issued to the same group is cancelled.
[email protected]c55fabd2013-11-04 23:26:565089TEST_F(ClientSocketPoolBaseTest, IgnoreLimitsCancelOtherJob) {
[email protected]c55fabd2013-11-04 23:26:565090 CreatePool(1, 1);
5091
5092 // Issue a request to reach the socket pool limit.
Matt Menkec6b3edf72019-03-19 17:00:395093 EXPECT_EQ(OK, StartRequestWithIgnoreLimits(
5094 TestGroupId("a"), MAXIMUM_PRIORITY,
5095 ClientSocketPool::RespectLimits::ENABLED));
Matt Menke9fa17d52019-03-25 19:12:265096 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]c55fabd2013-11-04 23:26:565097
5098 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
5099
mmenked3641e12016-01-28 16:06:155100 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
Matt Menkec6b3edf72019-03-19 17:00:395101 TestGroupId("a"), MAXIMUM_PRIORITY,
mmenked3641e12016-01-28 16:06:155102 ClientSocketPool::RespectLimits::ENABLED));
Matt Menke9fa17d52019-03-25 19:12:265103 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]c55fabd2013-11-04 23:26:565104
mmenked3641e12016-01-28 16:06:155105 // Issue a request with RespectLimits::DISABLED, so a new ConnectJob is
5106 // created.
5107 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
Matt Menkec6b3edf72019-03-19 17:00:395108 TestGroupId("a"), MAXIMUM_PRIORITY,
mmenked3641e12016-01-28 16:06:155109 ClientSocketPool::RespectLimits::DISABLED));
Matt Menke9fa17d52019-03-25 19:12:265110 ASSERT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]b021ece62013-06-11 11:06:335111
mmenked3641e12016-01-28 16:06:155112 // Cancel the pending request with RespectLimits::ENABLED. The ConnectJob
[email protected]b021ece62013-06-11 11:06:335113 // should not be cancelled.
5114 request(1)->handle()->Reset();
Matt Menke9fa17d52019-03-25 19:12:265115 ASSERT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]b021ece62013-06-11 11:06:335116
robpercival214763f2016-07-01 23:27:015117 EXPECT_THAT(request(2)->WaitForResult(), IsOk());
[email protected]b021ece62013-06-11 11:06:335118 EXPECT_FALSE(request(1)->have_result());
5119}
5120
Matt Menkeb57663b32019-03-01 17:17:105121TEST_F(ClientSocketPoolBaseTest, ProxyAuthNoAuthCallback) {
5122 CreatePool(1, 1);
5123
5124 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5125
5126 ClientSocketHandle handle;
5127 TestCompletionCallback callback;
5128 EXPECT_EQ(
5129 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:285130 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
5131 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5132 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5133 pool_.get(), NetLogWithSource()));
Matt Menkeb57663b32019-03-01 17:17:105134
Matt Menke9fa17d52019-03-25 19:12:265135 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105136
5137 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_PROXY_AUTH_REQUESTED));
5138 EXPECT_FALSE(handle.is_initialized());
5139 EXPECT_FALSE(handle.socket());
5140
5141 // The group should now be empty, and thus be deleted.
Matt Menke9fa17d52019-03-25 19:12:265142 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105143}
5144
5145class TestAuthHelper {
5146 public:
5147 TestAuthHelper() = default;
5148 ~TestAuthHelper() = default;
5149
Matt Menkec6b3edf72019-03-19 17:00:395150 void InitHandle(
Matt Menke84d11e562019-03-27 00:11:195151 scoped_refptr<ClientSocketPool::SocketParams> params,
Matt Menke9fa17d52019-03-25 19:12:265152 TransportClientSocketPool* pool,
Matt Menkec6b3edf72019-03-19 17:00:395153 RequestPriority priority = DEFAULT_PRIORITY,
5154 ClientSocketPool::RespectLimits respect_limits =
5155 ClientSocketPool::RespectLimits::ENABLED,
5156 const ClientSocketPool::GroupId& group_id_in = TestGroupId("a")) {
Matt Menkeb57663b32019-03-01 17:17:105157 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:285158 handle_.Init(group_id_in, params, base::nullopt, priority,
5159 SocketTag(), respect_limits, callback_.callback(),
Matt Menkeb57663b32019-03-01 17:17:105160 base::BindRepeating(&TestAuthHelper::AuthCallback,
5161 base::Unretained(this)),
5162 pool, NetLogWithSource()));
5163 }
5164
5165 void WaitForAuth() {
5166 run_loop_ = std::make_unique<base::RunLoop>();
5167 run_loop_->Run();
5168 run_loop_.reset();
5169 }
5170
5171 void WaitForAuthAndRestartSync() {
5172 restart_sync_ = true;
5173 WaitForAuth();
5174 restart_sync_ = false;
5175 }
5176
5177 void WaitForAuthAndResetHandleSync() {
5178 reset_handle_sync_ = true;
5179 WaitForAuth();
5180 reset_handle_sync_ = false;
5181 }
5182
5183 void RestartWithAuth() {
5184 DCHECK(restart_with_auth_callback_);
5185 std::move(restart_with_auth_callback_).Run();
5186 }
5187
5188 int WaitForResult() {
5189 int result = callback_.WaitForResult();
5190 // There shouldn't be any callback waiting to be invoked once the request is
5191 // complete.
5192 EXPECT_FALSE(restart_with_auth_callback_);
5193 // The socket should only be initialized on success.
5194 EXPECT_EQ(result == OK, handle_.is_initialized());
5195 EXPECT_EQ(result == OK, handle_.socket() != nullptr);
5196 return result;
5197 }
5198
5199 ClientSocketHandle* handle() { return &handle_; }
5200 int auth_count() const { return auth_count_; }
5201 int have_result() const { return callback_.have_result(); }
5202
5203 private:
5204 void AuthCallback(const HttpResponseInfo& response,
5205 HttpAuthController* auth_controller,
5206 base::OnceClosure restart_with_auth_callback) {
5207 EXPECT_FALSE(restart_with_auth_callback_);
5208 EXPECT_TRUE(restart_with_auth_callback);
5209
5210 // Once there's a result, this method shouldn't be invoked again.
5211 EXPECT_FALSE(callback_.have_result());
5212
5213 ++auth_count_;
5214 run_loop_->Quit();
5215 if (restart_sync_) {
5216 std::move(restart_with_auth_callback).Run();
5217 return;
5218 }
5219
5220 restart_with_auth_callback_ = std::move(restart_with_auth_callback);
5221
5222 if (reset_handle_sync_) {
5223 handle_.Reset();
5224 return;
5225 }
5226 }
5227
5228 std::unique_ptr<base::RunLoop> run_loop_;
5229 base::OnceClosure restart_with_auth_callback_;
5230
5231 bool restart_sync_ = false;
5232 bool reset_handle_sync_ = false;
5233
5234 ClientSocketHandle handle_;
5235 int auth_count_ = 0;
5236 TestCompletionCallback callback_;
5237
5238 DISALLOW_COPY_AND_ASSIGN(TestAuthHelper);
5239};
5240
5241TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnce) {
5242 CreatePool(1, 1);
5243 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5244
5245 TestAuthHelper auth_helper;
5246 auth_helper.InitHandle(params_, pool_.get());
Matt Menke9fa17d52019-03-25 19:12:265247 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menke4b69f932019-03-04 16:20:015248 EXPECT_EQ(LOAD_STATE_CONNECTING,
Matt Menkec6b3edf72019-03-19 17:00:395249 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:105250
5251 auth_helper.WaitForAuth();
Matt Menke9fa17d52019-03-25 19:12:265252 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menke4b69f932019-03-04 16:20:015253 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
Matt Menkec6b3edf72019-03-19 17:00:395254 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:105255
5256 auth_helper.RestartWithAuth();
Matt Menke9fa17d52019-03-25 19:12:265257 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menke4b69f932019-03-04 16:20:015258 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
Matt Menkec6b3edf72019-03-19 17:00:395259 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:105260
5261 EXPECT_THAT(auth_helper.WaitForResult(), IsOk());
5262 EXPECT_EQ(1, auth_helper.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265263 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5264 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:395265 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105266 EXPECT_EQ(0, pool_->IdleSocketCount());
5267}
5268
5269TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceSync) {
5270 CreatePool(1, 1);
5271 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5272
5273 TestAuthHelper auth_helper;
5274 auth_helper.InitHandle(params_, pool_.get());
Matt Menke9fa17d52019-03-25 19:12:265275 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menke4b69f932019-03-04 16:20:015276 EXPECT_EQ(LOAD_STATE_CONNECTING,
Matt Menkec6b3edf72019-03-19 17:00:395277 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:105278
5279 auth_helper.WaitForAuthAndRestartSync();
Matt Menke9fa17d52019-03-25 19:12:265280 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menke4b69f932019-03-04 16:20:015281 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
Matt Menkec6b3edf72019-03-19 17:00:395282 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:105283
5284 EXPECT_THAT(auth_helper.WaitForResult(), IsOk());
5285 EXPECT_EQ(1, auth_helper.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265286 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5287 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:395288 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105289 EXPECT_EQ(0, pool_->IdleSocketCount());
5290}
5291
5292TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceFails) {
5293 CreatePool(1, 1);
5294 connect_job_factory_->set_job_type(
5295 TestConnectJob::kMockAuthChallengeOnceFailingJob);
5296
5297 TestAuthHelper auth_helper;
5298 auth_helper.InitHandle(params_, pool_.get());
Matt Menke9fa17d52019-03-25 19:12:265299 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105300
5301 auth_helper.WaitForAuth();
5302 auth_helper.RestartWithAuth();
5303 EXPECT_THAT(auth_helper.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
5304
5305 EXPECT_EQ(1, auth_helper.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265306 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105307 EXPECT_EQ(0, pool_->IdleSocketCount());
5308}
5309
5310TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceSyncFails) {
5311 CreatePool(1, 1);
5312 connect_job_factory_->set_job_type(
5313 TestConnectJob::kMockAuthChallengeOnceFailingJob);
5314
5315 TestAuthHelper auth_helper;
5316 auth_helper.InitHandle(params_, pool_.get());
Matt Menke9fa17d52019-03-25 19:12:265317 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105318
5319 auth_helper.WaitForAuthAndRestartSync();
5320 EXPECT_THAT(auth_helper.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
5321
5322 EXPECT_EQ(1, auth_helper.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265323 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105324 EXPECT_EQ(0, pool_->IdleSocketCount());
5325}
5326
5327TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceDeleteHandle) {
5328 CreatePool(1, 1);
5329 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5330
5331 TestAuthHelper auth_helper;
5332 auth_helper.InitHandle(params_, pool_.get());
Matt Menke9fa17d52019-03-25 19:12:265333 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105334
5335 auth_helper.WaitForAuth();
Matt Menke9fa17d52019-03-25 19:12:265336 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105337
5338 auth_helper.handle()->Reset();
5339
5340 EXPECT_EQ(1, auth_helper.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265341 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105342 EXPECT_EQ(0, pool_->IdleSocketCount());
5343 EXPECT_FALSE(auth_helper.handle()->is_initialized());
5344 EXPECT_FALSE(auth_helper.handle()->socket());
5345}
5346
5347TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceDeleteHandleSync) {
5348 CreatePool(1, 1);
5349 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5350
5351 TestAuthHelper auth_helper;
5352 auth_helper.InitHandle(params_, pool_.get());
Matt Menke9fa17d52019-03-25 19:12:265353 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105354
5355 auth_helper.WaitForAuthAndResetHandleSync();
5356 EXPECT_EQ(1, auth_helper.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265357 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105358 EXPECT_EQ(0, pool_->IdleSocketCount());
5359 EXPECT_FALSE(auth_helper.handle()->is_initialized());
5360 EXPECT_FALSE(auth_helper.handle()->socket());
5361}
5362
5363TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceFlushWithError) {
5364 CreatePool(1, 1);
5365 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5366
5367 TestAuthHelper auth_helper;
5368 auth_helper.InitHandle(params_, pool_.get());
Matt Menke9fa17d52019-03-25 19:12:265369 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105370
5371 auth_helper.WaitForAuth();
5372
Matt Menke433de6d2020-03-04 00:24:115373 pool_->FlushWithError(ERR_FAILED, "Network changed");
Matt Menkeb57663b32019-03-01 17:17:105374 base::RunLoop().RunUntilIdle();
5375
5376 // When flushing the socket pool, bound sockets should delay returning the
5377 // error until completion.
5378 EXPECT_FALSE(auth_helper.have_result());
Matt Menke9fa17d52019-03-25 19:12:265379 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105380 EXPECT_EQ(0, pool_->IdleSocketCount());
5381
5382 auth_helper.RestartWithAuth();
5383 // The callback should be called asynchronously.
5384 EXPECT_FALSE(auth_helper.have_result());
5385
5386 EXPECT_THAT(auth_helper.WaitForResult(), IsError(ERR_FAILED));
Matt Menke9fa17d52019-03-25 19:12:265387 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105388 EXPECT_EQ(0, pool_->IdleSocketCount());
5389}
5390
5391TEST_F(ClientSocketPoolBaseTest, ProxyAuthTwice) {
5392 CreatePool(1, 1);
5393 connect_job_factory_->set_job_type(
5394 TestConnectJob::kMockAuthChallengeTwiceJob);
5395
5396 TestAuthHelper auth_helper;
5397 auth_helper.InitHandle(params_, pool_.get());
Matt Menke9fa17d52019-03-25 19:12:265398 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menke4b69f932019-03-04 16:20:015399 EXPECT_EQ(LOAD_STATE_CONNECTING,
Matt Menkec6b3edf72019-03-19 17:00:395400 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:105401
5402 auth_helper.WaitForAuth();
5403 auth_helper.RestartWithAuth();
Matt Menke9fa17d52019-03-25 19:12:265404 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105405 EXPECT_EQ(1, auth_helper.auth_count());
Matt Menke4b69f932019-03-04 16:20:015406 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
Matt Menkec6b3edf72019-03-19 17:00:395407 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:105408
5409 auth_helper.WaitForAuth();
Matt Menke9fa17d52019-03-25 19:12:265410 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menke4b69f932019-03-04 16:20:015411 EXPECT_EQ(2, auth_helper.auth_count());
5412 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
Matt Menkec6b3edf72019-03-19 17:00:395413 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
Matt Menke4b69f932019-03-04 16:20:015414
Matt Menkeb57663b32019-03-01 17:17:105415 auth_helper.RestartWithAuth();
Matt Menke9fa17d52019-03-25 19:12:265416 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105417 EXPECT_EQ(2, auth_helper.auth_count());
Matt Menke4b69f932019-03-04 16:20:015418 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
Matt Menkec6b3edf72019-03-19 17:00:395419 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:105420
5421 EXPECT_THAT(auth_helper.WaitForResult(), IsOk());
5422 EXPECT_EQ(2, auth_helper.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265423 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5424 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:395425 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105426 EXPECT_EQ(0, pool_->IdleSocketCount());
5427}
5428
5429TEST_F(ClientSocketPoolBaseTest, ProxyAuthTwiceFails) {
5430 CreatePool(1, 1);
5431 connect_job_factory_->set_job_type(
5432 TestConnectJob::kMockAuthChallengeTwiceFailingJob);
5433
5434 TestAuthHelper auth_helper;
5435 auth_helper.InitHandle(params_, pool_.get());
Matt Menke9fa17d52019-03-25 19:12:265436 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105437
5438 auth_helper.WaitForAuth();
5439 auth_helper.RestartWithAuth();
Matt Menke9fa17d52019-03-25 19:12:265440 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105441 EXPECT_EQ(1, auth_helper.auth_count());
5442
5443 auth_helper.WaitForAuth();
5444 auth_helper.RestartWithAuth();
Matt Menke9fa17d52019-03-25 19:12:265445 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105446 EXPECT_EQ(2, auth_helper.auth_count());
5447
5448 EXPECT_THAT(auth_helper.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
5449 EXPECT_EQ(2, auth_helper.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265450 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105451 EXPECT_EQ(0, pool_->IdleSocketCount());
5452}
5453
5454// Makes sure that when a bound request is destroyed, a new ConnectJob is
5455// created, if needed.
5456TEST_F(ClientSocketPoolBaseTest,
5457 ProxyAuthCreateNewConnectJobOnDestroyBoundRequest) {
5458 CreatePool(1 /* max_sockets */, 1 /* max_sockets_per_group */);
5459 connect_job_factory_->set_job_type(
5460 TestConnectJob::kMockAuthChallengeOnceFailingJob);
5461
5462 // First request creates a ConnectJob.
5463 TestAuthHelper auth_helper1;
5464 auth_helper1.InitHandle(params_, pool_.get());
Matt Menke9fa17d52019-03-25 19:12:265465 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105466
5467 // A second request come in, but no new ConnectJob is needed, since the limit
5468 // has been reached.
5469 TestAuthHelper auth_helper2;
5470 auth_helper2.InitHandle(params_, pool_.get());
Matt Menke9fa17d52019-03-25 19:12:265471 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105472
5473 // Run until the auth callback for the first request is invoked.
5474 auth_helper1.WaitForAuth();
5475 EXPECT_EQ(0, auth_helper2.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265476 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5477 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:395478 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105479
5480 // Make connect jobs succeed, then cancel the first request, which should
5481 // destroy the bound ConnectJob, and cause a new ConnectJob to start.
5482 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
5483 auth_helper1.handle()->Reset();
5484 EXPECT_EQ(0, auth_helper2.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265485 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105486
5487 // The second ConnectJob should succeed.
5488 EXPECT_THAT(auth_helper2.WaitForResult(), IsOk());
5489 EXPECT_EQ(0, auth_helper2.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265490 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105491}
5492
5493// Makes sure that when a bound request is destroyed, a new ConnectJob is
5494// created for another group, if needed.
5495TEST_F(ClientSocketPoolBaseTest,
5496 ProxyAuthCreateNewConnectJobOnDestroyBoundRequestDifferentGroups) {
5497 CreatePool(1 /* max_sockets */, 1 /* max_sockets_per_group */);
5498 connect_job_factory_->set_job_type(
5499 TestConnectJob::kMockAuthChallengeOnceFailingJob);
5500
5501 // First request creates a ConnectJob.
5502 TestAuthHelper auth_helper1;
5503 auth_helper1.InitHandle(params_, pool_.get(), DEFAULT_PRIORITY);
Matt Menke9fa17d52019-03-25 19:12:265504 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105505
5506 // A second request come in, but no new ConnectJob is needed, since the limit
5507 // has been reached.
5508 TestAuthHelper auth_helper2;
5509 auth_helper2.InitHandle(params_, pool_.get(), DEFAULT_PRIORITY,
Matt Menkec6b3edf72019-03-19 17:00:395510 ClientSocketPool::RespectLimits::ENABLED,
5511 TestGroupId("b"));
Matt Menke9fa17d52019-03-25 19:12:265512 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5513 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
Matt Menkeb57663b32019-03-01 17:17:105514
5515 // Run until the auth callback for the first request is invoked.
5516 auth_helper1.WaitForAuth();
5517 EXPECT_EQ(0, auth_helper2.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265518 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5519 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:395520 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menke9fa17d52019-03-25 19:12:265521 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
5522 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("b")));
Matt Menkec6b3edf72019-03-19 17:00:395523 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("b")));
Matt Menkeb57663b32019-03-01 17:17:105524
5525 // Make connect jobs succeed, then cancel the first request, which should
5526 // destroy the bound ConnectJob, and cause a new ConnectJob to start for the
5527 // other group.
5528 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
5529 auth_helper1.handle()->Reset();
5530 EXPECT_EQ(0, auth_helper2.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265531 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
5532 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
Matt Menkeb57663b32019-03-01 17:17:105533
5534 // The second ConnectJob should succeed.
5535 EXPECT_THAT(auth_helper2.WaitForResult(), IsOk());
5536 EXPECT_EQ(0, auth_helper2.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265537 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
5538 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
Matt Menkeb57663b32019-03-01 17:17:105539}
5540
5541// Test that once an auth challenge is bound, that's the request that gets all
5542// subsequent calls and the socket itself.
5543TEST_F(ClientSocketPoolBaseTest, ProxyAuthStaysBound) {
5544 CreatePool(1, 1);
5545 connect_job_factory_->set_job_type(
5546 TestConnectJob::kMockAuthChallengeTwiceJob);
5547
5548 // First request creates a ConnectJob.
5549 TestAuthHelper auth_helper1;
5550 auth_helper1.InitHandle(params_, pool_.get(), LOWEST);
Matt Menke9fa17d52019-03-25 19:12:265551 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105552
5553 // A second, higher priority request is made.
5554 TestAuthHelper auth_helper2;
5555 auth_helper2.InitHandle(params_, pool_.get(), LOW);
Matt Menke9fa17d52019-03-25 19:12:265556 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105557
5558 // Run until the auth callback for the second request is invoked.
5559 auth_helper2.WaitForAuth();
5560 EXPECT_EQ(0, auth_helper1.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265561 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5562 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:395563 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105564
5565 // Start a higher priority job. It shouldn't be able to steal |auth_helper2|'s
5566 // ConnectJob.
5567 TestAuthHelper auth_helper3;
5568 auth_helper3.InitHandle(params_, pool_.get(), HIGHEST);
Matt Menke9fa17d52019-03-25 19:12:265569 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105570
5571 // Start a higher job that ignores limits, creating a hanging socket. It
5572 // shouldn't be able to steal |auth_helper2|'s ConnectJob.
5573 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
5574 TestAuthHelper auth_helper4;
5575 auth_helper4.InitHandle(params_, pool_.get(), HIGHEST,
5576 ClientSocketPool::RespectLimits::DISABLED);
Matt Menke9fa17d52019-03-25 19:12:265577 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105578
5579 // Restart with auth, and |auth_helper2|'s auth method should be invoked
5580 // again.
5581 auth_helper2.RestartWithAuth();
5582 auth_helper2.WaitForAuth();
5583 EXPECT_EQ(0, auth_helper1.auth_count());
5584 EXPECT_FALSE(auth_helper1.have_result());
5585 EXPECT_EQ(2, auth_helper2.auth_count());
5586 EXPECT_FALSE(auth_helper2.have_result());
5587 EXPECT_EQ(0, auth_helper3.auth_count());
5588 EXPECT_FALSE(auth_helper3.have_result());
5589 EXPECT_EQ(0, auth_helper4.auth_count());
5590 EXPECT_FALSE(auth_helper4.have_result());
5591
5592 // Advance auth again, and |auth_helper2| should get the socket.
5593 auth_helper2.RestartWithAuth();
5594 EXPECT_THAT(auth_helper2.WaitForResult(), IsOk());
5595 // The hung ConnectJob for the RespectLimits::DISABLED request is still in the
5596 // socket pool.
Matt Menke9fa17d52019-03-25 19:12:265597 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5598 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105599 EXPECT_EQ(0, auth_helper1.auth_count());
5600 EXPECT_FALSE(auth_helper1.have_result());
5601 EXPECT_EQ(0, auth_helper3.auth_count());
5602 EXPECT_FALSE(auth_helper3.have_result());
5603 EXPECT_EQ(0, auth_helper4.auth_count());
5604 EXPECT_FALSE(auth_helper4.have_result());
5605
5606 // If the socket is returned to the socket pool, the RespectLimits::DISABLED
5607 // socket request should be able to claim it.
5608 auth_helper2.handle()->Reset();
5609 EXPECT_THAT(auth_helper4.WaitForResult(), IsOk());
5610 EXPECT_EQ(0, auth_helper1.auth_count());
5611 EXPECT_FALSE(auth_helper1.have_result());
5612 EXPECT_EQ(0, auth_helper3.auth_count());
5613 EXPECT_FALSE(auth_helper3.have_result());
5614 EXPECT_EQ(0, auth_helper4.auth_count());
5615}
5616
David Benjaminbac8dff2019-08-07 01:30:415617enum class RefreshType {
5618 kServer,
5619 kProxy,
5620};
5621
5622// Common base class to test RefreshGroup() when called from either
5623// OnSSLConfigForServerChanged() matching a specific group or the pool's proxy.
5624//
5625// Tests which test behavior specific to one or the other case should use
5626// ClientSocketPoolBaseTest directly. In particular, there is no "other group"
5627// when the pool's proxy matches.
5628class ClientSocketPoolBaseRefreshTest
5629 : public ClientSocketPoolBaseTest,
5630 public testing::WithParamInterface<RefreshType> {
5631 public:
5632 void CreatePoolForRefresh(int max_sockets,
5633 int max_sockets_per_group,
5634 bool enable_backup_connect_jobs = false) {
5635 switch (GetParam()) {
5636 case RefreshType::kServer:
5637 CreatePool(max_sockets, max_sockets_per_group,
5638 enable_backup_connect_jobs);
5639 break;
5640 case RefreshType::kProxy:
5641 CreatePoolWithIdleTimeouts(
5642 max_sockets, max_sockets_per_group, kUnusedIdleSocketTimeout,
5643 ClientSocketPool::used_idle_socket_timeout(),
5644 enable_backup_connect_jobs,
5645 ProxyServer::FromPacString("HTTPS myproxy:70"));
5646 break;
5647 }
5648 }
5649
5650 static ClientSocketPool::GroupId GetGroupId() {
5651 return TestGroupId("a", 443, ClientSocketPool::SocketType::kSsl);
5652 }
5653
David Benjamin6dd7e882019-10-10 02:35:235654 static ClientSocketPool::GroupId GetGroupIdInPartition() {
5655 // Note this GroupId will match GetGroupId() unless
5656 // kPartitionConnectionsByNetworkIsolationKey is enabled.
Matt Menke4807a9a2020-11-21 00:14:415657 const SchemefulSite kSite(GURL("https://b/"));
5658 const NetworkIsolationKey kNetworkIsolationKey(kSite, kSite);
David Benjamin6dd7e882019-10-10 02:35:235659 return TestGroupId("a", 443, ClientSocketPool::SocketType::kSsl,
5660 PrivacyMode::PRIVACY_MODE_DISABLED,
5661 kNetworkIsolationKey);
5662 }
5663
David Benjaminbac8dff2019-08-07 01:30:415664 void OnSSLConfigForServerChanged() {
5665 switch (GetParam()) {
5666 case RefreshType::kServer:
5667 pool_->OnSSLConfigForServerChanged(HostPortPair("a", 443));
5668 break;
5669 case RefreshType::kProxy:
5670 pool_->OnSSLConfigForServerChanged(HostPortPair("myproxy", 70));
5671 break;
5672 }
5673 }
5674};
5675
5676INSTANTIATE_TEST_SUITE_P(RefreshType,
5677 ClientSocketPoolBaseRefreshTest,
5678 ::testing::Values(RefreshType::kServer,
5679 RefreshType::kProxy));
5680
5681TEST_P(ClientSocketPoolBaseRefreshTest, RefreshGroupCreatesNewConnectJobs) {
5682 CreatePoolForRefresh(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
5683 const ClientSocketPool::GroupId kGroupId = GetGroupId();
Matt Menkebf3c767d2019-04-15 23:28:245684
5685 // First job will be waiting until it gets aborted.
5686 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
5687
5688 ClientSocketHandle handle;
5689 TestCompletionCallback callback;
5690 EXPECT_THAT(
Matt Menkef09e64c2019-04-23 22:16:285691 handle.Init(kGroupId, params_, base::nullopt, DEFAULT_PRIORITY,
5692 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5693 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5694 pool_.get(), NetLogWithSource()),
Matt Menkebf3c767d2019-04-15 23:28:245695 IsError(ERR_IO_PENDING));
5696
5697 // Switch connect job types, so creating a new ConnectJob will result in
5698 // success.
5699 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
5700
David Benjaminbac8dff2019-08-07 01:30:415701 OnSSLConfigForServerChanged();
Matt Menkebf3c767d2019-04-15 23:28:245702 EXPECT_EQ(OK, callback.WaitForResult());
5703 ASSERT_TRUE(handle.socket());
5704 EXPECT_EQ(0, pool_->IdleSocketCount());
5705 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId));
5706 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(kGroupId));
5707 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(kGroupId));
5708 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId));
5709}
5710
David Benjaminbac8dff2019-08-07 01:30:415711TEST_P(ClientSocketPoolBaseRefreshTest, RefreshGroupClosesIdleConnectJobs) {
David Benjamin6dd7e882019-10-10 02:35:235712 base::test::ScopedFeatureList feature_list;
5713 feature_list.InitAndEnableFeature(
5714 features::kPartitionConnectionsByNetworkIsolationKey);
5715
David Benjaminbac8dff2019-08-07 01:30:415716 CreatePoolForRefresh(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
5717 const ClientSocketPool::GroupId kGroupId = GetGroupId();
David Benjamin6dd7e882019-10-10 02:35:235718 const ClientSocketPool::GroupId kGroupIdInPartition = GetGroupIdInPartition();
Matt Menkebf3c767d2019-04-15 23:28:245719
Matt Menkef09e64c2019-04-23 22:16:285720 pool_->RequestSockets(kGroupId, params_, base::nullopt, 2,
5721 NetLogWithSource());
David Benjamin6dd7e882019-10-10 02:35:235722 pool_->RequestSockets(kGroupIdInPartition, params_, base::nullopt, 2,
5723 NetLogWithSource());
Matt Menkebf3c767d2019-04-15 23:28:245724 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId));
David Benjamin6dd7e882019-10-10 02:35:235725 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupIdInPartition));
5726 EXPECT_EQ(4, pool_->IdleSocketCount());
Matt Menkebf3c767d2019-04-15 23:28:245727 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(kGroupId));
David Benjamin6dd7e882019-10-10 02:35:235728 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(kGroupIdInPartition));
Matt Menkebf3c767d2019-04-15 23:28:245729
David Benjaminbac8dff2019-08-07 01:30:415730 OnSSLConfigForServerChanged();
Matt Menkebf3c767d2019-04-15 23:28:245731 EXPECT_EQ(0, pool_->IdleSocketCount());
5732 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupId));
David Benjamin6dd7e882019-10-10 02:35:235733 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupIdInPartition));
Matt Menkebf3c767d2019-04-15 23:28:245734}
5735
5736TEST_F(ClientSocketPoolBaseTest,
5737 RefreshGroupDoesNotCloseIdleConnectJobsInOtherGroup) {
5738 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
David Benjaminbac8dff2019-08-07 01:30:415739 const ClientSocketPool::GroupId kGroupId =
5740 TestGroupId("a", 443, ClientSocketPool::SocketType::kSsl);
5741 const ClientSocketPool::GroupId kOtherGroupId =
5742 TestGroupId("b", 443, ClientSocketPool::SocketType::kSsl);
Matt Menkebf3c767d2019-04-15 23:28:245743
Matt Menkef09e64c2019-04-23 22:16:285744 pool_->RequestSockets(kOtherGroupId, params_, base::nullopt, 2,
5745 NetLogWithSource());
Matt Menkebf3c767d2019-04-15 23:28:245746 ASSERT_TRUE(pool_->HasGroupForTesting(kOtherGroupId));
5747 EXPECT_EQ(2, pool_->IdleSocketCount());
5748 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(kOtherGroupId));
5749
David Benjaminbac8dff2019-08-07 01:30:415750 pool_->OnSSLConfigForServerChanged(HostPortPair("a", 443));
Matt Menkebf3c767d2019-04-15 23:28:245751 ASSERT_TRUE(pool_->HasGroupForTesting(kOtherGroupId));
5752 EXPECT_EQ(2, pool_->IdleSocketCount());
5753 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(kOtherGroupId));
5754}
5755
David Benjaminbac8dff2019-08-07 01:30:415756TEST_P(ClientSocketPoolBaseRefreshTest, RefreshGroupPreventsSocketReuse) {
5757 CreatePoolForRefresh(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
5758 const ClientSocketPool::GroupId kGroupId = GetGroupId();
Matt Menkebf3c767d2019-04-15 23:28:245759
5760 ClientSocketHandle handle;
5761 TestCompletionCallback callback;
5762 EXPECT_THAT(
Matt Menkef09e64c2019-04-23 22:16:285763 handle.Init(kGroupId, params_, base::nullopt, DEFAULT_PRIORITY,
5764 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5765 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5766 pool_.get(), NetLogWithSource()),
Matt Menkebf3c767d2019-04-15 23:28:245767 IsOk());
5768 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId));
5769 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId));
5770
David Benjaminbac8dff2019-08-07 01:30:415771 OnSSLConfigForServerChanged();
Matt Menkebf3c767d2019-04-15 23:28:245772
5773 handle.Reset();
5774 EXPECT_EQ(0, pool_->IdleSocketCount());
5775 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupId));
5776}
5777
5778TEST_F(ClientSocketPoolBaseTest,
5779 RefreshGroupDoesNotPreventSocketReuseInOtherGroup) {
5780 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
David Benjaminbac8dff2019-08-07 01:30:415781 const ClientSocketPool::GroupId kGroupId =
5782 TestGroupId("a", 443, ClientSocketPool::SocketType::kSsl);
5783 const ClientSocketPool::GroupId kOtherGroupId =
5784 TestGroupId("b", 443, ClientSocketPool::SocketType::kSsl);
Matt Menkebf3c767d2019-04-15 23:28:245785
5786 ClientSocketHandle handle;
5787 TestCompletionCallback callback;
5788 EXPECT_THAT(
Matt Menkef09e64c2019-04-23 22:16:285789 handle.Init(kOtherGroupId, params_, base::nullopt, DEFAULT_PRIORITY,
5790 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5791 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5792 pool_.get(), NetLogWithSource()),
Matt Menkebf3c767d2019-04-15 23:28:245793 IsOk());
5794 ASSERT_TRUE(pool_->HasGroupForTesting(kOtherGroupId));
5795 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kOtherGroupId));
5796
David Benjaminbac8dff2019-08-07 01:30:415797 pool_->OnSSLConfigForServerChanged(HostPortPair("a", 443));
Matt Menkebf3c767d2019-04-15 23:28:245798
5799 handle.Reset();
5800 EXPECT_EQ(1, pool_->IdleSocketCount());
5801 ASSERT_TRUE(pool_->HasGroupForTesting(kOtherGroupId));
5802 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(kOtherGroupId));
5803}
5804
David Benjaminbac8dff2019-08-07 01:30:415805TEST_P(ClientSocketPoolBaseRefreshTest,
5806 RefreshGroupReplacesBoundConnectJobOnConnect) {
5807 CreatePoolForRefresh(1, 1);
5808 const ClientSocketPool::GroupId kGroupId = GetGroupId();
Matt Menkebf3c767d2019-04-15 23:28:245809 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5810
5811 TestAuthHelper auth_helper;
5812 auth_helper.InitHandle(params_, pool_.get(), DEFAULT_PRIORITY,
5813 ClientSocketPool::RespectLimits::ENABLED, kGroupId);
5814 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(kGroupId));
5815
5816 auth_helper.WaitForAuth();
5817
5818 // This should update the generation, but not cancel the old ConnectJob - it's
5819 // not safe to do anything while waiting on the original ConnectJob.
David Benjaminbac8dff2019-08-07 01:30:415820 OnSSLConfigForServerChanged();
Matt Menkebf3c767d2019-04-15 23:28:245821
5822 // Providing auth credentials and restarting the request with them will cause
5823 // the ConnectJob to complete successfully, but the result will be discarded
5824 // because of the generation mismatch.
5825 auth_helper.RestartWithAuth();
5826
5827 // Despite using ConnectJobs that simulate a single challenge, a second
5828 // challenge will be seen, due to using a new ConnectJob.
5829 auth_helper.WaitForAuth();
5830 auth_helper.RestartWithAuth();
5831
5832 EXPECT_THAT(auth_helper.WaitForResult(), IsOk());
5833 EXPECT_TRUE(auth_helper.handle()->socket());
5834 EXPECT_EQ(2, auth_helper.auth_count());
5835
5836 // When released, the socket will be returned to the socket pool, and
5837 // available for reuse.
5838 auth_helper.handle()->Reset();
5839 EXPECT_EQ(1, pool_->IdleSocketCount());
5840 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId));
5841 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(kGroupId));
5842}
5843
David Benjaminbac8dff2019-08-07 01:30:415844TEST_F(ClientSocketPoolBaseTest, RefreshProxyRefreshesAllGroups) {
5845 CreatePoolWithIdleTimeouts(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
5846 kUnusedIdleSocketTimeout,
5847 ClientSocketPool::used_idle_socket_timeout(),
5848 false /* no backup connect jobs */,
5849 ProxyServer::FromPacString("HTTPS myproxy:70"));
5850
5851 const ClientSocketPool::GroupId kGroupId1 =
5852 TestGroupId("a", 443, ClientSocketPool::SocketType::kSsl);
5853 const ClientSocketPool::GroupId kGroupId2 =
5854 TestGroupId("b", 443, ClientSocketPool::SocketType::kSsl);
5855 const ClientSocketPool::GroupId kGroupId3 =
5856 TestGroupId("c", 443, ClientSocketPool::SocketType::kSsl);
5857
5858 // Make three sockets in three different groups. The third socket is released
5859 // to the pool as idle.
5860 ClientSocketHandle handle1, handle2, handle3;
5861 TestCompletionCallback callback;
5862 EXPECT_THAT(
5863 handle1.Init(kGroupId1, params_, base::nullopt, DEFAULT_PRIORITY,
5864 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5865 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5866 pool_.get(), NetLogWithSource()),
5867 IsOk());
5868 EXPECT_THAT(
5869 handle2.Init(kGroupId2, params_, base::nullopt, DEFAULT_PRIORITY,
5870 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5871 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5872 pool_.get(), NetLogWithSource()),
5873 IsOk());
5874 EXPECT_THAT(
5875 handle3.Init(kGroupId3, params_, base::nullopt, DEFAULT_PRIORITY,
5876 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5877 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5878 pool_.get(), NetLogWithSource()),
5879 IsOk());
5880 handle3.Reset();
5881 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId1));
5882 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId1));
5883 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId2));
5884 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId2));
5885 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId3));
5886 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(kGroupId3));
5887
5888 // Changes to some other proxy do not affect the pool. The idle socket remains
5889 // alive and closing |handle2| makes the socket available for the pool.
5890 pool_->OnSSLConfigForServerChanged(HostPortPair("someotherproxy", 70));
5891
5892 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId1));
5893 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId1));
5894 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId2));
5895 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId2));
5896 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId3));
5897 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(kGroupId3));
5898
5899 handle2.Reset();
5900 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId2));
5901 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(kGroupId2));
5902
5903 // Changes to the matching proxy refreshes all groups.
5904 pool_->OnSSLConfigForServerChanged(HostPortPair("myproxy", 70));
5905
5906 // Idle sockets are closed.
5907 EXPECT_EQ(0, pool_->IdleSocketCount());
5908 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupId2));
5909 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupId3));
5910
5911 // The active socket, however, continues to be active.
5912 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId1));
5913 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId1));
5914
5915 // Closing it does not make it available for the pool.
5916 handle1.Reset();
5917 EXPECT_EQ(0, pool_->IdleSocketCount());
5918 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupId1));
5919}
5920
5921TEST_F(ClientSocketPoolBaseTest, RefreshBothPrivacyAndNormalSockets) {
5922 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
5923
5924 const ClientSocketPool::GroupId kGroupId =
5925 TestGroupId("a", 443, ClientSocketPool::SocketType::kSsl,
5926 PrivacyMode::PRIVACY_MODE_DISABLED);
5927 const ClientSocketPool::GroupId kGroupIdPrivacy =
5928 TestGroupId("a", 443, ClientSocketPool::SocketType::kSsl,
5929 PrivacyMode::PRIVACY_MODE_ENABLED);
5930 const ClientSocketPool::GroupId kOtherGroupId =
5931 TestGroupId("b", 443, ClientSocketPool::SocketType::kSsl);
5932
5933 // Make a socket in each groups.
5934 ClientSocketHandle handle1, handle2, handle3;
5935 TestCompletionCallback callback;
5936 EXPECT_THAT(
5937 handle1.Init(kGroupId, params_, base::nullopt, DEFAULT_PRIORITY,
5938 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5939 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5940 pool_.get(), NetLogWithSource()),
5941 IsOk());
5942 EXPECT_THAT(
5943 handle2.Init(kGroupIdPrivacy, params_, base::nullopt, DEFAULT_PRIORITY,
5944 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5945 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5946 pool_.get(), NetLogWithSource()),
5947 IsOk());
5948 EXPECT_THAT(
5949 handle3.Init(kOtherGroupId, params_, base::nullopt, DEFAULT_PRIORITY,
5950 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5951 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5952 pool_.get(), NetLogWithSource()),
5953 IsOk());
5954 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId));
5955 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId));
5956 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupIdPrivacy));
5957 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupIdPrivacy));
5958 ASSERT_TRUE(pool_->HasGroupForTesting(kOtherGroupId));
5959 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kOtherGroupId));
5960
5961 pool_->OnSSLConfigForServerChanged(HostPortPair("a", 443));
5962
5963 // Active sockets continue to be active.
5964 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId));
5965 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId));
5966 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupIdPrivacy));
5967 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupIdPrivacy));
5968 ASSERT_TRUE(pool_->HasGroupForTesting(kOtherGroupId));
5969 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kOtherGroupId));
5970
5971 // Closing them leaves kOtherGroupId alone, but kGroupId and kGroupIdPrivacy
5972 // are unusable.
5973 handle1.Reset();
5974 handle2.Reset();
5975 handle3.Reset();
5976 EXPECT_EQ(1, pool_->IdleSocketCount());
5977 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupId));
5978 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupIdPrivacy));
5979 EXPECT_TRUE(pool_->HasGroupForTesting(kOtherGroupId));
5980 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(kOtherGroupId));
5981}
5982
[email protected]f6d1d6eb2009-06-24 20:16:095983} // namespace
5984
5985} // namespace net