blob: 9260e5e1838669914ba4ff38945e5efd915e0e46 [file] [log] [blame]
[email protected]e34400c32012-01-24 02:49:331// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]f6d1d6eb2009-06-24 20:16:092// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Matt Menke9fa17d52019-03-25 19:12:265#include "net/socket/transport_client_socket_pool.h"
[email protected]f6d1d6eb2009-06-24 20:16:096
tbansalf82cc8e2015-10-14 20:05:497#include <stdint.h>
dchengc7eeda422015-12-26 03:56:488#include <utility>
[email protected]51fdc7c2012-04-10 19:19:489#include <vector>
10
[email protected]6ecf2b92011-12-15 01:14:5211#include "base/bind.h"
12#include "base/bind_helpers.h"
[email protected]2041cf342010-02-19 03:15:5913#include "base/callback.h"
skyostil4891b25b2015-06-11 11:43:4514#include "base/location.h"
mmenke33d24423d2015-05-19 19:41:0915#include "base/logging.h"
[email protected]3b63f8f42011-03-28 01:54:1516#include "base/memory/ref_counted.h"
[email protected]6ea7b152011-12-21 21:21:1317#include "base/memory/weak_ptr.h"
Alexander Timin4f9c35c2018-11-01 20:15:2018#include "base/message_loop/message_loop.h"
Matt Menkef09e64c2019-04-23 22:16:2819#include "base/optional.h"
[email protected]034df0f32013-01-07 23:17:4820#include "base/run_loop.h"
skyostil4891b25b2015-06-11 11:43:4521#include "base/single_thread_task_runner.h"
Avi Drissman4365a4782018-12-28 19:26:2422#include "base/stl_util.h"
[email protected]fc9be5802013-06-11 10:56:5123#include "base/strings/string_number_conversions.h"
[email protected]18b577412013-07-18 04:19:1524#include "base/strings/stringprintf.h"
Matt Menke166443c2019-05-24 18:45:5925#include "base/test/scoped_feature_list.h"
[email protected]f214f8792011-01-01 02:17:0826#include "base/threading/platform_thread.h"
gabf767595f2016-05-11 18:50:3527#include "base/threading/thread_task_runner_handle.h"
[email protected]f3a1c642011-07-12 19:15:0328#include "base/values.h"
Matt Menke166443c2019-05-24 18:45:5929#include "net/base/features.h"
[email protected]034df0f32013-01-07 23:17:4830#include "net/base/load_timing_info.h"
[email protected]b258e0792013-01-12 07:11:5931#include "net/base/load_timing_info_test_util.h"
[email protected]d8eb84242010-09-25 02:25:0632#include "net/base/net_errors.h"
Matt Menke166443c2019-05-24 18:45:5933#include "net/base/network_isolation_key.h"
Matt Menkebdf777802019-04-22 19:38:5934#include "net/base/privacy_mode.h"
Matt Menkeaafff542019-04-22 22:09:3635#include "net/base/proxy_server.h"
[email protected]ac790b42009-12-02 04:31:3136#include "net/base/request_priority.h"
[email protected]f6d1d6eb2009-06-24 20:16:0937#include "net/base/test_completion_callback.h"
[email protected]277d5942010-08-11 21:02:3538#include "net/http/http_response_headers.h"
Matt Menke39b7c5a2019-04-10 19:47:5139#include "net/http/http_response_info.h"
eroman87c53d62015-04-02 06:51:0740#include "net/log/net_log.h"
mikecirone8b85c432016-09-08 19:11:0041#include "net/log/net_log_event_type.h"
mikecironef22f9812016-10-04 03:40:1942#include "net/log/net_log_source.h"
mikecirone8b85c432016-09-08 19:11:0043#include "net/log/net_log_source_type.h"
mmenke16a7cbdd2015-04-24 23:00:5644#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4645#include "net/log/test_net_log_util.h"
[email protected]f6d1d6eb2009-06-24 20:16:0946#include "net/socket/client_socket_factory.h"
47#include "net/socket/client_socket_handle.h"
tfarina5dd13c22016-11-16 12:08:2648#include "net/socket/datagram_client_socket.h"
tbansalca83c002016-04-28 20:56:2849#include "net/socket/socket_performance_watcher.h"
Paul Jensen8d6f87ec2018-01-13 00:46:5450#include "net/socket/socket_tag.h"
[email protected]75439d3b2009-07-23 22:11:1751#include "net/socket/socket_test_util.h"
[email protected]18ccfdb2013-08-15 00:13:4452#include "net/socket/ssl_client_socket.h"
[email protected]3268023f2011-05-05 00:08:1053#include "net/socket/stream_socket.h"
Matt Menke9fa17d52019-03-25 19:12:2654#include "net/socket/transport_connect_job.h"
Matt Menke39b7c5a2019-04-10 19:47:5155#include "net/ssl/ssl_cert_request_info.h"
robpercival214763f2016-07-01 23:27:0156#include "net/test/gtest_util.h"
Gabriel Charettec7108742019-08-23 03:31:4057#include "net/test/test_with_task_environment.h"
Matt Menkef09e64c2019-04-23 22:16:2858#include "net/traffic_annotation/network_traffic_annotation.h"
Ramin Halavati0a08cc82018-02-06 07:46:3859#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
[email protected]51fdc7c2012-04-10 19:19:4860#include "testing/gmock/include/gmock/gmock.h"
[email protected]f6d1d6eb2009-06-24 20:16:0961#include "testing/gtest/include/gtest/gtest.h"
62
robpercival214763f2016-07-01 23:27:0163using net::test::IsError;
64using net::test::IsOk;
65
[email protected]51fdc7c2012-04-10 19:19:4866using ::testing::Invoke;
67using ::testing::Return;
68
[email protected]f6d1d6eb2009-06-24 20:16:0969namespace net {
70
71namespace {
72
[email protected]211d21722009-07-22 15:48:5373const int kDefaultMaxSockets = 4;
[email protected]c9d6a1d2009-07-14 16:15:2074const int kDefaultMaxSocketsPerGroup = 2;
Tarun Bansala7635092019-02-20 10:00:5975constexpr base::TimeDelta kUnusedIdleSocketTimeout =
76 base::TimeDelta::FromSeconds(10);
[email protected]0b7648c2009-07-06 20:14:0177
Matt Menkebdf777802019-04-22 19:38:5978ClientSocketPool::GroupId TestGroupId(
79 const std::string& host,
80 int port = 80,
81 ClientSocketPool::SocketType socket_type =
82 ClientSocketPool::SocketType::kHttp,
Matt Menke166443c2019-05-24 18:45:5983 PrivacyMode privacy_mode = PrivacyMode::PRIVACY_MODE_DISABLED,
84 NetworkIsolationKey network_isolation_key = NetworkIsolationKey()) {
Matt Menkec6b3edf72019-03-19 17:00:3985 return ClientSocketPool::GroupId(HostPortPair(host, port), socket_type,
Matt Menke166443c2019-05-24 18:45:5986 privacy_mode, network_isolation_key);
Matt Menkec6b3edf72019-03-19 17:00:3987}
88
[email protected]034df0f32013-01-07 23:17:4889// Make sure |handle| sets load times correctly when it has been assigned a
90// reused socket.
91void TestLoadTimingInfoConnectedReused(const ClientSocketHandle& handle) {
92 LoadTimingInfo load_timing_info;
93 // Only pass true in as |is_reused|, as in general, HttpStream types should
94 // have stricter concepts of reuse than socket pools.
95 EXPECT_TRUE(handle.GetLoadTimingInfo(true, &load_timing_info));
96
97 EXPECT_EQ(true, load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:1998 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]034df0f32013-01-07 23:17:4899
[email protected]b258e0792013-01-12 07:11:59100 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
101 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:48102}
103
104// Make sure |handle| sets load times correctly when it has been assigned a
[email protected]b021ece62013-06-11 11:06:33105// fresh socket. Also runs TestLoadTimingInfoConnectedReused, since the owner
[email protected]034df0f32013-01-07 23:17:48106// of a connection where |is_reused| is false may consider the connection
107// reused.
108void TestLoadTimingInfoConnectedNotReused(const ClientSocketHandle& handle) {
109 EXPECT_FALSE(handle.is_reused());
110
111 LoadTimingInfo load_timing_info;
112 EXPECT_TRUE(handle.GetLoadTimingInfo(false, &load_timing_info));
113
114 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19115 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]034df0f32013-01-07 23:17:48116
[email protected]b258e0792013-01-12 07:11:59117 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
118 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
119 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:48120
121 TestLoadTimingInfoConnectedReused(handle);
122}
123
124// Make sure |handle| sets load times correctly, in the case that it does not
125// currently have a socket.
126void TestLoadTimingInfoNotConnected(const ClientSocketHandle& handle) {
127 // Should only be set to true once a socket is assigned, if at all.
128 EXPECT_FALSE(handle.is_reused());
129
130 LoadTimingInfo load_timing_info;
131 EXPECT_FALSE(handle.GetLoadTimingInfo(false, &load_timing_info));
132
133 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19134 EXPECT_EQ(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]034df0f32013-01-07 23:17:48135
[email protected]b258e0792013-01-12 07:11:59136 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
137 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:48138}
139
[email protected]3268023f2011-05-05 00:08:10140class MockClientSocket : public StreamSocket {
[email protected]f6d1d6eb2009-06-24 20:16:09141 public:
[email protected]034df0f32013-01-07 23:17:48142 explicit MockClientSocket(net::NetLog* net_log)
143 : connected_(false),
[email protected]0dc88b32014-03-26 20:12:28144 has_unread_data_(false),
tfarina428341112016-09-22 13:38:20145 net_log_(NetLogWithSource::Make(net_log, NetLogSourceType::SOCKET)),
Charlie Harrison3e4c0622018-05-13 15:44:30146 was_used_to_convey_data_(false) {}
[email protected]f6d1d6eb2009-06-24 20:16:09147
[email protected]0dc88b32014-03-26 20:12:28148 // Sets whether the socket has unread data. If true, the next call to Read()
149 // will return 1 byte and IsConnectedAndIdle() will return false.
150 void set_has_unread_data(bool has_unread_data) {
151 has_unread_data_ = has_unread_data;
152 }
153
[email protected]3f55aa12011-12-07 02:03:33154 // Socket implementation.
dchengb03027d2014-10-21 12:00:20155 int Read(IOBuffer* /* buf */,
156 int len,
Brad Lassey3a814172018-04-26 03:30:21157 CompletionOnceCallback /* callback */) override {
[email protected]0dc88b32014-03-26 20:12:28158 if (has_unread_data_ && len > 0) {
159 has_unread_data_ = false;
160 was_used_to_convey_data_ = true;
161 return 1;
162 }
[email protected]e86df8dc2013-03-30 13:18:28163 return ERR_UNEXPECTED;
[email protected]3f55aa12011-12-07 02:03:33164 }
[email protected]ab838892009-06-30 18:49:05165
[email protected]a2b2cfc2017-12-06 09:06:08166 int Write(
167 IOBuffer* /* buf */,
168 int len,
Brad Lassey3a814172018-04-26 03:30:21169 CompletionOnceCallback /* callback */,
[email protected]a2b2cfc2017-12-06 09:06:08170 const NetworkTrafficAnnotationTag& /*traffic_annotation*/) override {
[email protected]0f873e82010-09-02 16:09:01171 was_used_to_convey_data_ = true;
172 return len;
[email protected]ab838892009-06-30 18:49:05173 }
Avi Drissman13fc8932015-12-20 04:40:46174 int SetReceiveBufferSize(int32_t size) override { return OK; }
175 int SetSendBufferSize(int32_t size) override { return OK; }
[email protected]ab838892009-06-30 18:49:05176
[email protected]dbf036f2011-12-06 23:33:24177 // StreamSocket implementation.
Brad Lassey3a814172018-04-26 03:30:21178 int Connect(CompletionOnceCallback callback) override {
[email protected]dbf036f2011-12-06 23:33:24179 connected_ = true;
180 return OK;
181 }
[email protected]f6d1d6eb2009-06-24 20:16:09182
dchengb03027d2014-10-21 12:00:20183 void Disconnect() override { connected_ = false; }
184 bool IsConnected() const override { return connected_; }
185 bool IsConnectedAndIdle() const override {
[email protected]0dc88b32014-03-26 20:12:28186 return connected_ && !has_unread_data_;
187 }
[email protected]0b7648c2009-07-06 20:14:01188
dchengb03027d2014-10-21 12:00:20189 int GetPeerAddress(IPEndPoint* /* address */) const override {
[email protected]9f864b32010-01-20 15:01:16190 return ERR_UNEXPECTED;
[email protected]f6d1d6eb2009-06-24 20:16:09191 }
[email protected]f6d1d6eb2009-06-24 20:16:09192
dchengb03027d2014-10-21 12:00:20193 int GetLocalAddress(IPEndPoint* /* address */) const override {
[email protected]e7f74da2011-04-19 23:49:35194 return ERR_UNEXPECTED;
195 }
196
tfarina428341112016-09-22 13:38:20197 const NetLogWithSource& NetLog() const override { return net_log_; }
[email protected]a2006ece2010-04-23 16:44:02198
dchengb03027d2014-10-21 12:00:20199 bool WasEverUsed() const override { return was_used_to_convey_data_; }
tfarina2846404c2016-12-25 14:31:37200 bool WasAlpnNegotiated() const override { return false; }
dchengb03027d2014-10-21 12:00:20201 NextProto GetNegotiatedProtocol() const override { return kProtoUnknown; }
202 bool GetSSLInfo(SSLInfo* ssl_info) override { return false; }
ttuttle23fdb7b2015-05-15 01:28:03203 void GetConnectionAttempts(ConnectionAttempts* out) const override {
204 out->clear();
205 }
206 void ClearConnectionAttempts() override {}
207 void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
tbansalf82cc8e2015-10-14 20:05:49208 int64_t GetTotalReceivedBytes() const override {
209 NOTIMPLEMENTED();
210 return 0;
211 }
Paul Jensen0f49dec2017-12-12 23:39:58212 void ApplySocketTag(const SocketTag& tag) override {}
[email protected]9b5614a2010-08-25 20:29:45213
[email protected]f6d1d6eb2009-06-24 20:16:09214 private:
215 bool connected_;
[email protected]0dc88b32014-03-26 20:12:28216 bool has_unread_data_;
tfarina428341112016-09-22 13:38:20217 NetLogWithSource net_log_;
[email protected]0f873e82010-09-02 16:09:01218 bool was_used_to_convey_data_;
[email protected]f6d1d6eb2009-06-24 20:16:09219
[email protected]ab838892009-06-30 18:49:05220 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
[email protected]f6d1d6eb2009-06-24 20:16:09221};
222
[email protected]5fc08e32009-07-15 17:09:57223class TestConnectJob;
224
[email protected]f6d1d6eb2009-06-24 20:16:09225class MockClientSocketFactory : public ClientSocketFactory {
226 public:
[email protected]ab838892009-06-30 18:49:05227 MockClientSocketFactory() : allocation_count_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:09228
danakj655b66c2016-04-16 00:51:38229 std::unique_ptr<DatagramClientSocket> CreateDatagramClientSocket(
[email protected]5370c012011-06-29 03:47:04230 DatagramSocket::BindType bind_type,
[email protected]98b0e582011-06-22 14:31:41231 NetLog* net_log,
mikecironef22f9812016-10-04 03:40:19232 const NetLogSource& source) override {
[email protected]98b0e582011-06-22 14:31:41233 NOTREACHED();
David Benjamin24725be2019-07-24 20:57:18234 return nullptr;
[email protected]98b0e582011-06-22 14:31:41235 }
236
Helen Lid5bb9222018-04-12 15:33:09237 std::unique_ptr<TransportClientSocket> CreateTransportClientSocket(
[email protected]0a0b7682010-08-25 17:08:07238 const AddressList& addresses,
danakj655b66c2016-04-16 00:51:38239 std::unique_ptr<
240 SocketPerformanceWatcher> /* socket_performance_watcher */,
[email protected]0a0b7682010-08-25 17:08:07241 NetLog* /* net_log */,
mikecironef22f9812016-10-04 03:40:19242 const NetLogSource& /*source*/) override {
[email protected]f6d1d6eb2009-06-24 20:16:09243 allocation_count_++;
Helen Lid5bb9222018-04-12 15:33:09244 return nullptr;
[email protected]f6d1d6eb2009-06-24 20:16:09245 }
246
danakj655b66c2016-04-16 00:51:38247 std::unique_ptr<SSLClientSocket> CreateSSLClientSocket(
David Benjamin24725be2019-07-24 20:57:18248 SSLClientContext* context,
Matt Menke841fc412019-03-05 23:20:12249 std::unique_ptr<StreamSocket> stream_socket,
[email protected]4f4de7e62010-11-12 19:55:27250 const HostPortPair& host_and_port,
David Benjamin24725be2019-07-24 20:57:18251 const SSLConfig& ssl_config) override {
[email protected]f6d1d6eb2009-06-24 20:16:09252 NOTIMPLEMENTED();
David Benjamin24725be2019-07-24 20:57:18253 return nullptr;
[email protected]f6d1d6eb2009-06-24 20:16:09254 }
Matt Menkefd956922019-02-04 23:44:03255
Matt Menke52cd95a2019-02-08 06:16:27256 std::unique_ptr<ProxyClientSocket> CreateProxyClientSocket(
257 std::unique_ptr<StreamSocket> stream_socket,
258 const std::string& user_agent,
259 const HostPortPair& endpoint,
260 const ProxyServer& proxy_server,
261 HttpAuthController* http_auth_controller,
262 bool tunnel,
263 bool using_spdy,
264 NextProto negotiated_protocol,
265 ProxyDelegate* proxy_delegate,
Matt Menke52cd95a2019-02-08 06:16:27266 const NetworkTrafficAnnotationTag& traffic_annotation) override {
267 NOTIMPLEMENTED();
268 return nullptr;
269 }
270
[email protected]5fc08e32009-07-15 17:09:57271 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
[email protected]03b7c8c2013-07-20 04:38:55272
[email protected]5fc08e32009-07-15 17:09:57273 void SignalJobs();
274
[email protected]03b7c8c2013-07-20 04:38:55275 void SignalJob(size_t job);
276
277 void SetJobLoadState(size_t job, LoadState load_state);
278
Matt Menke141b87f22019-01-30 02:43:03279 // Sets the HasConnectionEstablished value of the specified job to true,
280 // without invoking the callback.
281 void SetJobHasEstablishedConnection(size_t job);
282
[email protected]f6d1d6eb2009-06-24 20:16:09283 int allocation_count() const { return allocation_count_; }
284
[email protected]f6d1d6eb2009-06-24 20:16:09285 private:
286 int allocation_count_;
[email protected]5fc08e32009-07-15 17:09:57287 std::vector<TestConnectJob*> waiting_jobs_;
[email protected]f6d1d6eb2009-06-24 20:16:09288};
289
[email protected]ab838892009-06-30 18:49:05290class TestConnectJob : public ConnectJob {
291 public:
292 enum JobType {
293 kMockJob,
294 kMockFailingJob,
295 kMockPendingJob,
296 kMockPendingFailingJob,
[email protected]5fc08e32009-07-15 17:09:57297 kMockWaitingJob,
Matt Menkeb57663b32019-03-01 17:17:10298
299 // Certificate errors return a socket in addition to an error code.
300 kMockCertErrorJob,
301 kMockPendingCertErrorJob,
302
[email protected]e60e47a2010-07-14 03:37:18303 kMockAdditionalErrorStateJob,
304 kMockPendingAdditionalErrorStateJob,
[email protected]0dc88b32014-03-26 20:12:28305 kMockUnreadDataJob,
Matt Menkeb57663b32019-03-01 17:17:10306
307 kMockAuthChallengeOnceJob,
308 kMockAuthChallengeTwiceJob,
309 kMockAuthChallengeOnceFailingJob,
310 kMockAuthChallengeTwiceFailingJob,
[email protected]ab838892009-06-30 18:49:05311 };
312
[email protected]994d4932010-07-12 17:55:13313 // The kMockPendingJob uses a slight delay before allowing the connect
314 // to complete.
315 static const int kPendingConnectDelay = 2;
316
[email protected]ab838892009-06-30 18:49:05317 TestConnectJob(JobType job_type,
Matt Menke16f5c2e52019-03-25 21:50:40318 RequestPriority request_priority,
319 SocketTag socket_tag,
[email protected]974ebd62009-08-03 23:14:34320 base::TimeDelta timeout_duration,
Matt Menkea6f99ad2019-03-08 02:26:43321 const CommonConnectJobParams* common_connect_job_params,
[email protected]ab838892009-06-30 18:49:05322 ConnectJob::Delegate* delegate,
Matt Menkea6f99ad2019-03-08 02:26:43323 MockClientSocketFactory* client_socket_factory)
Matt Menke16f5c2e52019-03-25 21:50:40324 : ConnectJob(request_priority,
325 socket_tag,
Matt Menke1a6c92d2019-02-23 00:25:38326 timeout_duration,
Matt Menkea6f99ad2019-03-08 02:26:43327 common_connect_job_params,
Matt Menke1a6c92d2019-02-23 00:25:38328 delegate,
329 nullptr /* net_log */,
330 NetLogSourceType::TRANSPORT_CONNECT_JOB,
331 NetLogEventType::TRANSPORT_CONNECT_JOB_CONNECT),
[email protected]2ab05b52009-07-01 23:57:58332 job_type_(job_type),
[email protected]ab838892009-06-30 18:49:05333 client_socket_factory_(client_socket_factory),
[email protected]e60e47a2010-07-14 03:37:18334 load_state_(LOAD_STATE_IDLE),
Matt Menke141b87f22019-01-30 02:43:03335 has_established_connection_(false),
Jeremy Romand54000b22019-07-08 18:40:16336 store_additional_error_state_(false) {}
[email protected]ab838892009-06-30 18:49:05337
[email protected]974ebd62009-08-03 23:14:34338 void Signal() {
[email protected]e772db3f2010-07-12 18:11:13339 DoConnect(waiting_success_, true /* async */, false /* recoverable */);
[email protected]974ebd62009-08-03 23:14:34340 }
341
[email protected]03b7c8c2013-07-20 04:38:55342 void set_load_state(LoadState load_state) { load_state_ = load_state; }
343
Matt Menke141b87f22019-01-30 02:43:03344 void set_has_established_connection() {
345 DCHECK(!has_established_connection_);
346 has_established_connection_ = true;
347 }
348
[email protected]03b7c8c2013-07-20 04:38:55349 // From ConnectJob:
350
dchengb03027d2014-10-21 12:00:20351 LoadState GetLoadState() const override { return load_state_; }
[email protected]46451352009-09-01 14:54:21352
Matt Menke141b87f22019-01-30 02:43:03353 bool HasEstablishedConnection() const override {
354 return has_established_connection_;
355 }
356
Matt Menke6f84d1f12019-04-11 19:26:47357 bool IsSSLError() const override { return store_additional_error_state_; }
358
359 scoped_refptr<SSLCertRequestInfo> GetCertRequestInfo() override {
360 if (store_additional_error_state_)
361 return base::MakeRefCounted<SSLCertRequestInfo>();
362 return nullptr;
[email protected]e60e47a2010-07-14 03:37:18363 }
364
[email protected]974ebd62009-08-03 23:14:34365 private:
[email protected]03b7c8c2013-07-20 04:38:55366 // From ConnectJob:
[email protected]ab838892009-06-30 18:49:05367
dchengb03027d2014-10-21 12:00:20368 int ConnectInternal() override {
[email protected]ab838892009-06-30 18:49:05369 AddressList ignored;
Raul Tambre94493c652019-03-11 17:18:35370 client_socket_factory_->CreateTransportClientSocket(
371 ignored, nullptr, nullptr, NetLogSource());
[email protected]ab838892009-06-30 18:49:05372 switch (job_type_) {
373 case kMockJob:
[email protected]e772db3f2010-07-12 18:11:13374 return DoConnect(true /* successful */, false /* sync */,
Matt Menkeb57663b32019-03-01 17:17:10375 false /* cert_error */);
[email protected]ab838892009-06-30 18:49:05376 case kMockFailingJob:
[email protected]e772db3f2010-07-12 18:11:13377 return DoConnect(false /* error */, false /* sync */,
Matt Menkeb57663b32019-03-01 17:17:10378 false /* cert_error */);
[email protected]ab838892009-06-30 18:49:05379 case kMockPendingJob:
[email protected]5fc08e32009-07-15 17:09:57380 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47381
382 // Depending on execution timings, posting a delayed task can result
383 // in the task getting executed the at the earliest possible
384 // opportunity or only after returning once from the message loop and
385 // then a second call into the message loop. In order to make behavior
386 // more deterministic, we change the default delay to 2ms. This should
387 // always require us to wait for the second call into the message loop.
388 //
389 // N.B. The correct fix for this and similar timing problems is to
390 // abstract time for the purpose of unittests. Unfortunately, we have
391 // a lot of third-party components that directly call the various
392 // time functions, so this change would be rather invasive.
skyostil4891b25b2015-06-11 11:43:45393 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05394 FROM_HERE,
kylecharf4fe5172019-02-15 18:53:49395 base::BindOnce(base::IgnoreResult(&TestConnectJob::DoConnect),
396 weak_factory_.GetWeakPtr(), true /* successful */,
Matt Menkeb57663b32019-03-01 17:17:10397 true /* async */, false /* cert_error */),
[email protected]5761ab9c2012-02-04 16:44:53398 base::TimeDelta::FromMilliseconds(kPendingConnectDelay));
[email protected]ab838892009-06-30 18:49:05399 return ERR_IO_PENDING;
400 case kMockPendingFailingJob:
[email protected]5fc08e32009-07-15 17:09:57401 set_load_state(LOAD_STATE_CONNECTING);
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(), false /* error */,
Matt Menkeb57663b32019-03-01 17:17:10406 true /* async */, false /* cert_error */),
[email protected]5761ab9c2012-02-04 16:44:53407 base::TimeDelta::FromMilliseconds(2));
[email protected]ab838892009-06-30 18:49:05408 return ERR_IO_PENDING;
[email protected]5fc08e32009-07-15 17:09:57409 case kMockWaitingJob:
[email protected]03b7c8c2013-07-20 04:38:55410 set_load_state(LOAD_STATE_CONNECTING);
[email protected]5fc08e32009-07-15 17:09:57411 client_socket_factory_->WaitForSignal(this);
412 waiting_success_ = true;
413 return ERR_IO_PENDING;
Matt Menkeb57663b32019-03-01 17:17:10414 case kMockCertErrorJob:
[email protected]e772db3f2010-07-12 18:11:13415 return DoConnect(false /* error */, false /* sync */,
Matt Menkeb57663b32019-03-01 17:17:10416 true /* cert_error */);
417 case kMockPendingCertErrorJob:
[email protected]e772db3f2010-07-12 18:11:13418 set_load_state(LOAD_STATE_CONNECTING);
skyostil4891b25b2015-06-11 11:43:45419 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]e772db3f2010-07-12 18:11:13420 FROM_HERE,
kylecharf4fe5172019-02-15 18:53:49421 base::BindOnce(base::IgnoreResult(&TestConnectJob::DoConnect),
422 weak_factory_.GetWeakPtr(), false /* error */,
Matt Menkeb57663b32019-03-01 17:17:10423 true /* async */, true /* cert_error */),
[email protected]5761ab9c2012-02-04 16:44:53424 base::TimeDelta::FromMilliseconds(2));
[email protected]e772db3f2010-07-12 18:11:13425 return ERR_IO_PENDING;
[email protected]e60e47a2010-07-14 03:37:18426 case kMockAdditionalErrorStateJob:
427 store_additional_error_state_ = true;
428 return DoConnect(false /* error */, false /* sync */,
Matt Menkeb57663b32019-03-01 17:17:10429 false /* cert_error */);
[email protected]e60e47a2010-07-14 03:37:18430 case kMockPendingAdditionalErrorStateJob:
431 set_load_state(LOAD_STATE_CONNECTING);
432 store_additional_error_state_ = true;
skyostil4891b25b2015-06-11 11:43:45433 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]e60e47a2010-07-14 03:37:18434 FROM_HERE,
kylecharf4fe5172019-02-15 18:53:49435 base::BindOnce(base::IgnoreResult(&TestConnectJob::DoConnect),
436 weak_factory_.GetWeakPtr(), false /* error */,
Matt Menkeb57663b32019-03-01 17:17:10437 true /* async */, false /* cert_error */),
[email protected]5761ab9c2012-02-04 16:44:53438 base::TimeDelta::FromMilliseconds(2));
[email protected]e60e47a2010-07-14 03:37:18439 return ERR_IO_PENDING;
[email protected]0dc88b32014-03-26 20:12:28440 case kMockUnreadDataJob: {
441 int ret = DoConnect(true /* successful */, false /* sync */,
Matt Menkeb57663b32019-03-01 17:17:10442 false /* cert_error */);
[email protected]0dc88b32014-03-26 20:12:28443 static_cast<MockClientSocket*>(socket())->set_has_unread_data(true);
444 return ret;
445 }
Matt Menkeb57663b32019-03-01 17:17:10446 case kMockAuthChallengeOnceJob:
Matt Menke4b69f932019-03-04 16:20:01447 set_load_state(LOAD_STATE_CONNECTING);
Matt Menkeb57663b32019-03-01 17:17:10448 DoAdvanceAuthChallenge(1, true /* succeed_after_last_challenge */);
449 return ERR_IO_PENDING;
450 case kMockAuthChallengeTwiceJob:
Matt Menke4b69f932019-03-04 16:20:01451 set_load_state(LOAD_STATE_CONNECTING);
Matt Menkeb57663b32019-03-01 17:17:10452 DoAdvanceAuthChallenge(2, true /* succeed_after_last_challenge */);
453 return ERR_IO_PENDING;
454 case kMockAuthChallengeOnceFailingJob:
Matt Menke4b69f932019-03-04 16:20:01455 set_load_state(LOAD_STATE_CONNECTING);
Matt Menkeb57663b32019-03-01 17:17:10456 DoAdvanceAuthChallenge(1, false /* succeed_after_last_challenge */);
457 return ERR_IO_PENDING;
458 case kMockAuthChallengeTwiceFailingJob:
Matt Menke4b69f932019-03-04 16:20:01459 set_load_state(LOAD_STATE_CONNECTING);
Matt Menkeb57663b32019-03-01 17:17:10460 DoAdvanceAuthChallenge(2, false /* succeed_after_last_challenge */);
461 return ERR_IO_PENDING;
[email protected]ab838892009-06-30 18:49:05462 default:
463 NOTREACHED();
danakj655b66c2016-04-16 00:51:38464 SetSocket(std::unique_ptr<StreamSocket>());
[email protected]ab838892009-06-30 18:49:05465 return ERR_FAILED;
466 }
467 }
468
Lily Chen02ef29a2018-11-30 16:31:43469 void ChangePriorityInternal(RequestPriority priority) override {}
470
Matt Menkeb57663b32019-03-01 17:17:10471 int DoConnect(bool succeed, bool was_async, bool cert_error) {
[email protected]e772db3f2010-07-12 18:11:13472 int result = OK;
Matt Menke141b87f22019-01-30 02:43:03473 has_established_connection_ = true;
[email protected]ab838892009-06-30 18:49:05474 if (succeed) {
Matt Menkeb57663b32019-03-01 17:17:10475 SetSocket(std::make_unique<MockClientSocket>(net_log().net_log()));
Bence Békybdbb0e72018-08-07 21:42:59476 socket()->Connect(CompletionOnceCallback());
Matt Menkeb57663b32019-03-01 17:17:10477 } else if (cert_error) {
478 SetSocket(std::make_unique<MockClientSocket>(net_log().net_log()));
479 result = ERR_CERT_COMMON_NAME_INVALID;
[email protected]6e713f02009-08-06 02:56:40480 } else {
[email protected]e772db3f2010-07-12 18:11:13481 result = ERR_CONNECTION_FAILED;
danakj655b66c2016-04-16 00:51:38482 SetSocket(std::unique_ptr<StreamSocket>());
[email protected]ab838892009-06-30 18:49:05483 }
[email protected]2ab05b52009-07-01 23:57:58484
485 if (was_async)
[email protected]fd7b7c92009-08-20 19:38:30486 NotifyDelegateOfCompletion(result);
[email protected]ab838892009-06-30 18:49:05487 return result;
488 }
489
Matt Menkeb57663b32019-03-01 17:17:10490 void DoAdvanceAuthChallenge(int remaining_challenges,
491 bool succeed_after_last_challenge) {
492 base::ThreadTaskRunnerHandle::Get()->PostTask(
493 FROM_HERE,
494 base::BindOnce(&TestConnectJob::InvokeNextProxyAuthCallback,
495 weak_factory_.GetWeakPtr(), remaining_challenges,
496 succeed_after_last_challenge));
497 }
498
499 void InvokeNextProxyAuthCallback(int remaining_challenges,
500 bool succeed_after_last_challenge) {
Matt Menke4b69f932019-03-04 16:20:01501 set_load_state(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL);
Matt Menkeb57663b32019-03-01 17:17:10502 if (remaining_challenges == 0) {
503 DoConnect(succeed_after_last_challenge, true /* was_async */,
504 false /* cert_error */);
505 return;
506 }
507
508 // Integration tests make sure HttpResponseInfo and HttpAuthController work.
509 // The auth tests here are just focused on ConnectJob bookkeeping.
510 HttpResponseInfo info;
511 NotifyDelegateOfProxyAuth(
512 info, nullptr /* http_auth_controller */,
513 base::BindOnce(&TestConnectJob::DoAdvanceAuthChallenge,
514 weak_factory_.GetWeakPtr(), remaining_challenges - 1,
515 succeed_after_last_challenge));
516 }
517
[email protected]5fc08e32009-07-15 17:09:57518 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05519 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57520 MockClientSocketFactory* const client_socket_factory_;
[email protected]46451352009-09-01 14:54:21521 LoadState load_state_;
Matt Menke141b87f22019-01-30 02:43:03522 bool has_established_connection_;
[email protected]e60e47a2010-07-14 03:37:18523 bool store_additional_error_state_;
[email protected]ab838892009-06-30 18:49:05524
Jeremy Romand54000b22019-07-08 18:40:16525 base::WeakPtrFactory<TestConnectJob> weak_factory_{this};
[email protected]d5492c52013-11-10 20:44:39526
[email protected]ab838892009-06-30 18:49:05527 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
528};
529
[email protected]d80a4322009-08-14 07:07:49530class TestConnectJobFactory
Matt Menke16f5c2e52019-03-25 21:50:40531 : public TransportClientSocketPool::ConnectJobFactory {
[email protected]ab838892009-06-30 18:49:05532 public:
[email protected]034df0f32013-01-07 23:17:48533 TestConnectJobFactory(MockClientSocketFactory* client_socket_factory,
534 NetLog* net_log)
Matt Menkea6f99ad2019-03-08 02:26:43535 : common_connect_job_params_(
536 nullptr /* client_socket_factory */,
537 nullptr /* host_resolver */,
Matt Menkeb88837e2019-03-20 11:50:40538 nullptr /* http_auth_cache */,
539 nullptr /* http_auth_handler_factory */,
540 nullptr /* spdy_session_pool */,
Matt Menkeb5fb42b2019-03-22 17:26:13541 nullptr /* quic_supported_versions */,
Matt Menkeb88837e2019-03-20 11:50:40542 nullptr /* quic_stream_factory */,
Matt Menkea6f99ad2019-03-08 02:26:43543 nullptr /* proxy_delegate */,
Matt Menked732ea42019-03-08 12:05:00544 nullptr /* http_user_agent_settings */,
David Benjamin24725be2019-07-24 20:57:18545 nullptr /* ssl_client_context */,
Matt Menkea6f99ad2019-03-08 02:26:43546 nullptr /* socket_performance_watcher_factory */,
547 nullptr /* network_quality_estimator */,
548 net_log,
549 nullptr /* websocket_endpoint_lock_manager */),
550 job_type_(TestConnectJob::kMockJob),
Raul Tambre94493c652019-03-11 17:18:35551 job_types_(nullptr),
Matt Menkea6f99ad2019-03-08 02:26:43552 client_socket_factory_(client_socket_factory) {}
[email protected]ab838892009-06-30 18:49:05553
Chris Watkins7a41d3552017-12-01 02:13:27554 ~TestConnectJobFactory() override = default;
[email protected]ab838892009-06-30 18:49:05555
556 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
557
[email protected]51fdc7c2012-04-10 19:19:48558 void set_job_types(std::list<TestConnectJob::JobType>* job_types) {
559 job_types_ = job_types;
560 CHECK(!job_types_->empty());
561 }
562
[email protected]974ebd62009-08-03 23:14:34563 void set_timeout_duration(base::TimeDelta timeout_duration) {
564 timeout_duration_ = timeout_duration;
565 }
566
[email protected]3f55aa12011-12-07 02:03:33567 // ConnectJobFactory implementation.
[email protected]83039bb2011-12-09 18:43:55568
danakj655b66c2016-04-16 00:51:38569 std::unique_ptr<ConnectJob> NewConnectJob(
Matt Menkeaafff542019-04-22 22:09:36570 ClientSocketPool::GroupId group_id,
571 scoped_refptr<ClientSocketPool::SocketParams> socket_params,
Matt Menkef09e64c2019-04-23 22:16:28572 const base::Optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
Matt Menke16f5c2e52019-03-25 21:50:40573 RequestPriority request_priority,
574 SocketTag socket_tag,
mostynbba063d6032014-10-09 11:01:13575 ConnectJob::Delegate* delegate) const override {
[email protected]51fdc7c2012-04-10 19:19:48576 EXPECT_TRUE(!job_types_ || !job_types_->empty());
577 TestConnectJob::JobType job_type = job_type_;
578 if (job_types_ && !job_types_->empty()) {
579 job_type = job_types_->front();
580 job_types_->pop_front();
581 }
Matt Menkea6f99ad2019-03-08 02:26:43582 return std::make_unique<TestConnectJob>(
Matt Menke16f5c2e52019-03-25 21:50:40583 job_type, request_priority, socket_tag, timeout_duration_,
584 &common_connect_job_params_, delegate, client_socket_factory_);
[email protected]ab838892009-06-30 18:49:05585 }
586
587 private:
Matt Menkea6f99ad2019-03-08 02:26:43588 const CommonConnectJobParams common_connect_job_params_;
[email protected]ab838892009-06-30 18:49:05589 TestConnectJob::JobType job_type_;
[email protected]51fdc7c2012-04-10 19:19:48590 std::list<TestConnectJob::JobType>* job_types_;
[email protected]974ebd62009-08-03 23:14:34591 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57592 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05593
594 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
595};
596
[email protected]a937a06d2009-08-19 21:19:24597} // namespace
598
[email protected]a937a06d2009-08-19 21:19:24599namespace {
600
[email protected]5fc08e32009-07-15 17:09:57601void MockClientSocketFactory::SignalJobs() {
jdoerrie22a91d8b92018-10-05 08:43:26602 for (auto it = waiting_jobs_.begin(); it != waiting_jobs_.end(); ++it) {
[email protected]5fc08e32009-07-15 17:09:57603 (*it)->Signal();
604 }
605 waiting_jobs_.clear();
606}
607
[email protected]03b7c8c2013-07-20 04:38:55608void MockClientSocketFactory::SignalJob(size_t job) {
609 ASSERT_LT(job, waiting_jobs_.size());
610 waiting_jobs_[job]->Signal();
611 waiting_jobs_.erase(waiting_jobs_.begin() + job);
612}
613
614void MockClientSocketFactory::SetJobLoadState(size_t job,
615 LoadState load_state) {
616 ASSERT_LT(job, waiting_jobs_.size());
617 waiting_jobs_[job]->set_load_state(load_state);
618}
619
Matt Menke141b87f22019-01-30 02:43:03620void MockClientSocketFactory::SetJobHasEstablishedConnection(size_t job) {
621 ASSERT_LT(job, waiting_jobs_.size());
622 waiting_jobs_[job]->set_has_established_connection();
623}
624
Gabriel Charette694c3c332019-08-19 14:53:05625class ClientSocketPoolBaseTest : public TestWithTaskEnvironment {
[email protected]f6d1d6eb2009-06-24 20:16:09626 protected:
Alex Clarke0def2092018-12-10 12:01:45627 ClientSocketPoolBaseTest()
Gabriel Charette694c3c332019-08-19 14:53:05628 : TestWithTaskEnvironment(
629 base::test::TaskEnvironment::TimeSource::MOCK_TIME),
Matt Menke870e19ab2019-04-23 16:23:03630 params_(ClientSocketPool::SocketParams::CreateForHttpForTesting()) {
[email protected]636b8252011-04-08 19:56:54631 connect_backup_jobs_enabled_ =
Matt Menke16f5c2e52019-03-25 21:50:40632 TransportClientSocketPool::connect_backup_jobs_enabled();
633 TransportClientSocketPool::set_connect_backup_jobs_enabled(true);
[email protected]636b8252011-04-08 19:56:54634 }
[email protected]2431756e2010-09-29 20:26:13635
dcheng67be2b1f2014-10-27 21:47:29636 ~ClientSocketPoolBaseTest() override {
Matt Menke16f5c2e52019-03-25 21:50:40637 TransportClientSocketPool::set_connect_backup_jobs_enabled(
[email protected]636b8252011-04-08 19:56:54638 connect_backup_jobs_enabled_);
639 }
[email protected]c9d6a1d2009-07-14 16:15:20640
Matt Menke9fa17d52019-03-25 19:12:26641 void CreatePool(int max_sockets,
642 int max_sockets_per_group,
643 bool enable_backup_connect_jobs = false) {
Tarun Bansala7635092019-02-20 10:00:59644 CreatePoolWithIdleTimeouts(max_sockets, max_sockets_per_group,
645 kUnusedIdleSocketTimeout,
Matt Menke9fa17d52019-03-25 19:12:26646 ClientSocketPool::used_idle_socket_timeout(),
647 enable_backup_connect_jobs);
[email protected]9bf28db2009-08-29 01:35:16648 }
649
David Benjaminbac8dff2019-08-07 01:30:41650 void CreatePoolWithIdleTimeouts(
651 int max_sockets,
652 int max_sockets_per_group,
653 base::TimeDelta unused_idle_socket_timeout,
654 base::TimeDelta used_idle_socket_timeout,
655 bool enable_backup_connect_jobs = false,
656 ProxyServer proxy_server = ProxyServer::Direct()) {
[email protected]c9d6a1d2009-07-14 16:15:20657 DCHECK(!pool_.get());
Matt Menke9fa17d52019-03-25 19:12:26658 std::unique_ptr<TestConnectJobFactory> connect_job_factory =
659 std::make_unique<TestConnectJobFactory>(&client_socket_factory_,
660 &net_log_);
661 connect_job_factory_ = connect_job_factory.get();
662 pool_ = TransportClientSocketPool::CreateForTesting(
663 max_sockets, max_sockets_per_group, unused_idle_socket_timeout,
David Benjaminbac8dff2019-08-07 01:30:41664 used_idle_socket_timeout, proxy_server, std::move(connect_job_factory),
Matt Menke9fa17d52019-03-25 19:12:26665 nullptr /* ssl_config_service */, enable_backup_connect_jobs);
[email protected]c9d6a1d2009-07-14 16:15:20666 }
[email protected]f6d1d6eb2009-06-24 20:16:09667
mmenked3641e12016-01-28 16:06:15668 int StartRequestWithIgnoreLimits(
Matt Menkec6b3edf72019-03-19 17:00:39669 const ClientSocketPool::GroupId& group_id,
[email protected]b021ece62013-06-11 11:06:33670 RequestPriority priority,
mmenked3641e12016-01-28 16:06:15671 ClientSocketPool::RespectLimits respect_limits) {
Matt Menkec6b3edf72019-03-19 17:00:39672 return test_base_.StartRequestUsingPool(pool_.get(), group_id, priority,
mmenked3641e12016-01-28 16:06:15673 respect_limits, params_);
[email protected]b021ece62013-06-11 11:06:33674 }
675
Matt Menkec6b3edf72019-03-19 17:00:39676 int StartRequest(const ClientSocketPool::GroupId& group_id,
677 RequestPriority priority) {
mmenked3641e12016-01-28 16:06:15678 return StartRequestWithIgnoreLimits(
Matt Menkec6b3edf72019-03-19 17:00:39679 group_id, priority, ClientSocketPool::RespectLimits::ENABLED);
[email protected]f6d1d6eb2009-06-24 20:16:09680 }
681
[email protected]2431756e2010-09-29 20:26:13682 int GetOrderOfRequest(size_t index) const {
683 return test_base_.GetOrderOfRequest(index);
[email protected]f6d1d6eb2009-06-24 20:16:09684 }
685
[email protected]2431756e2010-09-29 20:26:13686 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
687 return test_base_.ReleaseOneConnection(keep_alive);
688 }
689
690 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
691 test_base_.ReleaseAllConnections(keep_alive);
692 }
693
694 TestSocketRequest* request(int i) { return test_base_.request(i); }
695 size_t requests_size() const { return test_base_.requests_size(); }
danakj655b66c2016-04-16 00:51:38696 std::vector<std::unique_ptr<TestSocketRequest>>* requests() {
olli.raula9d66b7d2015-11-23 08:30:42697 return test_base_.requests();
698 }
rdsmith29dbad12017-02-17 02:22:18699 // Only counts the requests that get sockets asynchronously;
700 // synchronous completions are not registered by this count.
[email protected]2431756e2010-09-29 20:26:13701 size_t completion_count() const { return test_base_.completion_count(); }
702
vishal.b62985ca92015-04-17 08:45:51703 TestNetLog net_log_;
[email protected]636b8252011-04-08 19:56:54704 bool connect_backup_jobs_enabled_;
[email protected]f6d1d6eb2009-06-24 20:16:09705 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04706 TestConnectJobFactory* connect_job_factory_;
Matt Menke9fa17d52019-03-25 19:12:26707 // These parameters are never actually used to create a TransportConnectJob.
Matt Menke84d11e562019-03-27 00:11:19708 scoped_refptr<ClientSocketPool::SocketParams> params_;
Matt Menke9fa17d52019-03-25 19:12:26709 std::unique_ptr<TransportClientSocketPool> pool_;
[email protected]2431756e2010-09-29 20:26:13710 ClientSocketPoolTest test_base_;
[email protected]f6d1d6eb2009-06-24 20:16:09711};
712
Shivani Sharma8ae506c2019-07-21 21:08:27713// TODO(950069): Add testing for frame_origin in NetworkIsolationKey
714// using kAppendInitiatingFrameOriginToNetworkIsolationKey.
715
[email protected]5fc08e32009-07-15 17:09:57716TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53717 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20718
[email protected]6ecf2b92011-12-15 01:14:52719 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06720 ClientSocketHandle handle;
vishal.b62985ca92015-04-17 08:45:51721 BoundTestNetLog log;
[email protected]034df0f32013-01-07 23:17:48722 TestLoadTimingInfoNotConnected(handle);
[email protected]9e743cd2010-03-16 07:03:53723
Matt Menkef09e64c2019-04-23 22:16:28724 EXPECT_EQ(OK, handle.Init(
725 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
726 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
727 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
728 pool_.get(), log.bound()));
[email protected]f6d1d6eb2009-06-24 20:16:09729 EXPECT_TRUE(handle.is_initialized());
730 EXPECT_TRUE(handle.socket());
[email protected]034df0f32013-01-07 23:17:48731 TestLoadTimingInfoConnectedNotReused(handle);
732
[email protected]f6d1d6eb2009-06-24 20:16:09733 handle.Reset();
[email protected]034df0f32013-01-07 23:17:48734 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:30735
Eric Roman79cc7552019-07-19 02:17:54736 auto entries = log.GetEntries();
[email protected]b2fcd0e2010-12-01 15:19:40737
Matt Menke9fa17d52019-03-25 19:12:26738 EXPECT_EQ(5u, entries.size());
[email protected]9e743cd2010-03-16 07:03:53739 EXPECT_TRUE(LogContainsEvent(
Matt Menke9fa17d52019-03-25 19:12:26740 entries, 0, NetLogEventType::TCP_CLIENT_SOCKET_POOL_REQUESTED_SOCKET,
mikecirone8b85c432016-09-08 19:11:00741 NetLogEventPhase::NONE));
Matt Menke9fa17d52019-03-25 19:12:26742 EXPECT_TRUE(LogContainsBeginEvent(entries, 1, NetLogEventType::SOCKET_POOL));
743 EXPECT_TRUE(LogContainsEvent(
744 entries, 2, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
745 NetLogEventPhase::NONE));
746 EXPECT_TRUE(LogContainsEvent(entries, 3,
mikecirone8b85c432016-09-08 19:11:00747 NetLogEventType::SOCKET_POOL_BOUND_TO_SOCKET,
748 NetLogEventPhase::NONE));
Matt Menke9fa17d52019-03-25 19:12:26749 EXPECT_TRUE(LogContainsEndEvent(entries, 4, NetLogEventType::SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09750}
751
[email protected]ab838892009-06-30 18:49:05752TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53753 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20754
[email protected]ab838892009-06-30 18:49:05755 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
vishal.b62985ca92015-04-17 08:45:51756 BoundTestNetLog log;
[email protected]9e743cd2010-03-16 07:03:53757
[email protected]2431756e2010-09-29 20:26:13758 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:52759 TestCompletionCallback callback;
[email protected]e60e47a2010-07-14 03:37:18760 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:13761 handle.set_is_ssl_error(true);
Matt Menke39b7c5a2019-04-10 19:47:51762 handle.set_ssl_cert_request_info(base::MakeRefCounted<SSLCertRequestInfo>());
Matt Menke28ac03e2019-02-25 22:25:50763 EXPECT_EQ(
764 ERR_CONNECTION_FAILED,
Matt Menkef09e64c2019-04-23 22:16:28765 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
766 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
767 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
768 pool_.get(), log.bound()));
[email protected]2431756e2010-09-29 20:26:13769 EXPECT_FALSE(handle.socket());
770 EXPECT_FALSE(handle.is_ssl_error());
Matt Menke39b7c5a2019-04-10 19:47:51771 EXPECT_FALSE(handle.ssl_cert_request_info());
[email protected]034df0f32013-01-07 23:17:48772 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:30773
Eric Roman79cc7552019-07-19 02:17:54774 auto entries = log.GetEntries();
[email protected]b2fcd0e2010-12-01 15:19:40775
Matt Menke9fa17d52019-03-25 19:12:26776 EXPECT_EQ(4u, entries.size());
[email protected]06650c52010-06-03 00:49:17777 EXPECT_TRUE(LogContainsEvent(
Matt Menke9fa17d52019-03-25 19:12:26778 entries, 0, NetLogEventType::TCP_CLIENT_SOCKET_POOL_REQUESTED_SOCKET,
mikecirone8b85c432016-09-08 19:11:00779 NetLogEventPhase::NONE));
Matt Menke9fa17d52019-03-25 19:12:26780 EXPECT_TRUE(LogContainsBeginEvent(entries, 1, NetLogEventType::SOCKET_POOL));
781 EXPECT_TRUE(LogContainsEvent(
782 entries, 2, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
783 NetLogEventPhase::NONE));
784 EXPECT_TRUE(LogContainsEndEvent(entries, 3, NetLogEventType::SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09785}
786
Matt Menkef6edce752019-03-19 17:21:56787// Make sure different groups do not share sockets.
788TEST_F(ClientSocketPoolBaseTest, GroupSeparation) {
Matt Menke166443c2019-05-24 18:45:59789 base::test::ScopedFeatureList feature_list;
790 feature_list.InitAndEnableFeature(
791 features::kPartitionConnectionsByNetworkIsolationKey);
792
Matt Menkef6edce752019-03-19 17:21:56793 CreatePool(1000 /* max_sockets */, 2 /* max_sockets_per_group */);
794
795 const HostPortPair kHostPortPairs[] = {
796 {"a", 80},
797 {"a", 443},
798 {"b", 80},
799 };
800
801 const ClientSocketPool::SocketType kSocketTypes[] = {
802 ClientSocketPool::SocketType::kHttp,
803 ClientSocketPool::SocketType::kSsl,
Matt Menkef6edce752019-03-19 17:21:56804 };
805
Matt Menkebdf777802019-04-22 19:38:59806 const PrivacyMode kPrivacyModes[] = {PrivacyMode::PRIVACY_MODE_DISABLED,
807 PrivacyMode::PRIVACY_MODE_ENABLED};
Matt Menkef6edce752019-03-19 17:21:56808
Shivani Sharma8ae506c2019-07-21 21:08:27809 const auto kOriginA = url::Origin::Create(GURL("http://a.test/"));
810 const auto kOriginB = url::Origin::Create(GURL("http://b.test/"));
Matt Menke166443c2019-05-24 18:45:59811 const NetworkIsolationKey kNetworkIsolationKeys[] = {
Shivani Sharma8ae506c2019-07-21 21:08:27812 NetworkIsolationKey(kOriginA, kOriginA),
813 NetworkIsolationKey(kOriginB, kOriginB),
Matt Menke166443c2019-05-24 18:45:59814 };
815
Matt Menkef6edce752019-03-19 17:21:56816 int total_idle_sockets = 0;
817
818 // Walk through each GroupId, making sure that requesting a socket for one
819 // group does not return a previously connected socket for another group.
820 for (const auto& host_port_pair : kHostPortPairs) {
821 SCOPED_TRACE(host_port_pair.ToString());
822 for (const auto& socket_type : kSocketTypes) {
823 SCOPED_TRACE(static_cast<int>(socket_type));
824 for (const auto& privacy_mode : kPrivacyModes) {
825 SCOPED_TRACE(privacy_mode);
Matt Menke166443c2019-05-24 18:45:59826 for (const auto& network_isolation_key : kNetworkIsolationKeys) {
827 SCOPED_TRACE(network_isolation_key.ToString());
Matt Menkef6edce752019-03-19 17:21:56828
Matt Menke166443c2019-05-24 18:45:59829 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
Matt Menkef6edce752019-03-19 17:21:56830
Matt Menke166443c2019-05-24 18:45:59831 ClientSocketPool::GroupId group_id(
832 host_port_pair, socket_type, privacy_mode, network_isolation_key);
Matt Menkef6edce752019-03-19 17:21:56833
Matt Menke166443c2019-05-24 18:45:59834 EXPECT_FALSE(pool_->HasGroupForTesting(group_id));
Matt Menkef6edce752019-03-19 17:21:56835
Matt Menke166443c2019-05-24 18:45:59836 TestCompletionCallback callback;
837 ClientSocketHandle handle;
Matt Menkef6edce752019-03-19 17:21:56838
Matt Menke166443c2019-05-24 18:45:59839 // Since the group is empty, requesting a socket should not complete
840 // synchronously.
841 EXPECT_THAT(
842 handle.Init(group_id, params_, base::nullopt, DEFAULT_PRIORITY,
843 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
844 callback.callback(),
845 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
846 NetLogWithSource()),
847 IsError(ERR_IO_PENDING));
848 EXPECT_TRUE(pool_->HasGroupForTesting(group_id));
849 EXPECT_EQ(total_idle_sockets, pool_->IdleSocketCount());
Matt Menkef6edce752019-03-19 17:21:56850
Matt Menke166443c2019-05-24 18:45:59851 EXPECT_THAT(callback.WaitForResult(), IsOk());
852 EXPECT_TRUE(handle.socket());
853 EXPECT_TRUE(pool_->HasGroupForTesting(group_id));
854 EXPECT_EQ(total_idle_sockets, pool_->IdleSocketCount());
Matt Menkef6edce752019-03-19 17:21:56855
Matt Menke166443c2019-05-24 18:45:59856 // Return socket to pool.
857 handle.Reset();
858 EXPECT_EQ(total_idle_sockets + 1, pool_->IdleSocketCount());
Matt Menkef6edce752019-03-19 17:21:56859
Matt Menke166443c2019-05-24 18:45:59860 // Requesting a socket again should return the same socket as before,
861 // so should complete synchronously.
862 EXPECT_THAT(
863 handle.Init(group_id, params_, base::nullopt, DEFAULT_PRIORITY,
864 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
865 callback.callback(),
866 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
867 NetLogWithSource()),
868 IsOk());
869 EXPECT_TRUE(handle.socket());
870 EXPECT_EQ(total_idle_sockets, pool_->IdleSocketCount());
Matt Menkef6edce752019-03-19 17:21:56871
Matt Menke166443c2019-05-24 18:45:59872 // Return socket to pool again.
873 handle.Reset();
874 EXPECT_EQ(total_idle_sockets + 1, pool_->IdleSocketCount());
Matt Menkef6edce752019-03-19 17:21:56875
Matt Menke166443c2019-05-24 18:45:59876 ++total_idle_sockets;
877 }
Matt Menkef6edce752019-03-19 17:21:56878 }
879 }
880 }
881}
882
[email protected]211d21722009-07-22 15:48:53883TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
884 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
885
[email protected]9e743cd2010-03-16 07:03:53886 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30887
Matt Menkec6b3edf72019-03-19 17:00:39888 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
889 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
890 EXPECT_THAT(StartRequest(TestGroupId("c"), DEFAULT_PRIORITY), IsOk());
891 EXPECT_THAT(StartRequest(TestGroupId("d"), DEFAULT_PRIORITY), IsOk());
[email protected]211d21722009-07-22 15:48:53892
[email protected]2431756e2010-09-29 20:26:13893 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53894 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13895 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53896
Matt Menkec6b3edf72019-03-19 17:00:39897 EXPECT_THAT(StartRequest(TestGroupId("e"), DEFAULT_PRIORITY),
898 IsError(ERR_IO_PENDING));
899 EXPECT_THAT(StartRequest(TestGroupId("f"), DEFAULT_PRIORITY),
900 IsError(ERR_IO_PENDING));
901 EXPECT_THAT(StartRequest(TestGroupId("g"), DEFAULT_PRIORITY),
902 IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:53903
[email protected]2431756e2010-09-29 20:26:13904 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53905
[email protected]2431756e2010-09-29 20:26:13906 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53907 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13908 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53909
910 EXPECT_EQ(1, GetOrderOfRequest(1));
911 EXPECT_EQ(2, GetOrderOfRequest(2));
912 EXPECT_EQ(3, GetOrderOfRequest(3));
913 EXPECT_EQ(4, GetOrderOfRequest(4));
914 EXPECT_EQ(5, GetOrderOfRequest(5));
915 EXPECT_EQ(6, GetOrderOfRequest(6));
916 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17917
918 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13919 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53920}
921
922TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
923 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
924
[email protected]9e743cd2010-03-16 07:03:53925 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30926
[email protected]211d21722009-07-22 15:48:53927 // Reach all limits: max total sockets, and max sockets per group.
Matt Menkec6b3edf72019-03-19 17:00:39928 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
929 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
930 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
931 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
[email protected]211d21722009-07-22 15:48:53932
[email protected]2431756e2010-09-29 20:26:13933 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53934 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13935 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53936
937 // Now create a new group and verify that we don't starve it.
Matt Menkec6b3edf72019-03-19 17:00:39938 EXPECT_THAT(StartRequest(TestGroupId("c"), DEFAULT_PRIORITY),
939 IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:53940
[email protected]2431756e2010-09-29 20:26:13941 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53942
[email protected]2431756e2010-09-29 20:26:13943 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53944 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13945 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53946
947 EXPECT_EQ(1, GetOrderOfRequest(1));
948 EXPECT_EQ(2, GetOrderOfRequest(2));
949 EXPECT_EQ(3, GetOrderOfRequest(3));
950 EXPECT_EQ(4, GetOrderOfRequest(4));
951 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17952
953 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13954 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53955}
956
957TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
958 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
959
Matt Menkec6b3edf72019-03-19 17:00:39960 EXPECT_THAT(StartRequest(TestGroupId("b"), LOWEST), IsOk());
961 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsOk());
962 EXPECT_THAT(StartRequest(TestGroupId("b"), HIGHEST), IsOk());
963 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsOk());
[email protected]211d21722009-07-22 15:48:53964
[email protected]2431756e2010-09-29 20:26:13965 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53966 client_socket_factory_.allocation_count());
967
Matt Menkec6b3edf72019-03-19 17:00:39968 EXPECT_THAT(StartRequest(TestGroupId("c"), LOWEST), IsError(ERR_IO_PENDING));
969 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
970 EXPECT_THAT(StartRequest(TestGroupId("b"), HIGHEST), IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:53971
[email protected]2431756e2010-09-29 20:26:13972 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53973
[email protected]2431756e2010-09-29 20:26:13974 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53975
976 // First 4 requests don't have to wait, and finish in order.
977 EXPECT_EQ(1, GetOrderOfRequest(1));
978 EXPECT_EQ(2, GetOrderOfRequest(2));
979 EXPECT_EQ(3, GetOrderOfRequest(3));
980 EXPECT_EQ(4, GetOrderOfRequest(4));
981
Matt Menkec6b3edf72019-03-19 17:00:39982 // Request ("b", HIGHEST) has the highest priority, then (TestGroupId("a"),
983 // MEDIUM), and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:53984 EXPECT_EQ(7, GetOrderOfRequest(5));
985 EXPECT_EQ(6, GetOrderOfRequest(6));
986 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17987
988 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13989 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]211d21722009-07-22 15:48:53990}
991
rdsmith29dbad12017-02-17 02:22:18992// Test reprioritizing a request before completion doesn't interfere with
993// its completion.
994TEST_F(ClientSocketPoolBaseTest, ReprioritizeOne) {
995 CreatePool(kDefaultMaxSockets, 1);
996
Matt Menkec6b3edf72019-03-19 17:00:39997 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(OK));
998 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
rdsmith29dbad12017-02-17 02:22:18999 EXPECT_TRUE(request(0)->handle()->socket());
1000 EXPECT_FALSE(request(1)->handle()->socket());
1001
Lily Chenecebf932018-11-02 17:15:431002 request(1)->handle()->SetPriority(HIGHEST);
rdsmith29dbad12017-02-17 02:22:181003
1004 ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE);
1005
1006 EXPECT_TRUE(request(1)->handle()->socket());
1007}
1008
1009// Reprioritize a request up past another one and make sure that changes the
1010// completion order.
1011TEST_F(ClientSocketPoolBaseTest, ReprioritizeUpReorder) {
1012 CreatePool(kDefaultMaxSockets, 1);
1013
Matt Menkec6b3edf72019-03-19 17:00:391014 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(OK));
1015 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1016 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
rdsmith29dbad12017-02-17 02:22:181017 EXPECT_TRUE(request(0)->handle()->socket());
1018 EXPECT_FALSE(request(1)->handle()->socket());
1019 EXPECT_FALSE(request(2)->handle()->socket());
1020
1021 request(2)->handle()->SetPriority(HIGHEST);
1022
1023 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1024
1025 EXPECT_EQ(1, GetOrderOfRequest(1));
1026 EXPECT_EQ(3, GetOrderOfRequest(2));
1027 EXPECT_EQ(2, GetOrderOfRequest(3));
1028}
1029
1030// Reprioritize a request without changing relative priorities and check
1031// that the order doesn't change.
1032TEST_F(ClientSocketPoolBaseTest, ReprioritizeUpNoReorder) {
1033 CreatePool(kDefaultMaxSockets, 1);
1034
Matt Menkec6b3edf72019-03-19 17:00:391035 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(OK));
1036 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1037 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsError(ERR_IO_PENDING));
rdsmith29dbad12017-02-17 02:22:181038 EXPECT_TRUE(request(0)->handle()->socket());
1039 EXPECT_FALSE(request(1)->handle()->socket());
1040 EXPECT_FALSE(request(2)->handle()->socket());
1041
1042 request(2)->handle()->SetPriority(MEDIUM);
1043
1044 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1045
1046 EXPECT_EQ(1, GetOrderOfRequest(1));
1047 EXPECT_EQ(2, GetOrderOfRequest(2));
1048 EXPECT_EQ(3, GetOrderOfRequest(3));
1049}
1050
1051// Reprioritize a request past down another one and make sure that changes the
1052// completion order.
1053TEST_F(ClientSocketPoolBaseTest, ReprioritizeDownReorder) {
1054 CreatePool(kDefaultMaxSockets, 1);
1055
Matt Menkec6b3edf72019-03-19 17:00:391056 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(OK));
1057 EXPECT_THAT(StartRequest(TestGroupId("a"), HIGHEST), IsError(ERR_IO_PENDING));
1058 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
rdsmith29dbad12017-02-17 02:22:181059 EXPECT_TRUE(request(0)->handle()->socket());
1060 EXPECT_FALSE(request(1)->handle()->socket());
1061 EXPECT_FALSE(request(2)->handle()->socket());
1062
1063 request(1)->handle()->SetPriority(LOW);
1064
1065 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1066
1067 EXPECT_EQ(1, GetOrderOfRequest(1));
1068 EXPECT_EQ(3, GetOrderOfRequest(2));
1069 EXPECT_EQ(2, GetOrderOfRequest(3));
1070}
1071
1072// Reprioritize a request to the same level as another and confirm it is
1073// put after the old request.
1074TEST_F(ClientSocketPoolBaseTest, ReprioritizeResetFIFO) {
1075 CreatePool(kDefaultMaxSockets, 1);
1076
Matt Menkec6b3edf72019-03-19 17:00:391077 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(OK));
1078 EXPECT_THAT(StartRequest(TestGroupId("a"), HIGHEST), IsError(ERR_IO_PENDING));
1079 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
rdsmith29dbad12017-02-17 02:22:181080 EXPECT_TRUE(request(0)->handle()->socket());
1081 EXPECT_FALSE(request(1)->handle()->socket());
1082 EXPECT_FALSE(request(2)->handle()->socket());
1083
1084 request(1)->handle()->SetPriority(MEDIUM);
1085
1086 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1087
1088 EXPECT_EQ(1, GetOrderOfRequest(1));
1089 EXPECT_EQ(3, GetOrderOfRequest(2));
1090 EXPECT_EQ(2, GetOrderOfRequest(3));
1091}
1092
[email protected]211d21722009-07-22 15:48:531093TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
1094 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1095
Matt Menkec6b3edf72019-03-19 17:00:391096 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsOk());
1097 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsOk());
1098 EXPECT_THAT(StartRequest(TestGroupId("b"), HIGHEST), IsOk());
1099 EXPECT_THAT(StartRequest(TestGroupId("b"), MEDIUM), IsOk());
[email protected]211d21722009-07-22 15:48:531100
[email protected]2431756e2010-09-29 20:26:131101 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531102 client_socket_factory_.allocation_count());
1103
Matt Menkec6b3edf72019-03-19 17:00:391104 EXPECT_THAT(StartRequest(TestGroupId("c"), MEDIUM), IsError(ERR_IO_PENDING));
1105 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsError(ERR_IO_PENDING));
1106 EXPECT_THAT(StartRequest(TestGroupId("b"), HIGHEST), IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:531107
[email protected]2431756e2010-09-29 20:26:131108 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:531109
[email protected]2431756e2010-09-29 20:26:131110 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531111 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131112 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:531113
1114 // First 4 requests don't have to wait, and finish in order.
1115 EXPECT_EQ(1, GetOrderOfRequest(1));
1116 EXPECT_EQ(2, GetOrderOfRequest(2));
1117 EXPECT_EQ(3, GetOrderOfRequest(3));
1118 EXPECT_EQ(4, GetOrderOfRequest(4));
1119
1120 // Request ("b", 7) has the highest priority, but we can't make new socket for
1121 // group "b", because it has reached the per-group limit. Then we make
1122 // socket for ("c", 6), because it has higher priority than ("a", 4),
1123 // and we still can't make a socket for group "b".
1124 EXPECT_EQ(5, GetOrderOfRequest(5));
1125 EXPECT_EQ(6, GetOrderOfRequest(6));
1126 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171127
1128 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131129 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:531130}
1131
1132// Make sure that we count connecting sockets against the total limit.
1133TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
1134 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1135
Matt Menkec6b3edf72019-03-19 17:00:391136 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1137 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
1138 EXPECT_THAT(StartRequest(TestGroupId("c"), DEFAULT_PRIORITY), IsOk());
[email protected]211d21722009-07-22 15:48:531139
1140 // Create one asynchronous request.
1141 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
Matt Menkec6b3edf72019-03-19 17:00:391142 EXPECT_THAT(StartRequest(TestGroupId("d"), DEFAULT_PRIORITY),
1143 IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:531144
[email protected]6b175382009-10-13 06:47:471145 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1146 // actually become pending until 2ms after they have been created. In order
1147 // to flush all tasks, we need to wait so that we know there are no
1148 // soon-to-be-pending tasks waiting.
Alex Clarke0def2092018-12-10 12:01:451149 FastForwardBy(base::TimeDelta::FromMilliseconds(10));
[email protected]6b175382009-10-13 06:47:471150
[email protected]211d21722009-07-22 15:48:531151 // The next synchronous request should wait for its turn.
1152 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
Matt Menkec6b3edf72019-03-19 17:00:391153 EXPECT_THAT(StartRequest(TestGroupId("e"), DEFAULT_PRIORITY),
1154 IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:531155
[email protected]2431756e2010-09-29 20:26:131156 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:531157
[email protected]2431756e2010-09-29 20:26:131158 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531159 client_socket_factory_.allocation_count());
1160
1161 EXPECT_EQ(1, GetOrderOfRequest(1));
1162 EXPECT_EQ(2, GetOrderOfRequest(2));
1163 EXPECT_EQ(3, GetOrderOfRequest(3));
1164 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:171165 EXPECT_EQ(5, GetOrderOfRequest(5));
1166
1167 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131168 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:531169}
1170
[email protected]6427fe22010-04-16 22:27:411171TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
1172 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1173 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1174
Matt Menkec6b3edf72019-03-19 17:00:391175 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1176 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1177 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1178 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
[email protected]6427fe22010-04-16 22:27:411179
1180 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1181
1182 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1183
Matt Menkec6b3edf72019-03-19 17:00:391184 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY),
1185 IsError(ERR_IO_PENDING));
1186 EXPECT_THAT(StartRequest(TestGroupId("c"), DEFAULT_PRIORITY),
1187 IsError(ERR_IO_PENDING));
[email protected]6427fe22010-04-16 22:27:411188
1189 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1190
[email protected]2431756e2010-09-29 20:26:131191 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411192 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131193 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411194 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131195 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1196 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411197 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
1198}
1199
[email protected]d7027bb2010-05-10 18:58:541200TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
1201 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1202 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1203
1204 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521205 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:501206 EXPECT_EQ(
1207 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:281208 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
1209 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1210 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1211 pool_.get(), NetLogWithSource()));
[email protected]d7027bb2010-05-10 18:58:541212
1213 ClientSocketHandle handles[4];
Avi Drissman4365a4782018-12-28 19:26:241214 for (size_t i = 0; i < base::size(handles); ++i) {
[email protected]6ecf2b92011-12-15 01:14:521215 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:501216 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:391217 handles[i].Init(
Matt Menkef09e64c2019-04-23 22:16:281218 TestGroupId("b"), params_, base::nullopt, DEFAULT_PRIORITY,
1219 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1220 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1221 pool_.get(), NetLogWithSource()));
[email protected]d7027bb2010-05-10 18:58:541222 }
1223
1224 // One will be stalled, cancel all the handles now.
1225 // This should hit the OnAvailableSocketSlot() code where we previously had
1226 // stalled groups, but no longer have any.
Avi Drissman4365a4782018-12-28 19:26:241227 for (size_t i = 0; i < base::size(handles); ++i)
[email protected]d7027bb2010-05-10 18:58:541228 handles[i].Reset();
1229}
1230
[email protected]eb5a99382010-07-11 03:18:261231TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
[email protected]43a21b82010-06-10 21:30:541232 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1233 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1234
[email protected]eb5a99382010-07-11 03:18:261235 {
1236 ClientSocketHandle handles[kDefaultMaxSockets];
[email protected]6ecf2b92011-12-15 01:14:521237 TestCompletionCallback callbacks[kDefaultMaxSockets];
[email protected]eb5a99382010-07-11 03:18:261238 for (int i = 0; i < kDefaultMaxSockets; ++i) {
Matt Menkef09e64c2019-04-23 22:16:281239 EXPECT_EQ(OK,
1240 handles[i].Init(TestGroupId(base::NumberToString(i)), params_,
1241 base::nullopt, DEFAULT_PRIORITY, SocketTag(),
1242 ClientSocketPool::RespectLimits::ENABLED,
1243 callbacks[i].callback(),
1244 ClientSocketPool::ProxyAuthCallback(),
1245 pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261246 }
1247
1248 // Force a stalled group.
1249 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521250 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:201251 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:391252 stalled_handle.Init(
Matt Menkef09e64c2019-04-23 22:16:281253 TestGroupId("foo"), params_, base::nullopt, DEFAULT_PRIORITY,
1254 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1255 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1256 pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261257
1258 // Cancel the stalled request.
1259 stalled_handle.Reset();
1260
1261 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1262 EXPECT_EQ(0, pool_->IdleSocketCount());
1263
1264 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541265 }
1266
[email protected]43a21b82010-06-10 21:30:541267 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1268 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
[email protected]eb5a99382010-07-11 03:18:261269}
[email protected]43a21b82010-06-10 21:30:541270
[email protected]eb5a99382010-07-11 03:18:261271TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
1272 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1273 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1274
1275 {
1276 ClientSocketHandle handles[kDefaultMaxSockets];
1277 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:521278 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:201279 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:391280 handles[i].Init(TestGroupId(base::NumberToString(i)), params_,
Matt Menkef09e64c2019-04-23 22:16:281281 base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menkec6b3edf72019-03-19 17:00:391282 ClientSocketPool::RespectLimits::ENABLED,
1283 callback.callback(),
1284 ClientSocketPool::ProxyAuthCallback(),
1285 pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261286 }
1287
1288 // Force a stalled group.
1289 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1290 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521291 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:201292 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:391293 stalled_handle.Init(
Matt Menkef09e64c2019-04-23 22:16:281294 TestGroupId("foo"), params_, base::nullopt, DEFAULT_PRIORITY,
1295 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1296 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1297 pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261298
1299 // Since it is stalled, it should have no connect jobs.
Matt Menke9fa17d52019-03-25 19:12:261300 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("foo")));
1301 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
1302 TestGroupId("foo")));
1303 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroupForTesting(
1304 TestGroupId("foo")));
[email protected]eb5a99382010-07-11 03:18:261305
1306 // Cancel the stalled request.
1307 handles[0].Reset();
1308
[email protected]eb5a99382010-07-11 03:18:261309 // Now we should have a connect job.
Matt Menke9fa17d52019-03-25 19:12:261310 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("foo")));
1311 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
1312 TestGroupId("foo")));
1313 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroupForTesting(
1314 TestGroupId("foo")));
[email protected]eb5a99382010-07-11 03:18:261315
1316 // The stalled socket should connect.
robpercival214763f2016-07-01 23:27:011317 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:261318
1319 EXPECT_EQ(kDefaultMaxSockets + 1,
1320 client_socket_factory_.allocation_count());
1321 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menke9fa17d52019-03-25 19:12:261322 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("foo")));
1323 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
1324 TestGroupId("foo")));
1325 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroupForTesting(
1326 TestGroupId("foo")));
[email protected]eb5a99382010-07-11 03:18:261327
1328 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541329 }
1330
[email protected]eb5a99382010-07-11 03:18:261331 EXPECT_EQ(1, pool_->IdleSocketCount());
1332}
[email protected]43a21b82010-06-10 21:30:541333
[email protected]eb5a99382010-07-11 03:18:261334TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
1335 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1336 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]43a21b82010-06-10 21:30:541337
[email protected]eb5a99382010-07-11 03:18:261338 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521339 TestCompletionCallback callback;
[email protected]eb5a99382010-07-11 03:18:261340 {
[email protected]51fdc7c2012-04-10 19:19:481341 EXPECT_FALSE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261342 ClientSocketHandle handles[kDefaultMaxSockets];
1343 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:521344 TestCompletionCallback callback;
Matt Menkec6b3edf72019-03-19 17:00:391345 EXPECT_EQ(
Matt Menkef09e64c2019-04-23 22:16:281346 OK, handles[i].Init(
1347 TestGroupId(base::StringPrintf("Take 2: %d", i)), params_,
1348 base::nullopt, DEFAULT_PRIORITY, SocketTag(),
1349 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1350 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
1351 NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261352 }
1353
1354 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1355 EXPECT_EQ(0, pool_->IdleSocketCount());
[email protected]51fdc7c2012-04-10 19:19:481356 EXPECT_FALSE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261357
1358 // Now we will hit the socket limit.
tfarina428341112016-09-22 13:38:201359 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:391360 stalled_handle.Init(
Matt Menkef09e64c2019-04-23 22:16:281361 TestGroupId("foo"), params_, base::nullopt, DEFAULT_PRIORITY,
1362 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1363 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1364 pool_.get(), NetLogWithSource()));
[email protected]51fdc7c2012-04-10 19:19:481365 EXPECT_TRUE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261366
1367 // Dropping out of scope will close all handles and return them to idle.
1368 }
[email protected]43a21b82010-06-10 21:30:541369
1370 // But if we wait for it, the released idle sockets will be closed in
1371 // preference of the waiting request.
robpercival214763f2016-07-01 23:27:011372 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:261373
1374 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1375 EXPECT_EQ(3, pool_->IdleSocketCount());
[email protected]43a21b82010-06-10 21:30:541376}
1377
1378// Regression test for http://crbug.com/40952.
1379TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
Matt Menke9fa17d52019-03-25 19:12:261380 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1381 true /* enable_backup_connect_jobs */);
[email protected]43a21b82010-06-10 21:30:541382 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1383
1384 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1385 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521386 TestCompletionCallback callback;
Matt Menkec6b3edf72019-03-19 17:00:391387 EXPECT_EQ(OK, handle.Init(TestGroupId(base::NumberToString(i)), params_,
Matt Menkef09e64c2019-04-23 22:16:281388 base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menkec6b3edf72019-03-19 17:00:391389 ClientSocketPool::RespectLimits::ENABLED,
1390 callback.callback(),
1391 ClientSocketPool::ProxyAuthCallback(),
1392 pool_.get(), NetLogWithSource()));
[email protected]43a21b82010-06-10 21:30:541393 }
1394
1395 // Flush all the DoReleaseSocket tasks.
fdoray5eeb7642016-06-22 16:11:281396 base::RunLoop().RunUntilIdle();
[email protected]43a21b82010-06-10 21:30:541397
1398 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
1399 // reuse a socket.
1400 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1401 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521402 TestCompletionCallback callback;
[email protected]43a21b82010-06-10 21:30:541403
1404 // "0" is special here, since it should be the first entry in the sorted map,
1405 // which is the one which we would close an idle socket for. We shouldn't
1406 // close an idle socket though, since we should reuse the idle socket.
Matt Menkec6b3edf72019-03-19 17:00:391407 EXPECT_EQ(OK, handle.Init(
Matt Menkef09e64c2019-04-23 22:16:281408 TestGroupId("0"), params_, base::nullopt, DEFAULT_PRIORITY,
1409 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menkec6b3edf72019-03-19 17:00:391410 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1411 pool_.get(), NetLogWithSource()));
[email protected]43a21b82010-06-10 21:30:541412
1413 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1414 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
1415}
1416
[email protected]ab838892009-06-30 18:49:051417TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:531418 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091419
Matt Menkec6b3edf72019-03-19 17:00:391420 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1421 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1422 EXPECT_THAT(StartRequest(TestGroupId("a"), IDLE), IsError(ERR_IO_PENDING));
1423 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
1424 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1425 EXPECT_THAT(StartRequest(TestGroupId("a"), HIGHEST), IsError(ERR_IO_PENDING));
1426 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsError(ERR_IO_PENDING));
1427 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091428
[email protected]2431756e2010-09-29 20:26:131429 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]c9d6a1d2009-07-14 16:15:201430 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1431 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131432 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1433 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091434
[email protected]c9d6a1d2009-07-14 16:15:201435 EXPECT_EQ(1, GetOrderOfRequest(1));
1436 EXPECT_EQ(2, GetOrderOfRequest(2));
[email protected]c9c6f5c2010-07-31 01:30:031437 EXPECT_EQ(8, GetOrderOfRequest(3));
1438 EXPECT_EQ(6, GetOrderOfRequest(4));
1439 EXPECT_EQ(4, GetOrderOfRequest(5));
1440 EXPECT_EQ(3, GetOrderOfRequest(6));
1441 EXPECT_EQ(5, GetOrderOfRequest(7));
1442 EXPECT_EQ(7, GetOrderOfRequest(8));
[email protected]75439d3b2009-07-23 22:11:171443
1444 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131445 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]f6d1d6eb2009-06-24 20:16:091446}
1447
[email protected]ab838892009-06-30 18:49:051448TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:531449 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091450
Matt Menkec6b3edf72019-03-19 17:00:391451 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1452 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1453 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
1454 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1455 EXPECT_THAT(StartRequest(TestGroupId("a"), HIGHEST), IsError(ERR_IO_PENDING));
1456 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsError(ERR_IO_PENDING));
1457 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091458
[email protected]2431756e2010-09-29 20:26:131459 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091460
[email protected]2431756e2010-09-29 20:26:131461 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i)
robpercival214763f2016-07-01 23:27:011462 EXPECT_THAT(request(i)->WaitForResult(), IsOk());
[email protected]c9d6a1d2009-07-14 16:15:201463
[email protected]2431756e2010-09-29 20:26:131464 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]c9d6a1d2009-07-14 16:15:201465 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131466 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1467 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091468}
1469
Matt Menke7eb405e2019-04-25 20:48:211470TEST_F(ClientSocketPoolBaseTest, ResetAndCloseSocket) {
1471 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1472
1473 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1474 ClientSocketHandle handle;
1475 TestCompletionCallback callback;
1476 EXPECT_EQ(
1477 ERR_IO_PENDING,
1478 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
1479 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1480 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1481 pool_.get(), NetLogWithSource()));
1482
1483 EXPECT_THAT(callback.WaitForResult(), IsOk());
1484 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1485 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1486 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
1487 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
1488
1489 handle.ResetAndCloseSocket();
1490 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
1491}
1492
Matt Menke99251ea42019-04-25 22:59:021493// This test will start up a socket request and then call Reset() on the handle.
1494// The pending ConnectJob should not be destroyed.
Matt Menke7eb405e2019-04-25 20:48:211495TEST_F(ClientSocketPoolBaseTest, CancelRequestKeepsConnectJob) {
[email protected]211d21722009-07-22 15:48:531496 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201497
[email protected]ab838892009-06-30 18:49:051498 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131499 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521500 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:501501 EXPECT_EQ(
1502 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:281503 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
1504 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1505 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1506 pool_.get(), NetLogWithSource()));
[email protected]2431756e2010-09-29 20:26:131507 handle.Reset();
Matt Menke7eb405e2019-04-25 20:48:211508 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1509 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1510}
1511
Matt Menke99251ea42019-04-25 22:59:021512// This test will start up a socket request and then call ResetAndCloseSocket()
1513// on the handle. The pending ConnectJob or connected socket should be
1514// destroyed.
Matt Menke7eb405e2019-04-25 20:48:211515TEST_F(ClientSocketPoolBaseTest, CancelRequestAndCloseSocket) {
1516 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1517
Matt Menke99251ea42019-04-25 22:59:021518 // When true, the socket connects before it's canceled.
1519 for (bool cancel_when_callback_pending : {false, true}) {
1520 if (cancel_when_callback_pending) {
1521 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1522 } else {
1523 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1524 }
1525 ClientSocketHandle handle;
1526 TestCompletionCallback callback;
1527 EXPECT_EQ(
1528 ERR_IO_PENDING,
1529 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
1530 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1531 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1532 pool_.get(), NetLogWithSource()));
1533 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1534 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1535
1536 if (cancel_when_callback_pending) {
1537 client_socket_factory_.SignalJobs();
1538 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1539 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
1540 }
1541
1542 handle.ResetAndCloseSocket();
1543 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
1544 }
Matt Menke7eb405e2019-04-25 20:48:211545}
1546
1547TEST_F(ClientSocketPoolBaseTest,
1548 CancelRequestAndCloseSocketWhenMoreRequestsThanConnectJobs) {
1549 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1550
Matt Menke99251ea42019-04-25 22:59:021551 // When true, the sockets connect before they're canceled.
1552 for (bool cancel_when_callback_pending : {false, true}) {
1553 if (cancel_when_callback_pending) {
1554 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1555 } else {
1556 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1557 }
Matt Menke7eb405e2019-04-25 20:48:211558
Matt Menke99251ea42019-04-25 22:59:021559 std::vector<std::unique_ptr<ClientSocketHandle>> handles;
1560 TestCompletionCallback callback;
1561 // Make |kDefaultMaxSockets + 1| socket requests.
1562 for (int i = 0; i < kDefaultMaxSocketsPerGroup + 1; ++i) {
1563 std::unique_ptr<ClientSocketHandle> handle =
1564 std::make_unique<ClientSocketHandle>();
1565 EXPECT_EQ(ERR_IO_PENDING,
1566 handle->Init(
1567 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
1568 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1569 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1570 pool_.get(), NetLogWithSource()));
1571 handles.push_back(std::move(handle));
Matt Menke7eb405e2019-04-25 20:48:211572 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
Matt Menke99251ea42019-04-25 22:59:021573 EXPECT_EQ(
1574 static_cast<size_t>(std::min(i + 1, kDefaultMaxSocketsPerGroup)),
1575 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1576 }
1577
1578 if (cancel_when_callback_pending) {
1579 client_socket_factory_.SignalJobs();
1580 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1581 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1582 pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
1583 }
1584
1585 // Calling ResetAndCloseSocket() on a handle should not cancel a ConnectJob
1586 // or close a socket, since there are more requests than ConnectJobs or
1587 // sockets.
1588 handles[kDefaultMaxSocketsPerGroup]->ResetAndCloseSocket();
1589 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1590 if (cancel_when_callback_pending) {
1591 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1592 pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
1593 } else {
1594 EXPECT_EQ(static_cast<size_t>(kDefaultMaxSocketsPerGroup),
Matt Menke7eb405e2019-04-25 20:48:211595 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1596 }
Matt Menke99251ea42019-04-25 22:59:021597
1598 // Calling ResetAndCloseSocket() on other handles should cancel a ConnectJob
1599 // or close a socket.
1600 for (int i = kDefaultMaxSocketsPerGroup - 1; i >= 0; --i) {
1601 handles[i]->ResetAndCloseSocket();
1602 if (i > 0) {
1603 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1604 if (cancel_when_callback_pending) {
1605 EXPECT_EQ(i,
1606 pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
1607 } else {
1608 EXPECT_EQ(static_cast<size_t>(i),
1609 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1610 }
1611 } else {
1612 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
1613 }
1614 }
Matt Menke7eb405e2019-04-25 20:48:211615 }
[email protected]f6d1d6eb2009-06-24 20:16:091616}
1617
[email protected]ab838892009-06-30 18:49:051618TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531619 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201620
[email protected]ab838892009-06-30 18:49:051621 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061622 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521623 TestCompletionCallback callback;
[email protected]f6d1d6eb2009-06-24 20:16:091624
Matt Menke28ac03e2019-02-25 22:25:501625 EXPECT_EQ(
1626 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:281627 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
1628 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1629 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1630 pool_.get(), NetLogWithSource()));
[email protected]f6d1d6eb2009-06-24 20:16:091631
1632 handle.Reset();
Matt Menke7eb405e2019-04-25 20:48:211633 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1634 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]f6d1d6eb2009-06-24 20:16:091635
Matt Menke7eb405e2019-04-25 20:48:211636 // This will create a second ConnectJob, since the other ConnectJob was
1637 // previously assigned to a request.
[email protected]6ecf2b92011-12-15 01:14:521638 TestCompletionCallback callback2;
Matt Menke28ac03e2019-02-25 22:25:501639 EXPECT_EQ(
1640 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:281641 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
1642 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501643 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
1644 pool_.get(), NetLogWithSource()));
[email protected]f6d1d6eb2009-06-24 20:16:091645
Matt Menke7eb405e2019-04-25 20:48:211646 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1647 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1648
robpercival214763f2016-07-01 23:27:011649 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]f6d1d6eb2009-06-24 20:16:091650 EXPECT_FALSE(callback.have_result());
Matt Menke7eb405e2019-04-25 20:48:211651 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1652 // One ConnectJob completed, and its socket is now assigned to |handle|.
1653 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
1654 // The other ConnectJob should have either completed, or still be connecting.
1655 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")) +
1656 pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]f6d1d6eb2009-06-24 20:16:091657
1658 handle.Reset();
Matt Menke7eb405e2019-04-25 20:48:211659 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1660 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")) +
1661 pool_->IdleSocketCountInGroup(TestGroupId("a")));
1662 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
[email protected]f6d1d6eb2009-06-24 20:16:091663}
1664
[email protected]ab838892009-06-30 18:49:051665TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531666 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091667
Matt Menkec6b3edf72019-03-19 17:00:391668 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1669 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1670 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
1671 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1672 EXPECT_THAT(StartRequest(TestGroupId("a"), HIGHEST), IsError(ERR_IO_PENDING));
1673 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsError(ERR_IO_PENDING));
1674 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091675
1676 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:201677 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]2431756e2010-09-29 20:26:131678 EXPECT_FALSE((*requests())[index_to_cancel]->handle()->is_initialized());
1679 (*requests())[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091680
[email protected]2431756e2010-09-29 20:26:131681 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091682
[email protected]c9d6a1d2009-07-14 16:15:201683 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1684 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131685 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup - 1,
1686 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091687
[email protected]c9d6a1d2009-07-14 16:15:201688 EXPECT_EQ(1, GetOrderOfRequest(1));
1689 EXPECT_EQ(2, GetOrderOfRequest(2));
1690 EXPECT_EQ(5, GetOrderOfRequest(3));
1691 EXPECT_EQ(3, GetOrderOfRequest(4));
[email protected]2431756e2010-09-29 20:26:131692 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
1693 GetOrderOfRequest(5)); // Canceled request.
[email protected]c9d6a1d2009-07-14 16:15:201694 EXPECT_EQ(4, GetOrderOfRequest(6));
1695 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171696
1697 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131698 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:091699}
1700
mmenke33d24423d2015-05-19 19:41:091701// Function to be used as a callback on socket request completion. It first
1702// disconnects the successfully connected socket from the first request, and
1703// then reuses the ClientSocketHandle to request another socket.
1704//
1705// |nested_callback| is called with the result of the second socket request.
1706void RequestSocketOnComplete(ClientSocketHandle* handle,
Matt Menke9fa17d52019-03-25 19:12:261707 TransportClientSocketPool* pool,
mmenke33d24423d2015-05-19 19:41:091708 TestConnectJobFactory* test_connect_job_factory,
1709 TestConnectJob::JobType next_job_type,
Bence Békya4a50932018-08-10 13:39:411710 TestCompletionCallback* nested_callback,
mmenke33d24423d2015-05-19 19:41:091711 int first_request_result) {
robpercival214763f2016-07-01 23:27:011712 EXPECT_THAT(first_request_result, IsOk());
mmenke33d24423d2015-05-19 19:41:091713
1714 test_connect_job_factory->set_job_type(next_job_type);
1715
1716 // Don't allow reuse of the socket. Disconnect it and then release it.
1717 if (handle->socket())
1718 handle->socket()->Disconnect();
1719 handle->Reset();
1720
mmenke33d24423d2015-05-19 19:41:091721 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:501722 int rv = handle->Init(
Matt Menke870e19ab2019-04-23 16:23:031723 TestGroupId("a"),
Matt Menkef09e64c2019-04-23 22:16:281724 ClientSocketPool::SocketParams::CreateForHttpForTesting(), base::nullopt,
1725 LOWEST, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke870e19ab2019-04-23 16:23:031726 nested_callback->callback(), ClientSocketPool::ProxyAuthCallback(), pool,
1727 NetLogWithSource());
mmenke33d24423d2015-05-19 19:41:091728 if (rv != ERR_IO_PENDING) {
1729 DCHECK_EQ(TestConnectJob::kMockJob, next_job_type);
Bence Békya4a50932018-08-10 13:39:411730 nested_callback->callback().Run(rv);
mmenke33d24423d2015-05-19 19:41:091731 } else {
1732 DCHECK_EQ(TestConnectJob::kMockPendingJob, next_job_type);
[email protected]6ecf2b92011-12-15 01:14:521733 }
mmenke33d24423d2015-05-19 19:41:091734}
[email protected]f6d1d6eb2009-06-24 20:16:091735
mmenke33d24423d2015-05-19 19:41:091736// Tests the case where a second socket is requested in a completion callback,
1737// and the second socket connects asynchronously. Reuses the same
1738// ClientSocketHandle for the second socket, after disconnecting the first.
[email protected]2ab05b52009-07-01 23:57:581739TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531740 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201741
[email protected]0b7648c2009-07-06 20:14:011742 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061743 ClientSocketHandle handle;
mmenke33d24423d2015-05-19 19:41:091744 TestCompletionCallback second_result_callback;
1745 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:281746 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Paul Jensen8d6f87ec2018-01-13 00:46:541747 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501748 base::BindOnce(&RequestSocketOnComplete, &handle, pool_.get(),
1749 connect_job_factory_, TestConnectJob::kMockPendingJob,
1750 &second_result_callback),
1751 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011752 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091753
robpercival214763f2016-07-01 23:27:011754 EXPECT_THAT(second_result_callback.WaitForResult(), IsOk());
[email protected]2ab05b52009-07-01 23:57:581755}
[email protected]f6d1d6eb2009-06-24 20:16:091756
mmenke33d24423d2015-05-19 19:41:091757// Tests the case where a second socket is requested in a completion callback,
1758// and the second socket connects synchronously. Reuses the same
1759// ClientSocketHandle for the second socket, after disconnecting the first.
[email protected]2ab05b52009-07-01 23:57:581760TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531761 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201762
[email protected]0b7648c2009-07-06 20:14:011763 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061764 ClientSocketHandle handle;
mmenke33d24423d2015-05-19 19:41:091765 TestCompletionCallback second_result_callback;
1766 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:281767 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Paul Jensen8d6f87ec2018-01-13 00:46:541768 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501769 base::BindOnce(&RequestSocketOnComplete, &handle, pool_.get(),
1770 connect_job_factory_, TestConnectJob::kMockPendingJob,
1771 &second_result_callback),
1772 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011773 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2ab05b52009-07-01 23:57:581774
robpercival214763f2016-07-01 23:27:011775 EXPECT_THAT(second_result_callback.WaitForResult(), IsOk());
[email protected]f6d1d6eb2009-06-24 20:16:091776}
1777
1778// Make sure that pending requests get serviced after active requests get
1779// cancelled.
[email protected]ab838892009-06-30 18:49:051780TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531781 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201782
[email protected]0b7648c2009-07-06 20:14:011783 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091784
Matt Menkec6b3edf72019-03-19 17:00:391785 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1786 IsError(ERR_IO_PENDING));
1787 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1788 IsError(ERR_IO_PENDING));
1789 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1790 IsError(ERR_IO_PENDING));
1791 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1792 IsError(ERR_IO_PENDING));
1793 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1794 IsError(ERR_IO_PENDING));
1795 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1796 IsError(ERR_IO_PENDING));
1797 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1798 IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091799
[email protected]c9d6a1d2009-07-14 16:15:201800 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1801 // Let's cancel them.
1802 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]2431756e2010-09-29 20:26:131803 ASSERT_FALSE(request(i)->handle()->is_initialized());
1804 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091805 }
1806
[email protected]f6d1d6eb2009-06-24 20:16:091807 // Let's wait for the rest to complete now.
[email protected]2431756e2010-09-29 20:26:131808 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i) {
robpercival214763f2016-07-01 23:27:011809 EXPECT_THAT(request(i)->WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:131810 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091811 }
1812
[email protected]2431756e2010-09-29 20:26:131813 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1814 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091815}
1816
1817// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051818TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531819 const size_t kMaxSockets = 5;
1820 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201821
[email protected]0b7648c2009-07-06 20:14:011822 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091823
[email protected]211d21722009-07-22 15:48:531824 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1825 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091826
1827 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531828 for (size_t i = 0; i < kNumberOfRequests; ++i)
Matt Menkec6b3edf72019-03-19 17:00:391829 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1830 IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091831
[email protected]211d21722009-07-22 15:48:531832 for (size_t i = 0; i < kNumberOfRequests; ++i)
robpercival214763f2016-07-01 23:27:011833 EXPECT_THAT(request(i)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]f6d1d6eb2009-06-24 20:16:091834}
1835
mmenke9d72fe42017-05-18 22:36:071836// Make sure that pending requests that complete synchronously get serviced
1837// after active requests fail. See https://crbug.com/723748
1838TEST_F(ClientSocketPoolBaseTest, HandleMultipleSyncFailuresAfterAsyncFailure) {
1839 const size_t kNumberOfRequests = 10;
1840 const size_t kMaxSockets = 1;
1841 CreatePool(kMaxSockets, kMaxSockets);
1842
1843 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1844
Matt Menkec6b3edf72019-03-19 17:00:391845 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1846 IsError(ERR_IO_PENDING));
mmenke9d72fe42017-05-18 22:36:071847
1848 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
1849
1850 // Queue up all the other requests
1851 for (size_t i = 1; i < kNumberOfRequests; ++i)
Matt Menkec6b3edf72019-03-19 17:00:391852 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1853 IsError(ERR_IO_PENDING));
mmenke9d72fe42017-05-18 22:36:071854
1855 // Make sure all requests fail, instead of hanging.
1856 for (size_t i = 0; i < kNumberOfRequests; ++i)
1857 EXPECT_THAT(request(i)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
1858}
1859
[email protected]5fc08e32009-07-15 17:09:571860TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531861 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571862
1863 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1864
[email protected]2431756e2010-09-29 20:26:131865 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521866 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:501867 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:281868 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:501869 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1870 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011871 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:571872
1873 // Cancel the active request.
[email protected]2431756e2010-09-29 20:26:131874 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571875
Matt Menkef09e64c2019-04-23 22:16:281876 rv = handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
1877 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501878 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1879 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011880 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1881 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]5fc08e32009-07-15 17:09:571882
[email protected]2431756e2010-09-29 20:26:131883 EXPECT_FALSE(handle.is_reused());
[email protected]034df0f32013-01-07 23:17:481884 TestLoadTimingInfoConnectedNotReused(handle);
[email protected]5fc08e32009-07-15 17:09:571885 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1886}
1887
xunjieli26619e72016-11-23 19:39:551888TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsForced) {
xunjieli26619e72016-11-23 19:39:551889 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1890 ClientSocketHandle handle;
1891 TestCompletionCallback callback;
1892 BoundTestNetLog log;
Matt Menke28ac03e2019-02-25 22:25:501893 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:281894 TestGroupId("a"), params_, base::nullopt, LOWEST, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:501895 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1896 ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound());
xunjieli26619e72016-11-23 19:39:551897 EXPECT_THAT(rv, IsOk());
1898 handle.Reset();
1899 EXPECT_EQ(1, pool_->IdleSocketCount());
1900 pool_->CloseIdleSockets();
xunjieli26619e72016-11-23 19:39:551901}
1902
xunjieli92feb332017-03-03 17:19:231903TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsInGroupForced) {
xunjieli92feb332017-03-03 17:19:231904 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1905 TestCompletionCallback callback;
1906 BoundTestNetLog log;
1907 ClientSocketHandle handle1;
Matt Menke28ac03e2019-02-25 22:25:501908 int rv = handle1.Init(
Matt Menkef09e64c2019-04-23 22:16:281909 TestGroupId("a"), params_, base::nullopt, LOWEST, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:501910 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1911 ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound());
xunjieli92feb332017-03-03 17:19:231912 EXPECT_THAT(rv, IsOk());
1913 ClientSocketHandle handle2;
Matt Menkef09e64c2019-04-23 22:16:281914 rv = handle2.Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
1915 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501916 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1917 pool_.get(), log.bound());
xunjieli92feb332017-03-03 17:19:231918 ClientSocketHandle handle3;
Matt Menkef09e64c2019-04-23 22:16:281919 rv = handle3.Init(TestGroupId("b"), params_, base::nullopt, LOWEST,
1920 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501921 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1922 pool_.get(), log.bound());
xunjieli92feb332017-03-03 17:19:231923 EXPECT_THAT(rv, IsOk());
1924 handle1.Reset();
1925 handle2.Reset();
1926 handle3.Reset();
1927 EXPECT_EQ(3, pool_->IdleSocketCount());
Matt Menkec6b3edf72019-03-19 17:00:391928 pool_->CloseIdleSocketsInGroup(TestGroupId("a"));
xunjieli92feb332017-03-03 17:19:231929 EXPECT_EQ(1, pool_->IdleSocketCount());
xunjieli92feb332017-03-03 17:19:231930}
1931
xunjieli26619e72016-11-23 19:39:551932TEST_F(ClientSocketPoolBaseTest, CleanUpUnusableIdleSockets) {
xunjieli26619e72016-11-23 19:39:551933 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1934 ClientSocketHandle handle;
1935 TestCompletionCallback callback;
1936 BoundTestNetLog log;
Matt Menke28ac03e2019-02-25 22:25:501937 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:281938 TestGroupId("a"), params_, base::nullopt, LOWEST, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:501939 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1940 ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound());
xunjieli26619e72016-11-23 19:39:551941 EXPECT_THAT(rv, IsOk());
1942 StreamSocket* socket = handle.socket();
1943 handle.Reset();
1944 EXPECT_EQ(1, pool_->IdleSocketCount());
1945
1946 // Disconnect socket now to make the socket unusable.
1947 socket->Disconnect();
1948 ClientSocketHandle handle2;
Matt Menkef09e64c2019-04-23 22:16:281949 rv = handle2.Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
1950 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501951 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1952 pool_.get(), log.bound());
xunjieli26619e72016-11-23 19:39:551953 EXPECT_THAT(rv, IsOk());
1954 EXPECT_FALSE(handle2.is_reused());
xunjieli26619e72016-11-23 19:39:551955}
1956
[email protected]2b7523d2009-07-29 20:29:231957// Regression test for http://crbug.com/17985.
1958TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1959 const int kMaxSockets = 3;
1960 const int kMaxSocketsPerGroup = 2;
1961 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1962
[email protected]ac790b42009-12-02 04:31:311963 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231964
Matt Menkec6b3edf72019-03-19 17:00:391965 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1966 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
[email protected]2b7523d2009-07-29 20:29:231967
1968 // This is going to be a pending request in an otherwise empty group.
Matt Menkec6b3edf72019-03-19 17:00:391969 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1970 IsError(ERR_IO_PENDING));
[email protected]2b7523d2009-07-29 20:29:231971
1972 // Reach the maximum socket limit.
Matt Menkec6b3edf72019-03-19 17:00:391973 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
[email protected]2b7523d2009-07-29 20:29:231974
1975 // Create a stalled group with high priorities.
Matt Menkec6b3edf72019-03-19 17:00:391976 EXPECT_THAT(StartRequest(TestGroupId("c"), kHighPriority),
1977 IsError(ERR_IO_PENDING));
1978 EXPECT_THAT(StartRequest(TestGroupId("c"), kHighPriority),
1979 IsError(ERR_IO_PENDING));
[email protected]2b7523d2009-07-29 20:29:231980
Matt Menkec6b3edf72019-03-19 17:00:391981 // Release the first two sockets from TestGroupId("a"). Because this is a
1982 // keepalive, the first release will unblock the pending request for
1983 // TestGroupId("a"). The second release will unblock a request for "c",
1984 // because it is the next high priority socket.
[email protected]2431756e2010-09-29 20:26:131985 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1986 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]2b7523d2009-07-29 20:29:231987
1988 // Closing idle sockets should not get us into trouble, but in the bug
1989 // we were hitting a CHECK here.
Matt Menkec6b3edf72019-03-19 17:00:391990 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]43a21b82010-06-10 21:30:541991 pool_->CloseIdleSockets();
[email protected]eb5a99382010-07-11 03:18:261992
[email protected]2da659e2013-05-23 20:51:341993 // Run the released socket wakeups.
fdoray5eeb7642016-06-22 16:11:281994 base::RunLoop().RunUntilIdle();
[email protected]2b7523d2009-07-29 20:29:231995}
1996
[email protected]4d3b05d2010-01-27 21:27:291997TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531998 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571999
2000 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:132001 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522002 TestCompletionCallback callback;
vishal.b62985ca92015-04-17 08:45:512003 BoundTestNetLog 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());
robpercival214763f2016-07-01 23:27:012008 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Matt Menkec6b3edf72019-03-19 17:00:392009 EXPECT_EQ(LOAD_STATE_CONNECTING,
2010 pool_->GetLoadState(TestGroupId("a"), &handle));
[email protected]034df0f32013-01-07 23:17:482011 TestLoadTimingInfoNotConnected(handle);
2012
robpercival214763f2016-07-01 23:27:012013 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132014 EXPECT_TRUE(handle.is_initialized());
2015 EXPECT_TRUE(handle.socket());
[email protected]034df0f32013-01-07 23:17:482016 TestLoadTimingInfoConnectedNotReused(handle);
2017
[email protected]2431756e2010-09-29 20:26:132018 handle.Reset();
[email protected]034df0f32013-01-07 23:17:482019 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:302020
Eric Roman79cc7552019-07-19 02:17:542021 auto entries = log.GetEntries();
[email protected]b2fcd0e2010-12-01 15:19:402022
Matt Menke9fa17d52019-03-25 19:12:262023 EXPECT_EQ(5u, entries.size());
[email protected]06650c52010-06-03 00:49:172024 EXPECT_TRUE(LogContainsEvent(
Matt Menke9fa17d52019-03-25 19:12:262025 entries, 0, NetLogEventType::TCP_CLIENT_SOCKET_POOL_REQUESTED_SOCKET,
mikecirone8b85c432016-09-08 19:11:002026 NetLogEventPhase::NONE));
Matt Menke9fa17d52019-03-25 19:12:262027 EXPECT_TRUE(LogContainsBeginEvent(entries, 1, NetLogEventType::SOCKET_POOL));
2028 EXPECT_TRUE(LogContainsEvent(
2029 entries, 2, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
2030 NetLogEventPhase::NONE));
2031 EXPECT_TRUE(LogContainsEvent(entries, 3,
mikecirone8b85c432016-09-08 19:11:002032 NetLogEventType::SOCKET_POOL_BOUND_TO_SOCKET,
2033 NetLogEventPhase::NONE));
Matt Menke9fa17d52019-03-25 19:12:262034 EXPECT_TRUE(LogContainsEndEvent(entries, 4, NetLogEventType::SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:572035}
2036
[email protected]4d3b05d2010-01-27 21:27:292037TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:572038 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:532039 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:572040
2041 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]2431756e2010-09-29 20:26:132042 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522043 TestCompletionCallback callback;
vishal.b62985ca92015-04-17 08:45:512044 BoundTestNetLog log;
[email protected]e60e47a2010-07-14 03:37:182045 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:132046 handle.set_is_ssl_error(true);
Matt Menke39b7c5a2019-04-10 19:47:512047 handle.set_ssl_cert_request_info(base::MakeRefCounted<SSLCertRequestInfo>());
Matt Menke28ac03e2019-02-25 22:25:502048 EXPECT_EQ(
2049 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:282050 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2051 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2052 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2053 pool_.get(), log.bound()));
Matt Menkec6b3edf72019-03-19 17:00:392054 EXPECT_EQ(LOAD_STATE_CONNECTING,
2055 pool_->GetLoadState(TestGroupId("a"), &handle));
robpercival214763f2016-07-01 23:27:012056 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]2431756e2010-09-29 20:26:132057 EXPECT_FALSE(handle.is_ssl_error());
Matt Menke39b7c5a2019-04-10 19:47:512058 EXPECT_FALSE(handle.ssl_cert_request_info());
[email protected]fd7b7c92009-08-20 19:38:302059
Eric Roman79cc7552019-07-19 02:17:542060 auto entries = log.GetEntries();
[email protected]b2fcd0e2010-12-01 15:19:402061
Matt Menke9fa17d52019-03-25 19:12:262062 EXPECT_EQ(4u, entries.size());
[email protected]06650c52010-06-03 00:49:172063 EXPECT_TRUE(LogContainsEvent(
Matt Menke9fa17d52019-03-25 19:12:262064 entries, 0, NetLogEventType::TCP_CLIENT_SOCKET_POOL_REQUESTED_SOCKET,
mikecirone8b85c432016-09-08 19:11:002065 NetLogEventPhase::NONE));
Matt Menke9fa17d52019-03-25 19:12:262066 EXPECT_TRUE(LogContainsBeginEvent(entries, 1, NetLogEventType::SOCKET_POOL));
2067 EXPECT_TRUE(LogContainsEvent(
2068 entries, 2, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
2069 NetLogEventPhase::NONE));
2070 EXPECT_TRUE(LogContainsEndEvent(entries, 3, NetLogEventType::SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:572071}
2072
mmenke6be122f2015-03-09 22:22:472073// Check that an async ConnectJob failure does not result in creation of a new
2074// ConnectJob when there's another pending request also waiting on its own
2075// ConnectJob. See http://crbug.com/463960.
2076TEST_F(ClientSocketPoolBaseTest, AsyncFailureWithPendingRequestWithJob) {
2077 CreatePool(2, 2);
2078 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2079
Matt Menkec6b3edf72019-03-19 17:00:392080 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2081 IsError(ERR_IO_PENDING));
2082 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2083 IsError(ERR_IO_PENDING));
mmenke6be122f2015-03-09 22:22:472084
robpercival214763f2016-07-01 23:27:012085 EXPECT_THAT(request(0)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
2086 EXPECT_THAT(request(1)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
mmenke6be122f2015-03-09 22:22:472087
2088 EXPECT_EQ(2, client_socket_factory_.allocation_count());
2089}
2090
[email protected]4d3b05d2010-01-27 21:27:292091TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]b22b5162010-03-16 07:53:102092 // TODO(eroman): Add back the log expectations! Removed them because the
2093 // ordering is difficult, and some may fire during destructor.
[email protected]211d21722009-07-22 15:48:532094 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:572095
2096 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:132097 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522098 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132099 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522100 TestCompletionCallback callback2;
[email protected]5fc08e32009-07-15 17:09:572101
Matt Menke28ac03e2019-02-25 22:25:502102 EXPECT_EQ(
2103 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:282104 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2105 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2106 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2107 pool_.get(), NetLogWithSource()));
vishal.b62985ca92015-04-17 08:45:512108 BoundTestNetLog log2;
tfarina428341112016-09-22 13:38:202109 EXPECT_EQ(
2110 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:282111 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2112 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502113 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2114 pool_.get(), NetLogWithSource()));
[email protected]5fc08e32009-07-15 17:09:572115
[email protected]2431756e2010-09-29 20:26:132116 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:572117
[email protected]fd7b7c92009-08-20 19:38:302118
2119 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]fd7b7c92009-08-20 19:38:302120
robpercival214763f2016-07-01 23:27:012121 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132122 handle2.Reset();
[email protected]fd7b7c92009-08-20 19:38:302123
2124 // Now request 2 has actually finished.
[email protected]9e743cd2010-03-16 07:03:532125 // TODO(eroman): Add back log expectations.
[email protected]5fc08e32009-07-15 17:09:572126}
2127
[email protected]4d3b05d2010-01-27 21:27:292128TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:342129 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2130
[email protected]17a0c6c2009-08-04 00:07:042131 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2132
Matt Menkec6b3edf72019-03-19 17:00:392133 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
2134 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsError(ERR_IO_PENDING));
2135 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
2136 EXPECT_THAT(StartRequest(TestGroupId("a"), HIGHEST), IsError(ERR_IO_PENDING));
[email protected]974ebd62009-08-03 23:14:342137
Raul Tambre8335a6d2019-02-21 16:57:432138 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
Matt Menke9fa17d52019-03-25 19:12:262139 static_cast<int>(
2140 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))));
[email protected]2431756e2010-09-29 20:26:132141 (*requests())[2]->handle()->Reset();
2142 (*requests())[3]->handle()->Reset();
Raul Tambre8335a6d2019-02-21 16:57:432143 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
Matt Menke9fa17d52019-03-25 19:12:262144 static_cast<int>(
2145 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))));
[email protected]974ebd62009-08-03 23:14:342146
[email protected]2431756e2010-09-29 20:26:132147 (*requests())[1]->handle()->Reset();
Raul Tambre8335a6d2019-02-21 16:57:432148 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
Matt Menke9fa17d52019-03-25 19:12:262149 static_cast<int>(
2150 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))));
[email protected]974ebd62009-08-03 23:14:342151
[email protected]2431756e2010-09-29 20:26:132152 (*requests())[0]->handle()->Reset();
Raul Tambre8335a6d2019-02-21 16:57:432153 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
Matt Menke9fa17d52019-03-25 19:12:262154 static_cast<int>(
2155 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))));
[email protected]974ebd62009-08-03 23:14:342156}
2157
[email protected]5fc08e32009-07-15 17:09:572158// When requests and ConnectJobs are not coupled, the request will get serviced
2159// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:292160TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:532161 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:572162
2163 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:322164 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:572165
[email protected]2431756e2010-09-29 20:26:132166 std::vector<TestSocketRequest*> request_order;
2167 size_t completion_count; // unused
2168 TestSocketRequest req1(&request_order, &completion_count);
Matt Menke28ac03e2019-02-25 22:25:502169 int rv = req1.handle()->Init(
Matt Menkef09e64c2019-04-23 22:16:282170 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502171 ClientSocketPool::RespectLimits::ENABLED, req1.callback(),
2172 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012173 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2174 EXPECT_THAT(req1.WaitForResult(), IsOk());
[email protected]5fc08e32009-07-15 17:09:572175
2176 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
2177 // without a job.
2178 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2179
[email protected]2431756e2010-09-29 20:26:132180 TestSocketRequest req2(&request_order, &completion_count);
Matt Menke28ac03e2019-02-25 22:25:502181 rv = req2.handle()->Init(
Matt Menkef09e64c2019-04-23 22:16:282182 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502183 ClientSocketPool::RespectLimits::ENABLED, req2.callback(),
2184 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012185 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2431756e2010-09-29 20:26:132186 TestSocketRequest req3(&request_order, &completion_count);
Matt Menke28ac03e2019-02-25 22:25:502187 rv = req3.handle()->Init(
Matt Menkef09e64c2019-04-23 22:16:282188 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502189 ClientSocketPool::RespectLimits::ENABLED, req3.callback(),
2190 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012191 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:572192
2193 // Both Requests 2 and 3 are pending. We release socket 1 which should
2194 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:332195 req1.handle()->Reset();
[email protected]2da659e2013-05-23 20:51:342196 // Run the released socket wakeups.
fdoray5eeb7642016-06-22 16:11:282197 base::RunLoop().RunUntilIdle();
[email protected]a6c59f62009-07-29 16:33:332198 ASSERT_TRUE(req2.handle()->socket());
robpercival214763f2016-07-01 23:27:012199 EXPECT_THAT(req2.WaitForResult(), IsOk());
[email protected]a6c59f62009-07-29 16:33:332200 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:572201
2202 // Signal job 2, which should service request 3.
2203
2204 client_socket_factory_.SignalJobs();
robpercival214763f2016-07-01 23:27:012205 EXPECT_THAT(req3.WaitForResult(), IsOk());
[email protected]5fc08e32009-07-15 17:09:572206
Raul Tambre8335a6d2019-02-21 16:57:432207 ASSERT_EQ(3u, request_order.size());
[email protected]2431756e2010-09-29 20:26:132208 EXPECT_EQ(&req1, request_order[0]);
2209 EXPECT_EQ(&req2, request_order[1]);
2210 EXPECT_EQ(&req3, request_order[2]);
Matt Menkec6b3edf72019-03-19 17:00:392211 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]5fc08e32009-07-15 17:09:572212}
2213
2214// The requests are not coupled to the jobs. So, the requests should finish in
2215// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:292216TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:532217 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:572218 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:322219 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:572220
[email protected]2431756e2010-09-29 20:26:132221 std::vector<TestSocketRequest*> request_order;
2222 size_t completion_count; // unused
2223 TestSocketRequest req1(&request_order, &completion_count);
Matt Menke28ac03e2019-02-25 22:25:502224 int rv = req1.handle()->Init(
Matt Menkef09e64c2019-04-23 22:16:282225 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502226 ClientSocketPool::RespectLimits::ENABLED, req1.callback(),
2227 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012228 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:572229
[email protected]2431756e2010-09-29 20:26:132230 TestSocketRequest req2(&request_order, &completion_count);
Matt Menke28ac03e2019-02-25 22:25:502231 rv = req2.handle()->Init(
Matt Menkef09e64c2019-04-23 22:16:282232 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502233 ClientSocketPool::RespectLimits::ENABLED, req2.callback(),
2234 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012235 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:572236
2237 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:322238 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:572239
[email protected]2431756e2010-09-29 20:26:132240 TestSocketRequest req3(&request_order, &completion_count);
Matt Menke28ac03e2019-02-25 22:25:502241 rv = req3.handle()->Init(
Matt Menkef09e64c2019-04-23 22:16:282242 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502243 ClientSocketPool::RespectLimits::ENABLED, req3.callback(),
2244 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012245 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:572246
robpercival214763f2016-07-01 23:27:012247 EXPECT_THAT(req1.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
2248 EXPECT_THAT(req2.WaitForResult(), IsOk());
2249 EXPECT_THAT(req3.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]5fc08e32009-07-15 17:09:572250
Raul Tambre8335a6d2019-02-21 16:57:432251 ASSERT_EQ(3u, request_order.size());
[email protected]2431756e2010-09-29 20:26:132252 EXPECT_EQ(&req1, request_order[0]);
2253 EXPECT_EQ(&req2, request_order[1]);
2254 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:572255}
2256
[email protected]03b7c8c2013-07-20 04:38:552257// Test GetLoadState in the case there's only one socket request.
2258TEST_F(ClientSocketPoolBaseTest, LoadStateOneRequest) {
[email protected]211d21722009-07-22 15:48:532259 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]03b7c8c2013-07-20 04:38:552260 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
[email protected]5fc08e32009-07-15 17:09:572261
[email protected]2431756e2010-09-29 20:26:132262 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522263 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502264 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:282265 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502266 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2267 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012268 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552269 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:572270
[email protected]03b7c8c2013-07-20 04:38:552271 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2272 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
2273
2274 // No point in completing the connection, since ClientSocketHandles only
2275 // expect the LoadState to be checked while connecting.
2276}
2277
2278// Test GetLoadState in the case there are two socket requests.
2279TEST_F(ClientSocketPoolBaseTest, LoadStateTwoRequests) {
2280 CreatePool(2, 2);
2281 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2282
2283 ClientSocketHandle handle;
2284 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502285 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:282286 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502287 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2288 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012289 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
haavardm835c1d62015-04-22 08:18:002290 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_RESOLVING_HOST);
2291
2292 ClientSocketHandle handle2;
2293 TestCompletionCallback callback2;
Matt Menkef09e64c2019-04-23 22:16:282294 rv = handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2295 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502296 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2297 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012298 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
haavardm835c1d62015-04-22 08:18:002299 client_socket_factory_.SetJobLoadState(1, LOAD_STATE_RESOLVING_HOST);
2300
Matt Menke4b69f932019-03-04 16:20:012301 // Each handle should reflect the state of its own job.
haavardm835c1d62015-04-22 08:18:002302 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle.GetLoadState());
2303 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle2.GetLoadState());
2304
Matt Menke4b69f932019-03-04 16:20:012305 // Update the state of the first job.
haavardm835c1d62015-04-22 08:18:002306 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_CONNECTING);
2307
Matt Menke4b69f932019-03-04 16:20:012308 // Only the state of the first request should have changed.
haavardm835c1d62015-04-22 08:18:002309 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
haavardm835c1d62015-04-22 08:18:002310 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle2.GetLoadState());
Matt Menke4b69f932019-03-04 16:20:012311
2312 // Update the state of the second job.
2313 client_socket_factory_.SetJobLoadState(1, LOAD_STATE_SSL_HANDSHAKE);
2314
2315 // Only the state of the second request should have changed.
2316 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2317 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle2.GetLoadState());
2318
2319 // Second job connects and the first request gets the socket. The
2320 // second handle switches to the state of the remaining ConnectJob.
2321 client_socket_factory_.SignalJob(1);
2322 EXPECT_THAT(callback.WaitForResult(), IsOk());
2323 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
[email protected]03b7c8c2013-07-20 04:38:552324}
2325
2326// Test GetLoadState in the case the per-group limit is reached.
2327TEST_F(ClientSocketPoolBaseTest, LoadStateGroupLimit) {
2328 CreatePool(2, 1);
2329 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2330
2331 ClientSocketHandle handle;
2332 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502333 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:282334 TestGroupId("a"), params_, base::nullopt, MEDIUM, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502335 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2336 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012337 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552338 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2339
2340 // Request another socket from the same pool, buth with a higher priority.
2341 // The first request should now be stalled at the socket group limit.
2342 ClientSocketHandle handle2;
2343 TestCompletionCallback callback2;
Matt Menkef09e64c2019-04-23 22:16:282344 rv = handle2.Init(TestGroupId("a"), params_, base::nullopt, HIGHEST,
2345 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502346 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2347 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012348 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552349 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2350 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
2351
2352 // The first handle should remain stalled as the other socket goes through
2353 // the connect process.
2354
2355 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2356 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2357 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle2.GetLoadState());
2358
2359 client_socket_factory_.SignalJob(0);
robpercival214763f2016-07-01 23:27:012360 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]03b7c8c2013-07-20 04:38:552361 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2362
2363 // Closing the second socket should cause the stalled handle to finally get a
2364 // ConnectJob.
2365 handle2.socket()->Disconnect();
2366 handle2.Reset();
2367 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2368}
2369
2370// Test GetLoadState in the case the per-pool limit is reached.
2371TEST_F(ClientSocketPoolBaseTest, LoadStatePoolLimit) {
2372 CreatePool(2, 2);
2373 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2374
2375 ClientSocketHandle handle;
2376 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502377 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:282378 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502379 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2380 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012381 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552382
2383 // Request for socket from another pool.
2384 ClientSocketHandle handle2;
2385 TestCompletionCallback callback2;
Matt Menkef09e64c2019-04-23 22:16:282386 rv = handle2.Init(TestGroupId("b"), params_, base::nullopt, DEFAULT_PRIORITY,
2387 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502388 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2389 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012390 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552391
2392 // Request another socket from the first pool. Request should stall at the
2393 // socket pool limit.
2394 ClientSocketHandle handle3;
2395 TestCompletionCallback callback3;
Matt Menkef09e64c2019-04-23 22:16:282396 rv = handle3.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2397 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502398 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2399 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012400 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552401
2402 // The third handle should remain stalled as the other sockets in its group
2403 // goes through the connect process.
2404
2405 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2406 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2407
2408 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2409 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
2410 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2411
2412 client_socket_factory_.SignalJob(0);
robpercival214763f2016-07-01 23:27:012413 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]03b7c8c2013-07-20 04:38:552414 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2415
2416 // Closing a socket should allow the stalled handle to finally get a new
2417 // ConnectJob.
2418 handle.socket()->Disconnect();
2419 handle.Reset();
2420 EXPECT_EQ(LOAD_STATE_CONNECTING, handle3.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:572421}
2422
Matt Menkeb57663b32019-03-01 17:17:102423TEST_F(ClientSocketPoolBaseTest, CertError) {
[email protected]e772db3f2010-07-12 18:11:132424 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
Matt Menkeb57663b32019-03-01 17:17:102425 connect_job_factory_->set_job_type(TestConnectJob::kMockCertErrorJob);
[email protected]e772db3f2010-07-12 18:11:132426
[email protected]2431756e2010-09-29 20:26:132427 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522428 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502429 EXPECT_EQ(
Matt Menkeb57663b32019-03-01 17:17:102430 ERR_CERT_COMMON_NAME_INVALID,
Matt Menkef09e64c2019-04-23 22:16:282431 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2432 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2433 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2434 pool_.get(), NetLogWithSource()));
[email protected]2431756e2010-09-29 20:26:132435 EXPECT_TRUE(handle.is_initialized());
2436 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:132437}
2438
Matt Menkeb57663b32019-03-01 17:17:102439TEST_F(ClientSocketPoolBaseTest, AsyncCertError) {
[email protected]e772db3f2010-07-12 18:11:132440 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2441
Matt Menkeb57663b32019-03-01 17:17:102442 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingCertErrorJob);
[email protected]2431756e2010-09-29 20:26:132443 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522444 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502445 EXPECT_EQ(
2446 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:282447 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2448 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2449 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2450 pool_.get(), NetLogWithSource()));
Matt Menkec6b3edf72019-03-19 17:00:392451 EXPECT_EQ(LOAD_STATE_CONNECTING,
2452 pool_->GetLoadState(TestGroupId("a"), &handle));
Matt Menkeb57663b32019-03-01 17:17:102453 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CERT_COMMON_NAME_INVALID));
[email protected]2431756e2010-09-29 20:26:132454 EXPECT_TRUE(handle.is_initialized());
2455 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:132456}
2457
[email protected]e60e47a2010-07-14 03:37:182458TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) {
2459 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2460 connect_job_factory_->set_job_type(
2461 TestConnectJob::kMockAdditionalErrorStateJob);
2462
[email protected]2431756e2010-09-29 20:26:132463 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522464 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502465 EXPECT_EQ(
2466 ERR_CONNECTION_FAILED,
Matt Menkef09e64c2019-04-23 22:16:282467 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2468 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2469 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2470 pool_.get(), NetLogWithSource()));
[email protected]2431756e2010-09-29 20:26:132471 EXPECT_FALSE(handle.is_initialized());
2472 EXPECT_FALSE(handle.socket());
2473 EXPECT_TRUE(handle.is_ssl_error());
Matt Menke39b7c5a2019-04-10 19:47:512474 EXPECT_TRUE(handle.ssl_cert_request_info());
[email protected]e60e47a2010-07-14 03:37:182475}
2476
2477TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) {
2478 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2479
2480 connect_job_factory_->set_job_type(
2481 TestConnectJob::kMockPendingAdditionalErrorStateJob);
[email protected]2431756e2010-09-29 20:26:132482 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522483 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502484 EXPECT_EQ(
2485 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:282486 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2487 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2488 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2489 pool_.get(), NetLogWithSource()));
Matt Menkec6b3edf72019-03-19 17:00:392490 EXPECT_EQ(LOAD_STATE_CONNECTING,
2491 pool_->GetLoadState(TestGroupId("a"), &handle));
robpercival214763f2016-07-01 23:27:012492 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]2431756e2010-09-29 20:26:132493 EXPECT_FALSE(handle.is_initialized());
2494 EXPECT_FALSE(handle.socket());
2495 EXPECT_TRUE(handle.is_ssl_error());
Matt Menke39b7c5a2019-04-10 19:47:512496 EXPECT_TRUE(handle.ssl_cert_request_info());
[email protected]e60e47a2010-07-14 03:37:182497}
2498
martijn003cd612016-05-19 22:24:382499// Make sure we can reuse sockets.
2500TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSocketsReuse) {
[email protected]64770b7d2011-11-16 04:30:412501 CreatePoolWithIdleTimeouts(
2502 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
[email protected]e7b1c6d2c2012-05-05 00:54:032503 base::TimeDelta(), // Time out unused sockets immediately.
2504 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2505
2506 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2507
2508 ClientSocketHandle handle;
2509 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502510 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:282511 TestGroupId("a"), params_, base::nullopt, LOWEST, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502512 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2513 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012514 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
Matt Menkec6b3edf72019-03-19 17:00:392515 EXPECT_EQ(LOAD_STATE_CONNECTING,
2516 pool_->GetLoadState(TestGroupId("a"), &handle));
robpercival214763f2016-07-01 23:27:012517 ASSERT_THAT(callback.WaitForResult(), IsOk());
[email protected]e7b1c6d2c2012-05-05 00:54:032518
2519 // Use and release the socket.
Raul Tambre94493c652019-03-11 17:18:352520 EXPECT_EQ(1, handle.socket()->Write(nullptr, 1, CompletionOnceCallback(),
Ramin Halavati0a08cc82018-02-06 07:46:382521 TRAFFIC_ANNOTATION_FOR_TESTS));
[email protected]034df0f32013-01-07 23:17:482522 TestLoadTimingInfoConnectedNotReused(handle);
[email protected]e7b1c6d2c2012-05-05 00:54:032523 handle.Reset();
2524
2525 // Should now have one idle socket.
2526 ASSERT_EQ(1, pool_->IdleSocketCount());
2527
2528 // Request a new socket. This should reuse the old socket and complete
2529 // synchronously.
vishal.b62985ca92015-04-17 08:45:512530 BoundTestNetLog log;
Matt Menke28ac03e2019-02-25 22:25:502531 rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:282532 TestGroupId("a"), params_, base::nullopt, LOWEST, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502533 ClientSocketPool::RespectLimits::ENABLED, CompletionOnceCallback(),
2534 ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound());
robpercival214763f2016-07-01 23:27:012535 ASSERT_THAT(rv, IsOk());
[email protected]e7b1c6d2c2012-05-05 00:54:032536 EXPECT_TRUE(handle.is_reused());
[email protected]034df0f32013-01-07 23:17:482537 TestLoadTimingInfoConnectedReused(handle);
[email protected]e7b1c6d2c2012-05-05 00:54:032538
Matt Menke9fa17d52019-03-25 19:12:262539 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:392540 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menke9fa17d52019-03-25 19:12:262541 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
[email protected]e7b1c6d2c2012-05-05 00:54:032542
Eric Roman79cc7552019-07-19 02:17:542543 auto entries = log.GetEntries();
Matt Menke9fa17d52019-03-25 19:12:262544 EXPECT_TRUE(LogContainsEvent(
2545 entries, 0, NetLogEventType::TCP_CLIENT_SOCKET_POOL_REQUESTED_SOCKET,
2546 NetLogEventPhase::NONE));
2547 EXPECT_TRUE(LogContainsBeginEvent(entries, 1, NetLogEventType::SOCKET_POOL));
[email protected]e7b1c6d2c2012-05-05 00:54:032548 EXPECT_TRUE(LogContainsEntryWithType(
Matt Menke9fa17d52019-03-25 19:12:262549 entries, 2, NetLogEventType::SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]e7b1c6d2c2012-05-05 00:54:032550}
2551
martijn003cd612016-05-19 22:24:382552// Make sure we cleanup old unused sockets.
Eric Romanb49715e2018-04-24 22:41:172553TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSocketsNoReuse) {
[email protected]e7b1c6d2c2012-05-05 00:54:032554 CreatePoolWithIdleTimeouts(
2555 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2556 base::TimeDelta(), // Time out unused sockets immediately
2557 base::TimeDelta()); // Time out used sockets immediately
[email protected]64770b7d2011-11-16 04:30:412558
2559 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2560
2561 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
2562
2563 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522564 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502565 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:282566 TestGroupId("a"), params_, base::nullopt, LOWEST, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502567 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2568 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012569 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
Matt Menkec6b3edf72019-03-19 17:00:392570 EXPECT_EQ(LOAD_STATE_CONNECTING,
2571 pool_->GetLoadState(TestGroupId("a"), &handle));
[email protected]64770b7d2011-11-16 04:30:412572
2573 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522574 TestCompletionCallback callback2;
Matt Menkef09e64c2019-04-23 22:16:282575 rv = handle2.Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
2576 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502577 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2578 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012579 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
Matt Menkec6b3edf72019-03-19 17:00:392580 EXPECT_EQ(LOAD_STATE_CONNECTING,
2581 pool_->GetLoadState(TestGroupId("a"), &handle2));
[email protected]64770b7d2011-11-16 04:30:412582
2583 // Cancel one of the requests. Wait for the other, which will get the first
2584 // job. Release the socket. Run the loop again to make sure the second
2585 // socket is sitting idle and the first one is released (since ReleaseSocket()
2586 // just posts a DoReleaseSocket() task).
2587
2588 handle.Reset();
robpercival214763f2016-07-01 23:27:012589 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]64770b7d2011-11-16 04:30:412590 // Use the socket.
Raul Tambre94493c652019-03-11 17:18:352591 EXPECT_EQ(1, handle2.socket()->Write(nullptr, 1, CompletionOnceCallback(),
Ramin Halavati0a08cc82018-02-06 07:46:382592 TRAFFIC_ANNOTATION_FOR_TESTS));
[email protected]64770b7d2011-11-16 04:30:412593 handle2.Reset();
2594
[email protected]e7b1c6d2c2012-05-05 00:54:032595 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
2596 // actually become pending until 2ms after they have been created. In order
2597 // to flush all tasks, we need to wait so that we know there are no
2598 // soon-to-be-pending tasks waiting.
Alex Clarke0def2092018-12-10 12:01:452599 FastForwardBy(base::TimeDelta::FromMilliseconds(10));
[email protected]64770b7d2011-11-16 04:30:412600
[email protected]e7b1c6d2c2012-05-05 00:54:032601 // Both sockets should now be idle.
[email protected]64770b7d2011-11-16 04:30:412602 ASSERT_EQ(2, pool_->IdleSocketCount());
2603
2604 // Request a new socket. This should cleanup the unused and timed out ones.
2605 // A new socket will be created rather than reusing the idle one.
vishal.b62985ca92015-04-17 08:45:512606 BoundTestNetLog log;
[email protected]6ecf2b92011-12-15 01:14:522607 TestCompletionCallback callback3;
Matt Menkef09e64c2019-04-23 22:16:282608 rv = handle.Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
2609 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502610 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
2611 pool_.get(), log.bound());
robpercival214763f2016-07-01 23:27:012612 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
2613 ASSERT_THAT(callback3.WaitForResult(), IsOk());
[email protected]64770b7d2011-11-16 04:30:412614 EXPECT_FALSE(handle.is_reused());
2615
[email protected]e7b1c6d2c2012-05-05 00:54:032616 // Make sure the idle socket is closed.
Matt Menke9fa17d52019-03-25 19:12:262617 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:392618 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menke9fa17d52019-03-25 19:12:262619 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
[email protected]64770b7d2011-11-16 04:30:412620
Eric Roman79cc7552019-07-19 02:17:542621 auto entries = log.GetEntries();
[email protected]64770b7d2011-11-16 04:30:412622 EXPECT_FALSE(LogContainsEntryWithType(
mikecirone8b85c432016-09-08 19:11:002623 entries, 1, NetLogEventType::SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]64770b7d2011-11-16 04:30:412624}
2625
[email protected]2041cf342010-02-19 03:15:592626// Make sure that we process all pending requests even when we're stalling
[email protected]4f2abec2010-02-03 18:10:162627// because of multiple releasing disconnected sockets.
2628TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
2629 CreatePoolWithIdleTimeouts(
2630 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2631 base::TimeDelta(), // Time out unused sockets immediately.
2632 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2633
2634 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2635
2636 // Startup 4 connect jobs. Two of them will be pending.
2637
[email protected]2431756e2010-09-29 20:26:132638 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522639 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502640 int rv = handle.Init(
Matt Menkef09e64c2019-04-23 22:16:282641 TestGroupId("a"), params_, base::nullopt, LOWEST, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502642 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2643 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012644 EXPECT_THAT(rv, IsOk());
[email protected]4f2abec2010-02-03 18:10:162645
[email protected]2431756e2010-09-29 20:26:132646 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522647 TestCompletionCallback callback2;
Matt Menkef09e64c2019-04-23 22:16:282648 rv = handle2.Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
2649 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502650 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2651 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012652 EXPECT_THAT(rv, IsOk());
[email protected]4f2abec2010-02-03 18:10:162653
[email protected]2431756e2010-09-29 20:26:132654 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:522655 TestCompletionCallback callback3;
Matt Menkef09e64c2019-04-23 22:16:282656 rv = handle3.Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
2657 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502658 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
2659 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012660 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4f2abec2010-02-03 18:10:162661
[email protected]2431756e2010-09-29 20:26:132662 ClientSocketHandle handle4;
[email protected]6ecf2b92011-12-15 01:14:522663 TestCompletionCallback callback4;
Matt Menkef09e64c2019-04-23 22:16:282664 rv = handle4.Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
2665 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502666 callback4.callback(), ClientSocketPool::ProxyAuthCallback(),
2667 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012668 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4f2abec2010-02-03 18:10:162669
2670 // Release two disconnected sockets.
2671
[email protected]2431756e2010-09-29 20:26:132672 handle.socket()->Disconnect();
2673 handle.Reset();
2674 handle2.socket()->Disconnect();
2675 handle2.Reset();
[email protected]4f2abec2010-02-03 18:10:162676
robpercival214763f2016-07-01 23:27:012677 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132678 EXPECT_FALSE(handle3.is_reused());
robpercival214763f2016-07-01 23:27:012679 EXPECT_THAT(callback4.WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132680 EXPECT_FALSE(handle4.is_reused());
[email protected]4f2abec2010-02-03 18:10:162681}
2682
[email protected]d7027bb2010-05-10 18:58:542683// Regression test for http://crbug.com/42267.
2684// When DoReleaseSocket() is processed for one socket, it is blocked because the
2685// other stalled groups all have releasing sockets, so no progress can be made.
2686TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
2687 CreatePoolWithIdleTimeouts(
2688 4 /* socket limit */, 4 /* socket limit per group */,
2689 base::TimeDelta(), // Time out unused sockets immediately.
2690 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2691
2692 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2693
2694 // Max out the socket limit with 2 per group.
2695
[email protected]2431756e2010-09-29 20:26:132696 ClientSocketHandle handle_a[4];
[email protected]6ecf2b92011-12-15 01:14:522697 TestCompletionCallback callback_a[4];
[email protected]2431756e2010-09-29 20:26:132698 ClientSocketHandle handle_b[4];
[email protected]6ecf2b92011-12-15 01:14:522699 TestCompletionCallback callback_b[4];
[email protected]d7027bb2010-05-10 18:58:542700
2701 for (int i = 0; i < 2; ++i) {
Matt Menkef09e64c2019-04-23 22:16:282702 EXPECT_EQ(OK, handle_a[i].Init(TestGroupId("a"), params_, base::nullopt,
2703 LOWEST, SocketTag(),
2704 ClientSocketPool::RespectLimits::ENABLED,
2705 callback_a[i].callback(),
2706 ClientSocketPool::ProxyAuthCallback(),
2707 pool_.get(), NetLogWithSource()));
2708 EXPECT_EQ(OK, handle_b[i].Init(TestGroupId("b"), params_, base::nullopt,
2709 LOWEST, SocketTag(),
2710 ClientSocketPool::RespectLimits::ENABLED,
2711 callback_b[i].callback(),
2712 ClientSocketPool::ProxyAuthCallback(),
2713 pool_.get(), NetLogWithSource()));
[email protected]d7027bb2010-05-10 18:58:542714 }
[email protected]b89f7e42010-05-20 20:37:002715
[email protected]d7027bb2010-05-10 18:58:542716 // Make 4 pending requests, 2 per group.
2717
2718 for (int i = 2; i < 4; ++i) {
Matt Menkef09e64c2019-04-23 22:16:282719 EXPECT_EQ(
2720 ERR_IO_PENDING,
2721 handle_a[i].Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
2722 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2723 callback_a[i].callback(),
2724 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2725 NetLogWithSource()));
2726 EXPECT_EQ(
2727 ERR_IO_PENDING,
2728 handle_b[i].Init(TestGroupId("b"), params_, base::nullopt, LOWEST,
2729 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2730 callback_b[i].callback(),
2731 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2732 NetLogWithSource()));
[email protected]d7027bb2010-05-10 18:58:542733 }
2734
2735 // Release b's socket first. The order is important, because in
2736 // DoReleaseSocket(), we'll process b's released socket, and since both b and
2737 // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
2738 // first, which has a releasing socket, so it refuses to start up another
2739 // ConnectJob. So, we used to infinite loop on this.
[email protected]2431756e2010-09-29 20:26:132740 handle_b[0].socket()->Disconnect();
2741 handle_b[0].Reset();
2742 handle_a[0].socket()->Disconnect();
2743 handle_a[0].Reset();
[email protected]d7027bb2010-05-10 18:58:542744
2745 // Used to get stuck here.
fdoray5eeb7642016-06-22 16:11:282746 base::RunLoop().RunUntilIdle();
[email protected]d7027bb2010-05-10 18:58:542747
[email protected]2431756e2010-09-29 20:26:132748 handle_b[1].socket()->Disconnect();
2749 handle_b[1].Reset();
2750 handle_a[1].socket()->Disconnect();
2751 handle_a[1].Reset();
[email protected]d7027bb2010-05-10 18:58:542752
2753 for (int i = 2; i < 4; ++i) {
robpercival214763f2016-07-01 23:27:012754 EXPECT_THAT(callback_b[i].WaitForResult(), IsOk());
2755 EXPECT_THAT(callback_a[i].WaitForResult(), IsOk());
[email protected]d7027bb2010-05-10 18:58:542756 }
2757}
2758
[email protected]fd4fe0b2010-02-08 23:02:152759TEST_F(ClientSocketPoolBaseTest,
2760 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
2761 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2762
2763 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2764
Matt Menkec6b3edf72019-03-19 17:00:392765 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2766 IsError(ERR_IO_PENDING));
2767 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2768 IsError(ERR_IO_PENDING));
2769 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2770 IsError(ERR_IO_PENDING));
2771 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2772 IsError(ERR_IO_PENDING));
[email protected]fd4fe0b2010-02-08 23:02:152773
robpercival214763f2016-07-01 23:27:012774 EXPECT_THAT((*requests())[0]->WaitForResult(), IsOk());
2775 EXPECT_THAT((*requests())[1]->WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132776 EXPECT_EQ(2u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152777
2778 // Releases one connection.
[email protected]2431756e2010-09-29 20:26:132779 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
robpercival214763f2016-07-01 23:27:012780 EXPECT_THAT((*requests())[2]->WaitForResult(), IsOk());
[email protected]fd4fe0b2010-02-08 23:02:152781
[email protected]2431756e2010-09-29 20:26:132782 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
robpercival214763f2016-07-01 23:27:012783 EXPECT_THAT((*requests())[3]->WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132784 EXPECT_EQ(4u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152785
2786 EXPECT_EQ(1, GetOrderOfRequest(1));
2787 EXPECT_EQ(2, GetOrderOfRequest(2));
2788 EXPECT_EQ(3, GetOrderOfRequest(3));
2789 EXPECT_EQ(4, GetOrderOfRequest(4));
2790
2791 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:132792 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(5));
[email protected]fd4fe0b2010-02-08 23:02:152793}
2794
[email protected]6ecf2b92011-12-15 01:14:522795class TestReleasingSocketRequest : public TestCompletionCallbackBase {
[email protected]4f1e4982010-03-02 18:31:042796 public:
Matt Menke9fa17d52019-03-25 19:12:262797 TestReleasingSocketRequest(TransportClientSocketPool* pool,
[email protected]2431756e2010-09-29 20:26:132798 int expected_result,
[email protected]e60e47a2010-07-14 03:37:182799 bool reset_releasing_handle)
2800 : pool_(pool),
2801 expected_result_(expected_result),
Bence Béky8ddc2492018-06-13 01:02:042802 reset_releasing_handle_(reset_releasing_handle) {}
[email protected]6ecf2b92011-12-15 01:14:522803
Chris Watkins7a41d3552017-12-01 02:13:272804 ~TestReleasingSocketRequest() override = default;
[email protected]4f1e4982010-03-02 18:31:042805
2806 ClientSocketHandle* handle() { return &handle_; }
2807
Bence Béky8ddc2492018-06-13 01:02:042808 CompletionOnceCallback callback() {
2809 return base::BindOnce(&TestReleasingSocketRequest::OnComplete,
2810 base::Unretained(this));
2811 }
[email protected]4f1e4982010-03-02 18:31:042812
2813 private:
[email protected]6ecf2b92011-12-15 01:14:522814 void OnComplete(int result) {
2815 SetResult(result);
2816 if (reset_releasing_handle_)
2817 handle_.Reset();
2818
Matt Menkec6b3edf72019-03-19 17:00:392819 EXPECT_EQ(
2820 expected_result_,
Matt Menke870e19ab2019-04-23 16:23:032821 handle2_.Init(
2822 TestGroupId("a"),
2823 ClientSocketPool::SocketParams::CreateForHttpForTesting(),
Matt Menkef09e64c2019-04-23 22:16:282824 base::nullopt, DEFAULT_PRIORITY, SocketTag(),
Matt Menke870e19ab2019-04-23 16:23:032825 ClientSocketPool::RespectLimits::ENABLED, CompletionOnceCallback(),
2826 ClientSocketPool::ProxyAuthCallback(), pool_, NetLogWithSource()));
[email protected]6ecf2b92011-12-15 01:14:522827 }
2828
Matt Menke9fa17d52019-03-25 19:12:262829 TransportClientSocketPool* const pool_;
[email protected]e60e47a2010-07-14 03:37:182830 int expected_result_;
2831 bool reset_releasing_handle_;
[email protected]4f1e4982010-03-02 18:31:042832 ClientSocketHandle handle_;
2833 ClientSocketHandle handle2_;
[email protected]4f1e4982010-03-02 18:31:042834};
2835
[email protected]e60e47a2010-07-14 03:37:182836
2837TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) {
2838 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2839
Matt Menkec6b3edf72019-03-19 17:00:392840 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
2841 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
2842 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
[email protected]e60e47a2010-07-14 03:37:182843
[email protected]2431756e2010-09-29 20:26:132844 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]e60e47a2010-07-14 03:37:182845 client_socket_factory_.allocation_count());
2846
2847 connect_job_factory_->set_job_type(
2848 TestConnectJob::kMockPendingAdditionalErrorStateJob);
2849 TestReleasingSocketRequest req(pool_.get(), OK, false);
Matt Menkef09e64c2019-04-23 22:16:282850 EXPECT_EQ(ERR_IO_PENDING,
2851 req.handle()->Init(
2852 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2853 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2854 req.callback(), ClientSocketPool::ProxyAuthCallback(),
2855 pool_.get(), NetLogWithSource()));
[email protected]e60e47a2010-07-14 03:37:182856 // The next job should complete synchronously
2857 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2858
robpercival214763f2016-07-01 23:27:012859 EXPECT_THAT(req.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:182860 EXPECT_FALSE(req.handle()->is_initialized());
2861 EXPECT_FALSE(req.handle()->socket());
2862 EXPECT_TRUE(req.handle()->is_ssl_error());
Matt Menke39b7c5a2019-04-10 19:47:512863 EXPECT_TRUE(req.handle()->ssl_cert_request_info());
[email protected]e60e47a2010-07-14 03:37:182864}
2865
[email protected]b6501d3d2010-06-03 23:53:342866// http://crbug.com/44724 regression test.
2867// We start releasing the pool when we flush on network change. When that
2868// happens, the only active references are in the ClientSocketHandles. When a
2869// ConnectJob completes and calls back into the last ClientSocketHandle, that
2870// callback can release the last reference and delete the pool. After the
2871// callback finishes, we go back to the stack frame within the now-deleted pool.
2872// Executing any code that refers to members of the now-deleted pool can cause
2873// crashes.
2874TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
2875 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2876 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2877
2878 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522879 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502880 EXPECT_EQ(
2881 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:282882 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2883 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2884 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2885 pool_.get(), NetLogWithSource()));
[email protected]b6501d3d2010-06-03 23:53:342886
[email protected]7af985a2012-12-14 22:40:422887 pool_->FlushWithError(ERR_NETWORK_CHANGED);
[email protected]b6501d3d2010-06-03 23:53:342888
2889 // We'll call back into this now.
2890 callback.WaitForResult();
2891}
2892
[email protected]a7e38572010-06-07 18:22:242893TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
2894 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2895 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2896
2897 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522898 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502899 EXPECT_EQ(
2900 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:282901 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2902 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2903 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2904 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:012905 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]a7e38572010-06-07 18:22:242906 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2907
[email protected]7af985a2012-12-14 22:40:422908 pool_->FlushWithError(ERR_NETWORK_CHANGED);
[email protected]a7e38572010-06-07 18:22:242909
2910 handle.Reset();
fdoray5eeb7642016-06-22 16:11:282911 base::RunLoop().RunUntilIdle();
[email protected]a7e38572010-06-07 18:22:242912
Matt Menke28ac03e2019-02-25 22:25:502913 EXPECT_EQ(
2914 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:282915 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2916 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2917 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2918 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:012919 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]a7e38572010-06-07 18:22:242920 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2921}
2922
[email protected]6ecf2b92011-12-15 01:14:522923class ConnectWithinCallback : public TestCompletionCallbackBase {
[email protected]06f92462010-08-31 19:24:142924 public:
Matt Menke9fa17d52019-03-25 19:12:262925 ConnectWithinCallback(
2926 const ClientSocketPool::GroupId& group_id,
Matt Menke84d11e562019-03-27 00:11:192927 const scoped_refptr<ClientSocketPool::SocketParams>& params,
Matt Menke9fa17d52019-03-25 19:12:262928 TransportClientSocketPool* pool)
Matt Menkec6b3edf72019-03-19 17:00:392929 : group_id_(group_id), params_(params), pool_(pool) {}
[email protected]06f92462010-08-31 19:24:142930
Chris Watkins7a41d3552017-12-01 02:13:272931 ~ConnectWithinCallback() override = default;
[email protected]06f92462010-08-31 19:24:142932
2933 int WaitForNestedResult() {
2934 return nested_callback_.WaitForResult();
2935 }
2936
Bence Béky8ddc2492018-06-13 01:02:042937 CompletionOnceCallback callback() {
2938 return base::BindOnce(&ConnectWithinCallback::OnComplete,
2939 base::Unretained(this));
2940 }
[email protected]6ecf2b92011-12-15 01:14:522941
[email protected]06f92462010-08-31 19:24:142942 private:
[email protected]6ecf2b92011-12-15 01:14:522943 void OnComplete(int result) {
2944 SetResult(result);
Matt Menkef09e64c2019-04-23 22:16:282945 EXPECT_EQ(
2946 ERR_IO_PENDING,
2947 handle_.Init(group_id_, params_, base::nullopt, DEFAULT_PRIORITY,
2948 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2949 nested_callback_.callback(),
2950 ClientSocketPool::ProxyAuthCallback(), pool_,
2951 NetLogWithSource()));
[email protected]6ecf2b92011-12-15 01:14:522952 }
2953
Matt Menkec6b3edf72019-03-19 17:00:392954 const ClientSocketPool::GroupId group_id_;
Matt Menke84d11e562019-03-27 00:11:192955 const scoped_refptr<ClientSocketPool::SocketParams> params_;
Matt Menke9fa17d52019-03-25 19:12:262956 TransportClientSocketPool* const pool_;
[email protected]06f92462010-08-31 19:24:142957 ClientSocketHandle handle_;
[email protected]6ecf2b92011-12-15 01:14:522958 TestCompletionCallback nested_callback_;
2959
2960 DISALLOW_COPY_AND_ASSIGN(ConnectWithinCallback);
[email protected]06f92462010-08-31 19:24:142961};
2962
2963TEST_F(ClientSocketPoolBaseTest, AbortAllRequestsOnFlush) {
2964 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2965
2966 // First job will be waiting until it gets aborted.
2967 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2968
2969 ClientSocketHandle handle;
Matt Menkec6b3edf72019-03-19 17:00:392970 ConnectWithinCallback callback(TestGroupId("a"), params_, pool_.get());
Matt Menke28ac03e2019-02-25 22:25:502971 EXPECT_EQ(
2972 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:282973 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2974 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2975 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2976 pool_.get(), NetLogWithSource()));
[email protected]06f92462010-08-31 19:24:142977
2978 // Second job will be started during the first callback, and will
2979 // asynchronously complete with OK.
2980 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]7af985a2012-12-14 22:40:422981 pool_->FlushWithError(ERR_NETWORK_CHANGED);
robpercival214763f2016-07-01 23:27:012982 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NETWORK_CHANGED));
2983 EXPECT_THAT(callback.WaitForNestedResult(), IsOk());
[email protected]06f92462010-08-31 19:24:142984}
2985
Matt Menke141b87f22019-01-30 02:43:032986TEST_F(ClientSocketPoolBaseTest, BackupSocketWaitsForHostResolution) {
Matt Menke9fa17d52019-03-25 19:12:262987 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets,
2988 true /* enable_backup_connect_jobs */);
Matt Menke141b87f22019-01-30 02:43:032989
2990 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2991 ClientSocketHandle handle;
2992 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502993 EXPECT_EQ(
2994 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:282995 handle.Init(TestGroupId("bar"), params_, base::nullopt, DEFAULT_PRIORITY,
2996 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2997 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2998 pool_.get(), NetLogWithSource()));
Matt Menke141b87f22019-01-30 02:43:032999 // The backup timer fires but doesn't start a new ConnectJob while resolving
3000 // the hostname.
3001 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_RESOLVING_HOST);
3002 FastForwardBy(base::TimeDelta::FromMilliseconds(
3003 ClientSocketPool::kMaxConnectRetryIntervalMs * 100));
3004 EXPECT_EQ(1, client_socket_factory_.allocation_count());
3005
3006 // Once the ConnectJob has finished resolving the hostname, the backup timer
3007 // will create a ConnectJob when it fires.
3008 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_CONNECTING);
3009 FastForwardBy(base::TimeDelta::FromMilliseconds(
3010 ClientSocketPool::kMaxConnectRetryIntervalMs));
3011 EXPECT_EQ(2, client_socket_factory_.allocation_count());
3012}
3013
3014// Test that no backup socket is created when a ConnectJob connects before it
3015// completes.
3016TEST_F(ClientSocketPoolBaseTest, NoBackupSocketWhenConnected) {
Matt Menke9fa17d52019-03-25 19:12:263017 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets,
3018 true /* enable_backup_connect_jobs */);
Matt Menke141b87f22019-01-30 02:43:033019
3020 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3021 ClientSocketHandle handle;
3022 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:503023 EXPECT_EQ(
3024 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283025 handle.Init(TestGroupId("bar"), params_, base::nullopt, DEFAULT_PRIORITY,
3026 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3027 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3028 pool_.get(), NetLogWithSource()));
Matt Menke141b87f22019-01-30 02:43:033029 // The backup timer fires but doesn't start a new ConnectJob while resolving
3030 // the hostname.
3031 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_RESOLVING_HOST);
3032 FastForwardBy(base::TimeDelta::FromMilliseconds(
3033 ClientSocketPool::kMaxConnectRetryIntervalMs * 100));
3034 EXPECT_EQ(1, client_socket_factory_.allocation_count());
3035
3036 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
3037 client_socket_factory_.SetJobHasEstablishedConnection(0);
3038 FastForwardBy(base::TimeDelta::FromMilliseconds(
3039 ClientSocketPool::kMaxConnectRetryIntervalMs * 100));
3040 EXPECT_EQ(1, client_socket_factory_.allocation_count());
3041}
3042
[email protected]25eea382010-07-10 23:55:263043// Cancel a pending socket request while we're at max sockets,
3044// and verify that the backup socket firing doesn't cause a crash.
3045TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
3046 // Max 4 sockets globally, max 4 sockets per group.
Matt Menke9fa17d52019-03-25 19:12:263047 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets,
3048 true /* enable_backup_connect_jobs */);
[email protected]25eea382010-07-10 23:55:263049
[email protected]4baaf9d2010-08-31 15:15:443050 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
3051 // timer.
[email protected]25eea382010-07-10 23:55:263052 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3053 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:523054 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:503055 EXPECT_EQ(
3056 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283057 handle.Init(TestGroupId("bar"), params_, base::nullopt, DEFAULT_PRIORITY,
3058 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3059 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3060 pool_.get(), NetLogWithSource()));
[email protected]25eea382010-07-10 23:55:263061
3062 // Start (MaxSockets - 1) connected sockets to reach max sockets.
3063 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3064 ClientSocketHandle handles[kDefaultMaxSockets];
3065 for (int i = 1; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:523066 TestCompletionCallback callback;
Matt Menkef09e64c2019-04-23 22:16:283067 EXPECT_EQ(OK, handles[i].Init(TestGroupId("bar"), params_, base::nullopt,
3068 DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203069 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503070 callback.callback(),
3071 ClientSocketPool::ProxyAuthCallback(),
3072 pool_.get(), NetLogWithSource()));
[email protected]25eea382010-07-10 23:55:263073 }
3074
fdoray5eeb7642016-06-22 16:11:283075 base::RunLoop().RunUntilIdle();
[email protected]25eea382010-07-10 23:55:263076
3077 // Cancel the pending request.
3078 handle.Reset();
3079
3080 // Wait for the backup timer to fire (add some slop to ensure it fires)
Alex Clarke0def2092018-12-10 12:01:453081 FastForwardBy(base::TimeDelta::FromMilliseconds(
[email protected]26b9973962012-01-28 00:57:003082 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]25eea382010-07-10 23:55:263083
[email protected]25eea382010-07-10 23:55:263084 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
3085}
3086
[email protected]3f00be82010-09-27 19:50:023087TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterCancelingAllRequests) {
Matt Menke9fa17d52019-03-25 19:12:263088 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets,
3089 true /* enable_backup_connect_jobs */);
[email protected]4baaf9d2010-08-31 15:15:443090
3091 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
3092 // timer.
3093 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3094 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:523095 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:503096 EXPECT_EQ(
3097 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283098 handle.Init(TestGroupId("bar"), params_, base::nullopt, DEFAULT_PRIORITY,
3099 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3100 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3101 pool_.get(), NetLogWithSource()));
Matt Menke9fa17d52019-03-25 19:12:263102 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("bar")));
3103 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("bar")));
3104 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3105 TestGroupId("bar")));
3106 EXPECT_EQ(
3107 0u, pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("bar")));
[email protected]4baaf9d2010-08-31 15:15:443108
3109 // Cancel the socket request. This should cancel the backup timer. Wait for
3110 // the backup time to see if it indeed got canceled.
3111 handle.Reset();
3112 // Wait for the backup timer to fire (add some slop to ensure it fires)
Alex Clarke0def2092018-12-10 12:01:453113 FastForwardBy(base::TimeDelta::FromMilliseconds(
[email protected]26b9973962012-01-28 00:57:003114 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
Matt Menke9fa17d52019-03-25 19:12:263115 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("bar")));
3116 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("bar")));
[email protected]4baaf9d2010-08-31 15:15:443117}
3118
[email protected]3f00be82010-09-27 19:50:023119TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterFinishingAllRequests) {
Matt Menke9fa17d52019-03-25 19:12:263120 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets,
3121 true /* enable_backup_connect_jobs */);
[email protected]3f00be82010-09-27 19:50:023122
3123 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
3124 // timer.
3125 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3126 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:523127 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:503128 EXPECT_EQ(
3129 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283130 handle.Init(TestGroupId("bar"), params_, base::nullopt, DEFAULT_PRIORITY,
3131 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3132 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3133 pool_.get(), NetLogWithSource()));
[email protected]3f00be82010-09-27 19:50:023134 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3135 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523136 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203137 EXPECT_EQ(
3138 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283139 handle2.Init(TestGroupId("bar"), params_, base::nullopt, DEFAULT_PRIORITY,
3140 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503141 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3142 pool_.get(), NetLogWithSource()));
Matt Menke9fa17d52019-03-25 19:12:263143 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("bar")));
3144 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("bar")));
[email protected]3f00be82010-09-27 19:50:023145
3146 // Cancel request 1 and then complete request 2. With the requests finished,
3147 // the backup timer should be cancelled.
3148 handle.Reset();
robpercival214763f2016-07-01 23:27:013149 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]3f00be82010-09-27 19:50:023150 // Wait for the backup timer to fire (add some slop to ensure it fires)
Alex Clarke0def2092018-12-10 12:01:453151 FastForwardBy(base::TimeDelta::FromMilliseconds(
[email protected]26b9973962012-01-28 00:57:003152 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]3f00be82010-09-27 19:50:023153}
3154
[email protected]eb5a99382010-07-11 03:18:263155// Test delayed socket binding for the case where we have two connects,
3156// and while one is waiting on a connect, the other frees up.
3157// The socket waiting on a connect should switch immediately to the freed
3158// up socket.
3159TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
3160 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3161 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3162
3163 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523164 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:503165 EXPECT_EQ(
3166 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283167 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3168 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503169 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3170 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013171 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:263172
3173 // No idle sockets, no pending jobs.
3174 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menke9fa17d52019-03-25 19:12:263175 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263176
3177 // Create a second socket to the same host, but this one will wait.
3178 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3179 ClientSocketHandle handle2;
Matt Menke28ac03e2019-02-25 22:25:503180 EXPECT_EQ(
3181 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283182 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3183 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503184 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3185 pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:263186 // No idle sockets, and one connecting job.
3187 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menke9fa17d52019-03-25 19:12:263188 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263189
3190 // Return the first handle to the pool. This will initiate the delayed
3191 // binding.
3192 handle1.Reset();
3193
fdoray5eeb7642016-06-22 16:11:283194 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263195
3196 // Still no idle sockets, still one pending connect job.
3197 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menke9fa17d52019-03-25 19:12:263198 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263199
3200 // The second socket connected, even though it was a Waiting Job.
robpercival214763f2016-07-01 23:27:013201 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:263202
3203 // And we can see there is still one job waiting.
Matt Menke9fa17d52019-03-25 19:12:263204 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263205
3206 // Finally, signal the waiting Connect.
3207 client_socket_factory_.SignalJobs();
Matt Menke9fa17d52019-03-25 19:12:263208 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263209
fdoray5eeb7642016-06-22 16:11:283210 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263211}
3212
3213// Test delayed socket binding when a group is at capacity and one
3214// of the group's sockets frees up.
3215TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
3216 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3217 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3218
3219 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523220 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:503221 EXPECT_EQ(
3222 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283223 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3224 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503225 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3226 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013227 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:263228
3229 // No idle sockets, no pending jobs.
3230 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menke9fa17d52019-03-25 19:12:263231 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263232
3233 // Create a second socket to the same host, but this one will wait.
3234 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3235 ClientSocketHandle handle2;
Matt Menke28ac03e2019-02-25 22:25:503236 EXPECT_EQ(
3237 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283238 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3239 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503240 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3241 pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:263242 // No idle sockets, and one connecting job.
3243 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menke9fa17d52019-03-25 19:12:263244 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263245
3246 // Return the first handle to the pool. This will initiate the delayed
3247 // binding.
3248 handle1.Reset();
3249
fdoray5eeb7642016-06-22 16:11:283250 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263251
3252 // Still no idle sockets, still one pending connect job.
3253 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menke9fa17d52019-03-25 19:12:263254 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263255
3256 // The second socket connected, even though it was a Waiting Job.
robpercival214763f2016-07-01 23:27:013257 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:263258
3259 // And we can see there is still one job waiting.
Matt Menke9fa17d52019-03-25 19:12:263260 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263261
3262 // Finally, signal the waiting Connect.
3263 client_socket_factory_.SignalJobs();
Matt Menke9fa17d52019-03-25 19:12:263264 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263265
fdoray5eeb7642016-06-22 16:11:283266 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263267}
3268
3269// Test out the case where we have one socket connected, one
3270// connecting, when the first socket finishes and goes idle.
[email protected]2abfe90a2010-08-25 17:49:513271// Although the second connection is pending, the second request
[email protected]eb5a99382010-07-11 03:18:263272// should complete, by taking the first socket's idle socket.
3273TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
3274 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3275 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3276
3277 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523278 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:503279 EXPECT_EQ(
3280 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283281 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3282 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503283 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3284 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013285 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:263286
3287 // No idle sockets, no pending jobs.
3288 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menke9fa17d52019-03-25 19:12:263289 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263290
3291 // Create a second socket to the same host, but this one will wait.
3292 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3293 ClientSocketHandle handle2;
Matt Menke28ac03e2019-02-25 22:25:503294 EXPECT_EQ(
3295 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283296 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3297 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503298 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3299 pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:263300 // No idle sockets, and one connecting job.
3301 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menke9fa17d52019-03-25 19:12:263302 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263303
3304 // Return the first handle to the pool. This will initiate the delayed
3305 // binding.
3306 handle1.Reset();
3307
fdoray5eeb7642016-06-22 16:11:283308 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263309
3310 // Still no idle sockets, still one pending connect job.
3311 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menke9fa17d52019-03-25 19:12:263312 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263313
3314 // The second socket connected, even though it was a Waiting Job.
robpercival214763f2016-07-01 23:27:013315 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:263316
3317 // And we can see there is still one job waiting.
Matt Menke9fa17d52019-03-25 19:12:263318 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263319
3320 // Finally, signal the waiting Connect.
3321 client_socket_factory_.SignalJobs();
Matt Menke9fa17d52019-03-25 19:12:263322 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263323
fdoray5eeb7642016-06-22 16:11:283324 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263325}
3326
[email protected]2abfe90a2010-08-25 17:49:513327// Cover the case where on an available socket slot, we have one pending
3328// request that completes synchronously, thereby making the Group empty.
3329TEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) {
3330 const int kUnlimitedSockets = 100;
3331 const int kOneSocketPerGroup = 1;
3332 CreatePool(kUnlimitedSockets, kOneSocketPerGroup);
3333
3334 // Make the first request asynchronous fail.
3335 // This will free up a socket slot later.
3336 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
3337
3338 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523339 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203340 EXPECT_EQ(
3341 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283342 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3343 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503344 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3345 pool_.get(), NetLogWithSource()));
Matt Menke9fa17d52019-03-25 19:12:263346 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]2abfe90a2010-08-25 17:49:513347
3348 // Make the second request synchronously fail. This should make the Group
3349 // empty.
3350 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3351 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523352 TestCompletionCallback callback2;
[email protected]2abfe90a2010-08-25 17:49:513353 // It'll be ERR_IO_PENDING now, but the TestConnectJob will synchronously fail
3354 // when created.
tfarina428341112016-09-22 13:38:203355 EXPECT_EQ(
3356 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283357 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3358 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503359 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3360 pool_.get(), NetLogWithSource()));
[email protected]2abfe90a2010-08-25 17:49:513361
Matt Menke9fa17d52019-03-25 19:12:263362 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]2abfe90a2010-08-25 17:49:513363
robpercival214763f2016-07-01 23:27:013364 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
3365 EXPECT_THAT(callback2.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
Matt Menke9fa17d52019-03-25 19:12:263366 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
[email protected]2abfe90a2010-08-25 17:49:513367}
3368
[email protected]e1b54dc2010-10-06 21:27:223369TEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) {
3370 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3371
3372 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3373
3374 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523375 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203376 EXPECT_EQ(
3377 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283378 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3379 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503380 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3381 pool_.get(), NetLogWithSource()));
[email protected]e1b54dc2010-10-06 21:27:223382
3383 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523384 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203385 EXPECT_EQ(
3386 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283387 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3388 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503389 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3390 pool_.get(), NetLogWithSource()));
[email protected]e1b54dc2010-10-06 21:27:223391 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:523392 TestCompletionCallback callback3;
tfarina428341112016-09-22 13:38:203393 EXPECT_EQ(
3394 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283395 handle3.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3396 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503397 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
3398 pool_.get(), NetLogWithSource()));
[email protected]e1b54dc2010-10-06 21:27:223399
robpercival214763f2016-07-01 23:27:013400 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3401 EXPECT_THAT(callback2.WaitForResult(), IsOk());
3402 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]e1b54dc2010-10-06 21:27:223403
3404 // Use the socket.
Raul Tambre94493c652019-03-11 17:18:353405 EXPECT_EQ(1, handle1.socket()->Write(nullptr, 1, CompletionOnceCallback(),
Ramin Halavati0a08cc82018-02-06 07:46:383406 TRAFFIC_ANNOTATION_FOR_TESTS));
Raul Tambre94493c652019-03-11 17:18:353407 EXPECT_EQ(1, handle3.socket()->Write(nullptr, 1, CompletionOnceCallback(),
Ramin Halavati0a08cc82018-02-06 07:46:383408 TRAFFIC_ANNOTATION_FOR_TESTS));
[email protected]e1b54dc2010-10-06 21:27:223409
3410 handle1.Reset();
3411 handle2.Reset();
3412 handle3.Reset();
3413
Matt Menkec6b3edf72019-03-19 17:00:393414 EXPECT_EQ(OK, handle1.Init(
Matt Menkef09e64c2019-04-23 22:16:283415 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3416 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menkec6b3edf72019-03-19 17:00:393417 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3418 pool_.get(), NetLogWithSource()));
3419 EXPECT_EQ(OK, handle2.Init(
Matt Menkef09e64c2019-04-23 22:16:283420 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3421 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menkec6b3edf72019-03-19 17:00:393422 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3423 pool_.get(), NetLogWithSource()));
3424 EXPECT_EQ(OK, handle3.Init(
Matt Menkef09e64c2019-04-23 22:16:283425 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3426 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menkec6b3edf72019-03-19 17:00:393427 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
3428 pool_.get(), NetLogWithSource()));
[email protected]e1b54dc2010-10-06 21:27:223429
3430 EXPECT_TRUE(handle1.socket()->WasEverUsed());
3431 EXPECT_TRUE(handle2.socket()->WasEverUsed());
3432 EXPECT_FALSE(handle3.socket()->WasEverUsed());
3433}
3434
[email protected]2c2bef152010-10-13 00:55:033435TEST_F(ClientSocketPoolBaseTest, RequestSockets) {
3436 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3437 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3438
Matt Menkef09e64c2019-04-23 22:16:283439 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
3440 NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033441
Matt Menke9fa17d52019-03-25 19:12:263442 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3443 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3444 EXPECT_EQ(2u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3445 TestGroupId("a")));
3446 EXPECT_EQ(2u,
3447 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393448 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033449
3450 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523451 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203452 EXPECT_EQ(
3453 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283454 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3455 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503456 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3457 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033458
3459 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523460 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203461 EXPECT_EQ(
3462 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283463 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3464 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503465 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3466 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033467
Matt Menke9fa17d52019-03-25 19:12:263468 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3469 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3470 TestGroupId("a")));
3471 EXPECT_EQ(0u,
3472 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393473 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033474
robpercival214763f2016-07-01 23:27:013475 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3476 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033477 handle1.Reset();
3478 handle2.Reset();
3479
Matt Menke9fa17d52019-03-25 19:12:263480 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3481 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3482 TestGroupId("a")));
3483 EXPECT_EQ(0u,
3484 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393485 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033486}
3487
3488TEST_F(ClientSocketPoolBaseTest, RequestSocketsWhenAlreadyHaveAConnectJob) {
3489 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3490 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3491
3492 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523493 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203494 EXPECT_EQ(
3495 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283496 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3497 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503498 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3499 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033500
Matt Menke9fa17d52019-03-25 19:12:263501 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3502 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3503 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3504 TestGroupId("a")));
3505 EXPECT_EQ(0u,
3506 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393507 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033508
Matt Menkef09e64c2019-04-23 22:16:283509 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
3510 NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033511
Matt Menke9fa17d52019-03-25 19:12:263512 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3513 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3514 TestGroupId("a")));
3515 EXPECT_EQ(1u,
3516 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393517 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033518
3519 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523520 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203521 EXPECT_EQ(
3522 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283523 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3524 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503525 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3526 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033527
Matt Menke9fa17d52019-03-25 19:12:263528 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3529 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3530 TestGroupId("a")));
3531 EXPECT_EQ(0u,
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
robpercival214763f2016-07-01 23:27:013535 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3536 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033537 handle1.Reset();
3538 handle2.Reset();
3539
Matt Menke9fa17d52019-03-25 19:12:263540 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3541 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3542 TestGroupId("a")));
3543 EXPECT_EQ(0u,
3544 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393545 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033546}
3547
3548TEST_F(ClientSocketPoolBaseTest,
3549 RequestSocketsWhenAlreadyHaveMultipleConnectJob) {
3550 CreatePool(4, 4);
3551 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3552
3553 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523554 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203555 EXPECT_EQ(
3556 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283557 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3558 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503559 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3560 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033561
3562 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523563 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203564 EXPECT_EQ(
3565 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283566 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3567 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503568 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3569 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033570
3571 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:523572 TestCompletionCallback callback3;
tfarina428341112016-09-22 13:38:203573 EXPECT_EQ(
3574 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283575 handle3.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3576 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503577 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
3578 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033579
Matt Menke9fa17d52019-03-25 19:12:263580 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3581 EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3582 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3583 TestGroupId("a")));
3584 EXPECT_EQ(0u,
3585 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393586 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033587
Matt Menkef09e64c2019-04-23 22:16:283588 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
3589 NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033590
Matt Menke9fa17d52019-03-25 19:12:263591 EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3592 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3593 TestGroupId("a")));
3594 EXPECT_EQ(0u,
3595 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393596 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033597
robpercival214763f2016-07-01 23:27:013598 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3599 EXPECT_THAT(callback2.WaitForResult(), IsOk());
3600 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033601 handle1.Reset();
3602 handle2.Reset();
3603 handle3.Reset();
3604
Matt Menke9fa17d52019-03-25 19:12:263605 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3606 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3607 TestGroupId("a")));
3608 EXPECT_EQ(0u,
3609 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393610 EXPECT_EQ(3u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033611}
3612
3613TEST_F(ClientSocketPoolBaseTest, RequestSocketsAtMaxSocketLimit) {
3614 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3615 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3616
Matt Menke9fa17d52019-03-25 19:12:263617 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033618
Matt Menkef09e64c2019-04-23 22:16:283619 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt,
3620 kDefaultMaxSockets, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033621
Matt Menke9fa17d52019-03-25 19:12:263622 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
Raul Tambre8335a6d2019-02-21 16:57:433623 EXPECT_EQ(kDefaultMaxSockets,
Matt Menkec6b3edf72019-03-19 17:00:393624 static_cast<int>(
Matt Menke9fa17d52019-03-25 19:12:263625 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))));
3626 EXPECT_EQ(
3627 kDefaultMaxSockets,
3628 static_cast<int>(pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3629 TestGroupId("a"))));
Raul Tambre8335a6d2019-02-21 16:57:433630 EXPECT_EQ(kDefaultMaxSockets,
Matt Menke9fa17d52019-03-25 19:12:263631 static_cast<int>(pool_->NumUnassignedConnectJobsInGroupForTesting(
3632 TestGroupId("a"))));
[email protected]2c2bef152010-10-13 00:55:033633
Matt Menke9fa17d52019-03-25 19:12:263634 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("b")));
[email protected]2c2bef152010-10-13 00:55:033635
Matt Menkef09e64c2019-04-23 22:16:283636 pool_->RequestSockets(TestGroupId("b"), params_, base::nullopt,
3637 kDefaultMaxSockets, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033638
Matt Menke9fa17d52019-03-25 19:12:263639 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("b")));
[email protected]2c2bef152010-10-13 00:55:033640}
3641
3642TEST_F(ClientSocketPoolBaseTest, RequestSocketsHitMaxSocketLimit) {
3643 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3644 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3645
Matt Menke9fa17d52019-03-25 19:12:263646 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033647
Matt Menkef09e64c2019-04-23 22:16:283648 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt,
3649 kDefaultMaxSockets - 1, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033650
Matt Menke9fa17d52019-03-25 19:12:263651 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:433652 EXPECT_EQ(kDefaultMaxSockets - 1,
Matt Menkec6b3edf72019-03-19 17:00:393653 static_cast<int>(
Matt Menke9fa17d52019-03-25 19:12:263654 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))));
3655 EXPECT_EQ(
3656 kDefaultMaxSockets - 1,
3657 static_cast<int>(pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3658 TestGroupId("a"))));
Raul Tambre8335a6d2019-02-21 16:57:433659 EXPECT_EQ(kDefaultMaxSockets - 1,
Matt Menke9fa17d52019-03-25 19:12:263660 static_cast<int>(pool_->NumUnassignedConnectJobsInGroupForTesting(
3661 TestGroupId("a"))));
[email protected]51fdc7c2012-04-10 19:19:483662 EXPECT_FALSE(pool_->IsStalled());
[email protected]2c2bef152010-10-13 00:55:033663
Matt Menke9fa17d52019-03-25 19:12:263664 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("b")));
[email protected]2c2bef152010-10-13 00:55:033665
Matt Menkef09e64c2019-04-23 22:16:283666 pool_->RequestSockets(TestGroupId("b"), params_, base::nullopt,
3667 kDefaultMaxSockets, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033668
Matt Menke9fa17d52019-03-25 19:12:263669 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("b")));
3670 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
[email protected]51fdc7c2012-04-10 19:19:483671 EXPECT_FALSE(pool_->IsStalled());
[email protected]2c2bef152010-10-13 00:55:033672}
3673
3674TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) {
3675 CreatePool(4, 4);
3676 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3677
3678 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523679 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203680 EXPECT_EQ(
3681 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283682 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3683 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503684 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3685 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013686 ASSERT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033687 handle1.Reset();
3688
Matt Menke9fa17d52019-03-25 19:12:263689 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3690 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(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033696
Matt Menkef09e64c2019-04-23 22:16:283697 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
3698 NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033699
Matt Menke9fa17d52019-03-25 19:12:263700 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3701 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3702 TestGroupId("a")));
3703 EXPECT_EQ(1u,
3704 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393705 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033706}
3707
3708TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountActiveSockets) {
3709 CreatePool(4, 4);
3710 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3711
3712 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523713 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203714 EXPECT_EQ(
3715 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283716 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3717 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503718 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3719 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013720 ASSERT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033721
Matt Menke9fa17d52019-03-25 19:12:263722 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3723 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3724 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3725 TestGroupId("a")));
3726 EXPECT_EQ(0u,
3727 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393728 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menke9fa17d52019-03-25 19:12:263729 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033730
Matt Menkef09e64c2019-04-23 22:16:283731 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
3732 NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033733
Matt Menke9fa17d52019-03-25 19:12:263734 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3735 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3736 TestGroupId("a")));
3737 EXPECT_EQ(1u,
3738 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393739 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menke9fa17d52019-03-25 19:12:263740 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033741}
3742
3743TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronous) {
3744 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3745 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3746
Matt Menkef09e64c2019-04-23 22:16:283747 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt,
3748 kDefaultMaxSocketsPerGroup, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033749
Matt Menke9fa17d52019-03-25 19:12:263750 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3751 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3752 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3753 TestGroupId("a")));
3754 EXPECT_EQ(0u,
3755 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Raul Tambre8335a6d2019-02-21 16:57:433756 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
Matt Menkec6b3edf72019-03-19 17:00:393757 static_cast<int>(pool_->IdleSocketCountInGroup(TestGroupId("a"))));
[email protected]2c2bef152010-10-13 00:55:033758
Matt Menkef09e64c2019-04-23 22:16:283759 pool_->RequestSockets(TestGroupId("b"), params_, base::nullopt,
3760 kDefaultMaxSocketsPerGroup, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033761
Matt Menke9fa17d52019-03-25 19:12:263762 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
3763 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3764 TestGroupId("b")));
3765 EXPECT_EQ(0u,
3766 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("b")));
Raul Tambre8335a6d2019-02-21 16:57:433767 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
Matt Menkec6b3edf72019-03-19 17:00:393768 static_cast<int>(pool_->IdleSocketCountInGroup(TestGroupId("b"))));
[email protected]2c2bef152010-10-13 00:55:033769}
3770
[email protected]3c819f522010-12-02 02:03:123771TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronousError) {
3772 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3773 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3774
Matt Menkef09e64c2019-04-23 22:16:283775 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt,
3776 kDefaultMaxSocketsPerGroup, NetLogWithSource());
[email protected]3c819f522010-12-02 02:03:123777
Matt Menke9fa17d52019-03-25 19:12:263778 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
[email protected]fd2e53e2011-01-14 20:40:523779
3780 connect_job_factory_->set_job_type(
3781 TestConnectJob::kMockAdditionalErrorStateJob);
Matt Menkef09e64c2019-04-23 22:16:283782 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt,
3783 kDefaultMaxSocketsPerGroup, NetLogWithSource());
[email protected]fd2e53e2011-01-14 20:40:523784
Matt Menke9fa17d52019-03-25 19:12:263785 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
[email protected]3c819f522010-12-02 02:03:123786}
3787
[email protected]8159a1c2012-06-07 00:00:103788TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) {
[email protected]2c2bef152010-10-13 00:55:033789 CreatePool(4, 4);
Lily Chenecebf932018-11-02 17:15:433790 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
[email protected]2c2bef152010-10-13 00:55:033791
Matt Menkef09e64c2019-04-23 22:16:283792 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
3793 NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033794
Matt Menke9fa17d52019-03-25 19:12:263795 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3796 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3797 EXPECT_EQ(2u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3798 TestGroupId("a")));
3799 EXPECT_EQ(2u,
3800 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3801 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393802 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033803
Matt Menkef09e64c2019-04-23 22:16:283804 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
3805 NetLogWithSource());
Matt Menke9fa17d52019-03-25 19:12:263806 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3807 EXPECT_EQ(2u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3808 TestGroupId("a")));
3809 EXPECT_EQ(2u,
3810 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3811 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393812 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033813
3814 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523815 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203816 EXPECT_EQ(
3817 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283818 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3819 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503820 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3821 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:433822
3823 client_socket_factory_.SignalJob(0);
3824 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3825
Matt Menke9fa17d52019-03-25 19:12:263826 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3827 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3828 TestGroupId("a")));
3829 EXPECT_EQ(1u,
3830 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3831 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393832 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033833
3834 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523835 TestCompletionCallback callback2;
Lily Chenecebf932018-11-02 17:15:433836 EXPECT_EQ(
3837 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283838 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3839 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503840 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3841 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:433842 client_socket_factory_.SignalJob(0);
3843 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033844
Matt Menke9fa17d52019-03-25 19:12:263845 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3846 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3847 TestGroupId("a")));
3848 EXPECT_EQ(0u,
3849 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3850 EXPECT_EQ(2, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393851 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]8159a1c2012-06-07 00:00:103852
[email protected]2c2bef152010-10-13 00:55:033853 handle1.Reset();
3854 handle2.Reset();
3855
Matt Menke9fa17d52019-03-25 19:12:263856 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3857 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3858 TestGroupId("a")));
3859 EXPECT_EQ(0u,
3860 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3861 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393862 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033863
Matt Menkef09e64c2019-04-23 22:16:283864 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
3865 NetLogWithSource());
Matt Menke9fa17d52019-03-25 19:12:263866 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3867 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3868 TestGroupId("a")));
3869 EXPECT_EQ(0u,
3870 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3871 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393872 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033873}
3874
3875TEST_F(ClientSocketPoolBaseTest, RequestSocketsDifferentNumSockets) {
3876 CreatePool(4, 4);
3877 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3878
Matt Menkef09e64c2019-04-23 22:16:283879 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 1,
3880 NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033881
Matt Menke9fa17d52019-03-25 19:12:263882 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3883 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3884 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3885 TestGroupId("a")));
3886 EXPECT_EQ(1u,
3887 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393888 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033889
Matt Menkef09e64c2019-04-23 22:16:283890 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
3891 NetLogWithSource());
Matt Menke9fa17d52019-03-25 19:12:263892 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3893 EXPECT_EQ(2u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3894 TestGroupId("a")));
3895 EXPECT_EQ(2u,
3896 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393897 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033898
Matt Menkef09e64c2019-04-23 22:16:283899 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 3,
3900 NetLogWithSource());
Matt Menke9fa17d52019-03-25 19:12:263901 EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3902 EXPECT_EQ(3u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3903 TestGroupId("a")));
3904 EXPECT_EQ(3u,
3905 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393906 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033907
Matt Menkef09e64c2019-04-23 22:16:283908 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 1,
3909 NetLogWithSource());
Matt Menke9fa17d52019-03-25 19:12:263910 EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3911 EXPECT_EQ(3u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3912 TestGroupId("a")));
3913 EXPECT_EQ(3u,
3914 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393915 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033916}
3917
3918TEST_F(ClientSocketPoolBaseTest, PreconnectJobsTakenByNormalRequests) {
3919 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
Lily Chenecebf932018-11-02 17:15:433920 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
[email protected]2c2bef152010-10-13 00:55:033921
Matt Menkef09e64c2019-04-23 22:16:283922 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 1,
3923 NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033924
Matt Menke9fa17d52019-03-25 19:12:263925 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3926 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3927 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3928 TestGroupId("a")));
3929 EXPECT_EQ(1u,
3930 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393931 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033932
3933 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523934 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203935 EXPECT_EQ(
3936 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:283937 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3938 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503939 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3940 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033941
Matt Menke9fa17d52019-03-25 19:12:263942 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3943 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3944 TestGroupId("a")));
3945 EXPECT_EQ(0u,
3946 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393947 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033948
Lily Chenecebf932018-11-02 17:15:433949 client_socket_factory_.SignalJobs();
3950 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3951
Matt Menke9fa17d52019-03-25 19:12:263952 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3953 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3954 TestGroupId("a")));
3955 EXPECT_EQ(0u,
3956 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393957 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menke9fa17d52019-03-25 19:12:263958 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033959
[email protected]0dc88b32014-03-26 20:12:283960 // Make sure if a preconnected socket is not fully connected when a request
[email protected]034df0f32013-01-07 23:17:483961 // starts, it has a connect start time.
3962 TestLoadTimingInfoConnectedNotReused(handle1);
[email protected]2c2bef152010-10-13 00:55:033963 handle1.Reset();
3964
Matt Menkec6b3edf72019-03-19 17:00:393965 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033966}
3967
[email protected]034df0f32013-01-07 23:17:483968// Checks that fully connected preconnect jobs have no connect times, and are
3969// marked as reused.
3970TEST_F(ClientSocketPoolBaseTest, ConnectedPreconnectJobsHaveNoConnectTimes) {
3971 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3972 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
Matt Menkef09e64c2019-04-23 22:16:283973 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 1,
3974 NetLogWithSource());
[email protected]034df0f32013-01-07 23:17:483975
Matt Menke9fa17d52019-03-25 19:12:263976 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3977 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3978 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3979 TestGroupId("a")));
3980 EXPECT_EQ(0u,
3981 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:393982 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]034df0f32013-01-07 23:17:483983
3984 ClientSocketHandle handle;
3985 TestCompletionCallback callback;
Matt Menkec6b3edf72019-03-19 17:00:393986 EXPECT_EQ(OK, handle.Init(
Matt Menkef09e64c2019-04-23 22:16:283987 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3988 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menkec6b3edf72019-03-19 17:00:393989 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3990 pool_.get(), NetLogWithSource()));
[email protected]034df0f32013-01-07 23:17:483991
3992 // Make sure the idle socket was used.
Matt Menkec6b3edf72019-03-19 17:00:393993 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]034df0f32013-01-07 23:17:483994
3995 TestLoadTimingInfoConnectedReused(handle);
3996 handle.Reset();
3997 TestLoadTimingInfoNotConnected(handle);
3998}
3999
[email protected]dcbe168a2010-12-02 03:14:464000// http://crbug.com/64940 regression test.
4001TEST_F(ClientSocketPoolBaseTest, PreconnectClosesIdleSocketRemovesGroup) {
4002 const int kMaxTotalSockets = 3;
4003 const int kMaxSocketsPerGroup = 2;
4004 CreatePool(kMaxTotalSockets, kMaxSocketsPerGroup);
Lily Chenecebf932018-11-02 17:15:434005 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
[email protected]dcbe168a2010-12-02 03:14:464006
Matt Menkef6edce752019-03-19 17:21:564007 // Note that group id ordering matters here. "a" comes before "b", so
[email protected]dcbe168a2010-12-02 03:14:464008 // CloseOneIdleSocket() will try to close "a"'s idle socket.
4009
4010 // Set up one idle socket in "a".
4011 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:524012 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:204013 EXPECT_EQ(
4014 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284015 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4016 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504017 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4018 pool_.get(), NetLogWithSource()));
Matt Menke9fa17d52019-03-25 19:12:264019 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
4020 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4021 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4022 TestGroupId("a")));
4023 EXPECT_EQ(0u,
4024 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394025 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]dcbe168a2010-12-02 03:14:464026
Lily Chenecebf932018-11-02 17:15:434027 client_socket_factory_.SignalJobs();
robpercival214763f2016-07-01 23:27:014028 ASSERT_THAT(callback1.WaitForResult(), IsOk());
Matt Menke9fa17d52019-03-25 19:12:264029 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4030 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4031 TestGroupId("a")));
4032 EXPECT_EQ(0u,
4033 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4034 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434035
[email protected]dcbe168a2010-12-02 03:14:464036 handle1.Reset();
Matt Menkec6b3edf72019-03-19 17:00:394037 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]dcbe168a2010-12-02 03:14:464038
4039 // Set up two active sockets in "b".
4040 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:524041 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:204042 EXPECT_EQ(
4043 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284044 handle1.Init(TestGroupId("b"), params_, base::nullopt, DEFAULT_PRIORITY,
4045 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504046 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4047 pool_.get(), NetLogWithSource()));
tfarina428341112016-09-22 13:38:204048 EXPECT_EQ(
4049 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284050 handle2.Init(TestGroupId("b"), params_, base::nullopt, DEFAULT_PRIORITY,
4051 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504052 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4053 pool_.get(), NetLogWithSource()));
[email protected]dcbe168a2010-12-02 03:14:464054
Matt Menke9fa17d52019-03-25 19:12:264055 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("b")));
4056 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
4057 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4058 TestGroupId("b")));
4059 EXPECT_EQ(0u,
4060 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("b")));
Matt Menkec6b3edf72019-03-19 17:00:394061 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("b")));
Lily Chenecebf932018-11-02 17:15:434062
4063 client_socket_factory_.SignalJobs();
robpercival214763f2016-07-01 23:27:014064 ASSERT_THAT(callback1.WaitForResult(), IsOk());
4065 ASSERT_THAT(callback2.WaitForResult(), IsOk());
Matt Menkec6b3edf72019-03-19 17:00:394066 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("b")));
Matt Menke9fa17d52019-03-25 19:12:264067 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4068 TestGroupId("b")));
4069 EXPECT_EQ(0u,
4070 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("b")));
4071 EXPECT_EQ(2, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("b")));
[email protected]dcbe168a2010-12-02 03:14:464072
4073 // Now we have 1 idle socket in "a" and 2 active sockets in "b". This means
4074 // we've maxed out on sockets, since we set |kMaxTotalSockets| to 3.
4075 // Requesting 2 preconnected sockets for "a" should fail to allocate any more
4076 // sockets for "a", and "b" should still have 2 active sockets.
4077
Matt Menkef09e64c2019-04-23 22:16:284078 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
4079 NetLogWithSource());
Matt Menke9fa17d52019-03-25 19:12:264080 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4081 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4082 TestGroupId("a")));
4083 EXPECT_EQ(0u,
4084 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394085 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menke9fa17d52019-03-25 19:12:264086 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
4087 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
4088 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4089 TestGroupId("b")));
4090 EXPECT_EQ(0u,
4091 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("b")));
Matt Menkec6b3edf72019-03-19 17:00:394092 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("b")));
Matt Menke9fa17d52019-03-25 19:12:264093 EXPECT_EQ(2, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("b")));
[email protected]dcbe168a2010-12-02 03:14:464094
4095 // Now release the 2 active sockets for "b". This will give us 1 idle socket
4096 // in "a" and 2 idle sockets in "b". Requesting 2 preconnected sockets for
4097 // "a" should result in closing 1 for "b".
4098 handle1.Reset();
4099 handle2.Reset();
Matt Menkec6b3edf72019-03-19 17:00:394100 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(TestGroupId("b")));
Matt Menke9fa17d52019-03-25 19:12:264101 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("b")));
[email protected]dcbe168a2010-12-02 03:14:464102
Matt Menkef09e64c2019-04-23 22:16:284103 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
4104 NetLogWithSource());
Matt Menke9fa17d52019-03-25 19:12:264105 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4106 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4107 TestGroupId("a")));
4108 EXPECT_EQ(1u,
4109 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394110 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menke9fa17d52019-03-25 19:12:264111 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
4112 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
4113 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4114 TestGroupId("b")));
4115 EXPECT_EQ(0u,
4116 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("b")));
Matt Menkec6b3edf72019-03-19 17:00:394117 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("b")));
Matt Menke9fa17d52019-03-25 19:12:264118 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("b")));
[email protected]dcbe168a2010-12-02 03:14:464119}
4120
[email protected]b7b8be42011-07-12 12:46:414121TEST_F(ClientSocketPoolBaseTest, PreconnectWithoutBackupJob) {
Matt Menke9fa17d52019-03-25 19:12:264122 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
4123 true /* enable_backup_connect_jobs */);
[email protected]a9fc8fc2011-05-10 02:41:074124
4125 // Make the ConnectJob hang until it times out, shorten the timeout.
4126 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4127 connect_job_factory_->set_timeout_duration(
4128 base::TimeDelta::FromMilliseconds(500));
Matt Menkef09e64c2019-04-23 22:16:284129 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 1,
4130 NetLogWithSource());
Matt Menke9fa17d52019-03-25 19:12:264131 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4132 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4133 TestGroupId("a")));
4134 EXPECT_EQ(1u,
4135 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394136 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]a9fc8fc2011-05-10 02:41:074137
[email protected]b7b8be42011-07-12 12:46:414138 // Verify the backup timer doesn't create a backup job, by making
4139 // the backup job a pending job instead of a waiting job, so it
4140 // *would* complete if it were created.
[email protected]a9fc8fc2011-05-10 02:41:074141 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
skyostil4891b25b2015-06-11 11:43:454142 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
Gabriel Charetteea918012018-05-16 11:53:444143 FROM_HERE, base::RunLoop::QuitCurrentWhenIdleClosureDeprecated(),
[email protected]2da659e2013-05-23 20:51:344144 base::TimeDelta::FromSeconds(1));
fdoray5eeb7642016-06-22 16:11:284145 base::RunLoop().Run();
Matt Menke9fa17d52019-03-25 19:12:264146 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
[email protected]a9fc8fc2011-05-10 02:41:074147}
4148
[email protected]b7b8be42011-07-12 12:46:414149TEST_F(ClientSocketPoolBaseTest, PreconnectWithBackupJob) {
Matt Menke9fa17d52019-03-25 19:12:264150 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
4151 true /* enable_backup_connect_jobs */);
[email protected]a9fc8fc2011-05-10 02:41:074152
4153 // Make the ConnectJob hang forever.
4154 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
Matt Menkef09e64c2019-04-23 22:16:284155 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 1,
4156 NetLogWithSource());
Matt Menke9fa17d52019-03-25 19:12:264157 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4158 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4159 TestGroupId("a")));
4160 EXPECT_EQ(1u,
4161 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394162 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
fdoray5eeb7642016-06-22 16:11:284163 base::RunLoop().RunUntilIdle();
[email protected]a9fc8fc2011-05-10 02:41:074164
4165 // Make the backup job be a pending job, so it completes normally.
4166 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
4167 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:524168 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:504169 EXPECT_EQ(
4170 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284171 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4172 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4173 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
4174 pool_.get(), NetLogWithSource()));
[email protected]b7b8be42011-07-12 12:46:414175 // Timer has started, but the backup connect job shouldn't be created yet.
Matt Menke9fa17d52019-03-25 19:12:264176 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4177 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4178 TestGroupId("a")));
4179 EXPECT_EQ(0u,
4180 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394181 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menke9fa17d52019-03-25 19:12:264182 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
robpercival214763f2016-07-01 23:27:014183 ASSERT_THAT(callback.WaitForResult(), IsOk());
[email protected]a9fc8fc2011-05-10 02:41:074184
4185 // The hung connect job should still be there, but everything else should be
4186 // complete.
Matt Menke9fa17d52019-03-25 19:12:264187 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4188 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4189 TestGroupId("a")));
4190 EXPECT_EQ(1u,
4191 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394192 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menke9fa17d52019-03-25 19:12:264193 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
[email protected]a9fc8fc2011-05-10 02:41:074194}
4195
[email protected]0dc88b32014-03-26 20:12:284196// Tests that a preconnect that starts out with unread data can still be used.
4197// http://crbug.com/334467
4198TEST_F(ClientSocketPoolBaseTest, PreconnectWithUnreadData) {
4199 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4200 connect_job_factory_->set_job_type(TestConnectJob::kMockUnreadDataJob);
4201
Matt Menkef09e64c2019-04-23 22:16:284202 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 1,
4203 NetLogWithSource());
[email protected]0dc88b32014-03-26 20:12:284204
Matt Menke9fa17d52019-03-25 19:12:264205 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
4206 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4207 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4208 TestGroupId("a")));
4209 EXPECT_EQ(0u,
4210 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394211 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]0dc88b32014-03-26 20:12:284212
4213 // Fail future jobs to be sure that handle receives the preconnected socket
4214 // rather than closing it and making a new one.
4215 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
4216 ClientSocketHandle handle;
4217 TestCompletionCallback callback;
Matt Menkec6b3edf72019-03-19 17:00:394218 EXPECT_EQ(OK, handle.Init(
Matt Menkef09e64c2019-04-23 22:16:284219 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4220 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menkec6b3edf72019-03-19 17:00:394221 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
4222 pool_.get(), NetLogWithSource()));
[email protected]0dc88b32014-03-26 20:12:284223
Matt Menke9fa17d52019-03-25 19:12:264224 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
4225 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4226 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4227 TestGroupId("a")));
4228 EXPECT_EQ(0u,
4229 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394230 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menke9fa17d52019-03-25 19:12:264231 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
[email protected]0dc88b32014-03-26 20:12:284232
4233 // Drain the pending read.
Raul Tambre94493c652019-03-11 17:18:354234 EXPECT_EQ(1, handle.socket()->Read(nullptr, 1, CompletionOnceCallback()));
[email protected]0dc88b32014-03-26 20:12:284235
4236 TestLoadTimingInfoConnectedReused(handle);
4237 handle.Reset();
4238
4239 // The socket should be usable now that it's idle again.
Matt Menkec6b3edf72019-03-19 17:00:394240 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]0dc88b32014-03-26 20:12:284241}
4242
Lily Chenecebf932018-11-02 17:15:434243TEST_F(ClientSocketPoolBaseTest, RequestGetsAssignedJob) {
4244 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4245 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4246
4247 ClientSocketHandle handle1;
4248 TestCompletionCallback callback1;
4249 EXPECT_EQ(
4250 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284251 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4252 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504253 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4254 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434255
Matt Menke9fa17d52019-03-25 19:12:264256 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4257 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4258 TestGroupId("a")));
4259 EXPECT_EQ(0u,
4260 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394261 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434262
Matt Menkec6b3edf72019-03-19 17:00:394263 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4264 &handle1));
Lily Chenecebf932018-11-02 17:15:434265}
4266
4267TEST_F(ClientSocketPoolBaseTest, MultipleRequestsGetAssignedJobs) {
4268 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4269 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4270
4271 ClientSocketHandle handle1;
4272 TestCompletionCallback callback1;
4273 EXPECT_EQ(
4274 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284275 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4276 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504277 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4278 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434279
Matt Menke9fa17d52019-03-25 19:12:264280 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4281 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4282 TestGroupId("a")));
4283 EXPECT_EQ(0u,
4284 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394285 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434286
4287 ClientSocketHandle handle2;
4288 TestCompletionCallback callback2;
4289 EXPECT_EQ(
4290 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284291 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4292 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504293 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4294 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434295
Matt Menke9fa17d52019-03-25 19:12:264296 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4297 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4298 TestGroupId("a")));
4299 EXPECT_EQ(0u,
4300 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394301 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434302
Matt Menkec6b3edf72019-03-19 17:00:394303 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4304 &handle1));
4305 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4306 &handle2));
Lily Chenecebf932018-11-02 17:15:434307
4308 // One job completes. The other request should still have its job.
4309 client_socket_factory_.SignalJob(0);
4310 EXPECT_THAT(callback1.WaitForResult(), IsOk());
4311
Matt Menke9fa17d52019-03-25 19:12:264312 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4313 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4314 TestGroupId("a")));
4315 EXPECT_EQ(0u,
4316 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4317 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394318 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434319
Matt Menkec6b3edf72019-03-19 17:00:394320 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4321 &handle2));
Lily Chenecebf932018-11-02 17:15:434322}
4323
4324TEST_F(ClientSocketPoolBaseTest, PreconnectJobGetsAssignedToRequest) {
4325 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4326 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4327
Matt Menkef09e64c2019-04-23 22:16:284328 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 1,
4329 NetLogWithSource());
Lily Chenecebf932018-11-02 17:15:434330
Matt Menke9fa17d52019-03-25 19:12:264331 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
4332 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4333 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4334 TestGroupId("a")));
4335 EXPECT_EQ(1u,
4336 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394337 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434338
4339 ClientSocketHandle handle1;
4340 TestCompletionCallback callback1;
4341 EXPECT_EQ(
4342 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284343 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4344 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504345 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4346 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434347
Matt Menke9fa17d52019-03-25 19:12:264348 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4349 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4350 TestGroupId("a")));
4351 EXPECT_EQ(0u,
4352 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394353 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434354
Matt Menkec6b3edf72019-03-19 17:00:394355 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4356 &handle1));
Lily Chenecebf932018-11-02 17:15:434357}
4358
4359TEST_F(ClientSocketPoolBaseTest, HigherPriorityRequestStealsJob) {
4360 CreatePool(kDefaultMaxSockets, 1);
4361 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4362
4363 ClientSocketHandle handle1;
4364 TestCompletionCallback callback1;
4365 EXPECT_EQ(
4366 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284367 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4368 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504369 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4370 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434371
Matt Menke9fa17d52019-03-25 19:12:264372 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4373 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4374 TestGroupId("a")));
4375 EXPECT_EQ(0u,
4376 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394377 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434378
Matt Menkec6b3edf72019-03-19 17:00:394379 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4380 &handle1));
Lily Chenecebf932018-11-02 17:15:434381
4382 // Insert a higher priority request
4383 ClientSocketHandle handle2;
4384 TestCompletionCallback callback2;
4385 EXPECT_EQ(
4386 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284387 handle2.Init(TestGroupId("a"), params_, base::nullopt, HIGHEST,
4388 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504389 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4390 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434391
Matt Menke9fa17d52019-03-25 19:12:264392 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4393 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4394 TestGroupId("a")));
4395 EXPECT_EQ(0u,
4396 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394397 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434398
4399 // The highest priority request should steal the job from the default priority
4400 // request.
Matt Menkec6b3edf72019-03-19 17:00:394401 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4402 &handle2));
4403 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4404 &handle1));
Lily Chenecebf932018-11-02 17:15:434405}
4406
4407TEST_F(ClientSocketPoolBaseTest, RequestStealsJobFromLowestRequestWithJob) {
4408 CreatePool(3, 3);
4409 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4410
4411 ClientSocketHandle handle_lowest;
4412 TestCompletionCallback callback_lowest;
Matt Menkef09e64c2019-04-23 22:16:284413 EXPECT_EQ(
4414 ERR_IO_PENDING,
4415 handle_lowest.Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
4416 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4417 callback_lowest.callback(),
4418 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4419 NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434420
Matt Menke9fa17d52019-03-25 19:12:264421 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4422 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4423 TestGroupId("a")));
4424 EXPECT_EQ(0u,
4425 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394426 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434427
4428 ClientSocketHandle handle_highest;
4429 TestCompletionCallback callback_highest;
Matt Menkef09e64c2019-04-23 22:16:284430 EXPECT_EQ(
4431 ERR_IO_PENDING,
4432 handle_highest.Init(TestGroupId("a"), params_, base::nullopt, HIGHEST,
4433 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4434 callback_highest.callback(),
4435 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4436 NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434437
Matt Menke9fa17d52019-03-25 19:12:264438 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4439 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4440 TestGroupId("a")));
4441 EXPECT_EQ(0u,
4442 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394443 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434444
4445 ClientSocketHandle handle_low;
4446 TestCompletionCallback callback_low;
4447 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284448 handle_low.Init(
4449 TestGroupId("a"), params_, base::nullopt, LOW, SocketTag(),
4450 ClientSocketPool::RespectLimits::ENABLED,
4451 callback_low.callback(), ClientSocketPool::ProxyAuthCallback(),
4452 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434453
Matt Menke9fa17d52019-03-25 19:12:264454 EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4455 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4456 TestGroupId("a")));
4457 EXPECT_EQ(0u,
4458 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394459 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434460
4461 ClientSocketHandle handle_lowest2;
4462 TestCompletionCallback callback_lowest2;
Matt Menkef09e64c2019-04-23 22:16:284463 EXPECT_EQ(
4464 ERR_IO_PENDING,
4465 handle_lowest2.Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
4466 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4467 callback_lowest2.callback(),
4468 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4469 NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434470
Matt Menke9fa17d52019-03-25 19:12:264471 EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4472 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4473 TestGroupId("a")));
4474 EXPECT_EQ(0u,
4475 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394476 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434477
4478 // The top three requests in the queue should have jobs.
Matt Menkec6b3edf72019-03-19 17:00:394479 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4480 &handle_highest));
4481 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4482 &handle_low));
4483 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4484 &handle_lowest));
4485 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(
4486 TestGroupId("a"), &handle_lowest2));
Lily Chenecebf932018-11-02 17:15:434487
4488 // Add another request with medium priority. It should steal the job from the
4489 // lowest priority request with a job.
4490 ClientSocketHandle handle_medium;
4491 TestCompletionCallback callback_medium;
Matt Menkef09e64c2019-04-23 22:16:284492 EXPECT_EQ(
4493 ERR_IO_PENDING,
4494 handle_medium.Init(TestGroupId("a"), params_, base::nullopt, MEDIUM,
4495 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4496 callback_medium.callback(),
4497 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4498 NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434499
Matt Menke9fa17d52019-03-25 19:12:264500 EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4501 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4502 TestGroupId("a")));
4503 EXPECT_EQ(0u,
4504 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394505 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4506 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4507 &handle_highest));
4508 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4509 &handle_medium));
4510 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4511 &handle_low));
4512 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4513 &handle_lowest));
4514 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(
4515 TestGroupId("a"), &handle_lowest2));
Lily Chenecebf932018-11-02 17:15:434516}
4517
4518TEST_F(ClientSocketPoolBaseTest, ReprioritizeRequestStealsJob) {
4519 CreatePool(kDefaultMaxSockets, 1);
4520 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4521
4522 ClientSocketHandle handle1;
4523 TestCompletionCallback callback1;
4524 EXPECT_EQ(
4525 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284526 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4527 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504528 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4529 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434530
Matt Menke9fa17d52019-03-25 19:12:264531 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4532 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4533 TestGroupId("a")));
4534 EXPECT_EQ(0u,
4535 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394536 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434537
4538 ClientSocketHandle handle2;
4539 TestCompletionCallback callback2;
4540 EXPECT_EQ(
4541 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284542 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4543 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504544 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4545 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434546
Matt Menke9fa17d52019-03-25 19:12:264547 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4548 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4549 TestGroupId("a")));
4550 EXPECT_EQ(0u,
4551 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394552 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434553
4554 // The second request doesn't get a job because we are at the limit.
Matt Menkec6b3edf72019-03-19 17:00:394555 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4556 &handle1));
4557 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4558 &handle2));
Lily Chenecebf932018-11-02 17:15:434559
4560 // Reprioritizing the second request places it above the first, and it steals
4561 // the job from the first request.
Matt Menkec6b3edf72019-03-19 17:00:394562 pool_->SetPriority(TestGroupId("a"), &handle2, HIGHEST);
4563 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4564 &handle2));
4565 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4566 &handle1));
Lily Chenecebf932018-11-02 17:15:434567}
4568
4569TEST_F(ClientSocketPoolBaseTest, CancelRequestReassignsJob) {
4570 CreatePool(kDefaultMaxSockets, 1);
4571 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4572
4573 ClientSocketHandle handle1;
4574 TestCompletionCallback callback1;
4575 EXPECT_EQ(
4576 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284577 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4578 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504579 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4580 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434581
Matt Menke9fa17d52019-03-25 19:12:264582 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4583 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4584 TestGroupId("a")));
4585 EXPECT_EQ(0u,
4586 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394587 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434588
Matt Menkec6b3edf72019-03-19 17:00:394589 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4590 &handle1));
Lily Chenecebf932018-11-02 17:15:434591
4592 ClientSocketHandle handle2;
4593 TestCompletionCallback callback2;
4594 EXPECT_EQ(
4595 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284596 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4597 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504598 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4599 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434600
Matt Menke9fa17d52019-03-25 19:12:264601 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4602 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4603 TestGroupId("a")));
4604 EXPECT_EQ(0u,
4605 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394606 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434607
4608 // The second request doesn't get a job because we are the limit.
Matt Menkec6b3edf72019-03-19 17:00:394609 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4610 &handle1));
4611 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4612 &handle2));
Lily Chenecebf932018-11-02 17:15:434613
4614 // The second request should get a job upon cancelling the first request.
4615 handle1.Reset();
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
Matt Menkec6b3edf72019-03-19 17:00:394623 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4624 &handle2));
Lily Chenecebf932018-11-02 17:15:434625}
4626
4627TEST_F(ClientSocketPoolBaseTest, JobCompletionReassignsJob) {
4628 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4629 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4630
4631 ClientSocketHandle handle1;
4632 TestCompletionCallback callback1;
4633 EXPECT_EQ(
4634 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284635 handle1.Init(TestGroupId("a"), params_, base::nullopt, HIGHEST,
4636 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504637 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4638 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434639
Matt Menke9fa17d52019-03-25 19:12:264640 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4641 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4642 TestGroupId("a")));
4643 EXPECT_EQ(0u,
4644 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394645 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434646
4647 ClientSocketHandle handle2;
4648 TestCompletionCallback callback2;
4649 EXPECT_EQ(
4650 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284651 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4652 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504653 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4654 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434655
Matt Menke9fa17d52019-03-25 19:12:264656 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4657 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4658 TestGroupId("a")));
4659 EXPECT_EQ(0u,
4660 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394661 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434662
Matt Menkec6b3edf72019-03-19 17:00:394663 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4664 &handle1));
4665 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4666 &handle2));
Lily Chenecebf932018-11-02 17:15:434667
4668 // The lower-priority job completes first. The higher-priority request should
4669 // get the socket, and the lower-priority request should get the remaining
4670 // job.
4671 client_socket_factory_.SignalJob(1);
4672 EXPECT_THAT(callback1.WaitForResult(), IsOk());
Matt Menke9fa17d52019-03-25 19:12:264673 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4674 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4675 TestGroupId("a")));
4676 EXPECT_EQ(0u,
4677 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4678 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:394679 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434680 EXPECT_TRUE(handle1.socket());
Matt Menkec6b3edf72019-03-19 17:00:394681 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4682 &handle2));
Lily Chenecebf932018-11-02 17:15:434683}
4684
[email protected]043b68c82013-08-22 23:41:524685class MockLayeredPool : public HigherLayeredPool {
[email protected]58e562f2013-04-22 17:32:204686 public:
Matt Menke9fa17d52019-03-25 19:12:264687 MockLayeredPool(TransportClientSocketPool* pool,
Matt Menkec6b3edf72019-03-19 17:00:394688 const ClientSocketPool::GroupId& group_id)
4689 : pool_(pool), group_id_(group_id), can_release_connection_(true) {
[email protected]043b68c82013-08-22 23:41:524690 pool_->AddHigherLayeredPool(this);
[email protected]58e562f2013-04-22 17:32:204691 }
4692
Daniel Cheng4496d0822018-04-26 21:52:154693 ~MockLayeredPool() override { pool_->RemoveHigherLayeredPool(this); }
[email protected]58e562f2013-04-22 17:32:204694
Matt Menke9fa17d52019-03-25 19:12:264695 int RequestSocket(TransportClientSocketPool* pool) {
Matt Menke28ac03e2019-02-25 22:25:504696 return handle_.Init(
Matt Menke870e19ab2019-04-23 16:23:034697 group_id_, ClientSocketPool::SocketParams::CreateForHttpForTesting(),
Matt Menkef09e64c2019-04-23 22:16:284698 base::nullopt, DEFAULT_PRIORITY, SocketTag(),
4699 ClientSocketPool::RespectLimits::ENABLED, callback_.callback(),
4700 ClientSocketPool::ProxyAuthCallback(), pool, NetLogWithSource());
[email protected]58e562f2013-04-22 17:32:204701 }
4702
Matt Menke9fa17d52019-03-25 19:12:264703 int RequestSocketWithoutLimits(TransportClientSocketPool* pool) {
Matt Menke28ac03e2019-02-25 22:25:504704 return handle_.Init(
Matt Menke870e19ab2019-04-23 16:23:034705 group_id_, ClientSocketPool::SocketParams::CreateForHttpForTesting(),
Matt Menkef09e64c2019-04-23 22:16:284706 base::nullopt, MAXIMUM_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:504707 ClientSocketPool::RespectLimits::DISABLED, callback_.callback(),
4708 ClientSocketPool::ProxyAuthCallback(), pool, NetLogWithSource());
[email protected]58e562f2013-04-22 17:32:204709 }
4710
4711 bool ReleaseOneConnection() {
4712 if (!handle_.is_initialized() || !can_release_connection_) {
4713 return false;
4714 }
4715 handle_.socket()->Disconnect();
4716 handle_.Reset();
4717 return true;
4718 }
4719
4720 void set_can_release_connection(bool can_release_connection) {
4721 can_release_connection_ = can_release_connection;
4722 }
4723
4724 MOCK_METHOD0(CloseOneIdleConnection, bool());
4725
4726 private:
Matt Menke9fa17d52019-03-25 19:12:264727 TransportClientSocketPool* const pool_;
[email protected]58e562f2013-04-22 17:32:204728 ClientSocketHandle handle_;
4729 TestCompletionCallback callback_;
Matt Menkec6b3edf72019-03-19 17:00:394730 const ClientSocketPool::GroupId group_id_;
[email protected]58e562f2013-04-22 17:32:204731 bool can_release_connection_;
4732};
4733
[email protected]58e562f2013-04-22 17:32:204734// Tests the basic case of closing an idle socket in a higher layered pool when
4735// a new request is issued and the lower layer pool is stalled.
4736TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsHeldByLayeredPoolWhenNeeded) {
4737 CreatePool(1, 1);
4738 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4739
Matt Menkec6b3edf72019-03-19 17:00:394740 MockLayeredPool mock_layered_pool(pool_.get(), TestGroupId("foo"));
robpercival214763f2016-07-01 23:27:014741 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:204742 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4743 .WillOnce(Invoke(&mock_layered_pool,
4744 &MockLayeredPool::ReleaseOneConnection));
4745 ClientSocketHandle handle;
4746 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:504747 EXPECT_EQ(
4748 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284749 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4750 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4751 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
4752 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:014753 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204754}
4755
Matt Menke833678642019-03-05 22:05:514756// Tests the case that trying to close an idle socket in a higher layered pool
4757// fails.
4758TEST_F(ClientSocketPoolBaseTest,
4759 CloseIdleSocketsHeldByLayeredPoolWhenNeededFails) {
4760 CreatePool(1, 1);
4761 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4762
Matt Menkec6b3edf72019-03-19 17:00:394763 MockLayeredPool mock_layered_pool(pool_.get(), TestGroupId("foo"));
Matt Menke833678642019-03-05 22:05:514764 mock_layered_pool.set_can_release_connection(false);
4765 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
4766 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4767 .WillOnce(Invoke(&mock_layered_pool,
4768 &MockLayeredPool::ReleaseOneConnection));
4769 ClientSocketHandle handle;
4770 TestCompletionCallback callback;
4771 EXPECT_EQ(
4772 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284773 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4774 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4775 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
4776 pool_.get(), NetLogWithSource()));
Matt Menke833678642019-03-05 22:05:514777 base::RunLoop().RunUntilIdle();
4778 EXPECT_FALSE(callback.have_result());
4779}
4780
[email protected]58e562f2013-04-22 17:32:204781// Same as above, but the idle socket is in the same group as the stalled
4782// socket, and closes the only other request in its group when closing requests
4783// in higher layered pools. This generally shouldn't happen, but it may be
4784// possible if a higher level pool issues a request and the request is
4785// subsequently cancelled. Even if it's not possible, best not to crash.
4786TEST_F(ClientSocketPoolBaseTest,
4787 CloseIdleSocketsHeldByLayeredPoolWhenNeededSameGroup) {
4788 CreatePool(2, 2);
4789 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4790
4791 // Need a socket in another group for the pool to be stalled (If a group
4792 // has the maximum number of connections already, it's not stalled).
4793 ClientSocketHandle handle1;
4794 TestCompletionCallback callback1;
Matt Menkef09e64c2019-04-23 22:16:284795 EXPECT_EQ(OK, handle1.Init(TestGroupId("group1"), params_, base::nullopt,
4796 DEFAULT_PRIORITY, SocketTag(),
4797 ClientSocketPool::RespectLimits::ENABLED,
4798 callback1.callback(),
4799 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4800 NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:204801
Matt Menkec6b3edf72019-03-19 17:00:394802 MockLayeredPool mock_layered_pool(pool_.get(), TestGroupId("group2"));
robpercival214763f2016-07-01 23:27:014803 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:204804 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4805 .WillOnce(Invoke(&mock_layered_pool,
4806 &MockLayeredPool::ReleaseOneConnection));
4807 ClientSocketHandle handle;
4808 TestCompletionCallback callback2;
Matt Menkef09e64c2019-04-23 22:16:284809 EXPECT_EQ(ERR_IO_PENDING,
4810 handle.Init(
4811 TestGroupId("group2"), params_, base::nullopt, DEFAULT_PRIORITY,
4812 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4813 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4814 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:014815 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204816}
4817
4818// Tests the case when an idle socket can be closed when a new request is
4819// issued, and the new request belongs to a group that was previously stalled.
4820TEST_F(ClientSocketPoolBaseTest,
4821 CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded) {
4822 CreatePool(2, 2);
4823 std::list<TestConnectJob::JobType> job_types;
4824 job_types.push_back(TestConnectJob::kMockJob);
4825 job_types.push_back(TestConnectJob::kMockJob);
4826 job_types.push_back(TestConnectJob::kMockJob);
4827 job_types.push_back(TestConnectJob::kMockJob);
4828 connect_job_factory_->set_job_types(&job_types);
4829
4830 ClientSocketHandle handle1;
4831 TestCompletionCallback callback1;
Matt Menkef09e64c2019-04-23 22:16:284832 EXPECT_EQ(OK, handle1.Init(TestGroupId("group1"), params_, base::nullopt,
4833 DEFAULT_PRIORITY, SocketTag(),
4834 ClientSocketPool::RespectLimits::ENABLED,
4835 callback1.callback(),
4836 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4837 NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:204838
Matt Menkec6b3edf72019-03-19 17:00:394839 MockLayeredPool mock_layered_pool(pool_.get(), TestGroupId("group2"));
robpercival214763f2016-07-01 23:27:014840 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:204841 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4842 .WillRepeatedly(Invoke(&mock_layered_pool,
4843 &MockLayeredPool::ReleaseOneConnection));
4844 mock_layered_pool.set_can_release_connection(false);
4845
4846 // The third request is made when the socket pool is in a stalled state.
4847 ClientSocketHandle handle3;
4848 TestCompletionCallback callback3;
Matt Menkef09e64c2019-04-23 22:16:284849 EXPECT_EQ(ERR_IO_PENDING,
4850 handle3.Init(
4851 TestGroupId("group3"), params_, base::nullopt, DEFAULT_PRIORITY,
4852 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4853 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
4854 pool_.get(), NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:204855
4856 base::RunLoop().RunUntilIdle();
4857 EXPECT_FALSE(callback3.have_result());
4858
4859 // The fourth request is made when the pool is no longer stalled. The third
4860 // request should be serviced first, since it was issued first and has the
4861 // same priority.
4862 mock_layered_pool.set_can_release_connection(true);
4863 ClientSocketHandle handle4;
4864 TestCompletionCallback callback4;
Matt Menkef09e64c2019-04-23 22:16:284865 EXPECT_EQ(ERR_IO_PENDING,
4866 handle4.Init(
4867 TestGroupId("group3"), params_, base::nullopt, DEFAULT_PRIORITY,
4868 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4869 callback4.callback(), ClientSocketPool::ProxyAuthCallback(),
4870 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:014871 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204872 EXPECT_FALSE(callback4.have_result());
4873
4874 // Closing a handle should free up another socket slot.
4875 handle1.Reset();
robpercival214763f2016-07-01 23:27:014876 EXPECT_THAT(callback4.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204877}
4878
4879// Tests the case when an idle socket can be closed when a new request is
4880// issued, and the new request belongs to a group that was previously stalled.
4881//
4882// The two differences from the above test are that the stalled requests are not
4883// in the same group as the layered pool's request, and the the fourth request
4884// has a higher priority than the third one, so gets a socket first.
4885TEST_F(ClientSocketPoolBaseTest,
4886 CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded2) {
4887 CreatePool(2, 2);
4888 std::list<TestConnectJob::JobType> job_types;
4889 job_types.push_back(TestConnectJob::kMockJob);
4890 job_types.push_back(TestConnectJob::kMockJob);
4891 job_types.push_back(TestConnectJob::kMockJob);
4892 job_types.push_back(TestConnectJob::kMockJob);
4893 connect_job_factory_->set_job_types(&job_types);
4894
4895 ClientSocketHandle handle1;
4896 TestCompletionCallback callback1;
Matt Menkef09e64c2019-04-23 22:16:284897 EXPECT_EQ(OK, handle1.Init(TestGroupId("group1"), params_, base::nullopt,
4898 DEFAULT_PRIORITY, SocketTag(),
4899 ClientSocketPool::RespectLimits::ENABLED,
4900 callback1.callback(),
4901 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4902 NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:204903
Matt Menkec6b3edf72019-03-19 17:00:394904 MockLayeredPool mock_layered_pool(pool_.get(), TestGroupId("group2"));
robpercival214763f2016-07-01 23:27:014905 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:204906 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4907 .WillRepeatedly(Invoke(&mock_layered_pool,
4908 &MockLayeredPool::ReleaseOneConnection));
4909 mock_layered_pool.set_can_release_connection(false);
4910
4911 // The third request is made when the socket pool is in a stalled state.
4912 ClientSocketHandle handle3;
4913 TestCompletionCallback callback3;
tfarina428341112016-09-22 13:38:204914 EXPECT_EQ(
4915 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284916 handle3.Init(TestGroupId("group3"), params_, base::nullopt, MEDIUM,
4917 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504918 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
4919 pool_.get(), NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:204920
4921 base::RunLoop().RunUntilIdle();
4922 EXPECT_FALSE(callback3.have_result());
4923
4924 // The fourth request is made when the pool is no longer stalled. This
4925 // request has a higher priority than the third request, so is serviced first.
4926 mock_layered_pool.set_can_release_connection(true);
4927 ClientSocketHandle handle4;
4928 TestCompletionCallback callback4;
tfarina428341112016-09-22 13:38:204929 EXPECT_EQ(
4930 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284931 handle4.Init(TestGroupId("group3"), params_, base::nullopt, HIGHEST,
4932 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504933 callback4.callback(), ClientSocketPool::ProxyAuthCallback(),
4934 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:014935 EXPECT_THAT(callback4.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204936 EXPECT_FALSE(callback3.have_result());
4937
4938 // Closing a handle should free up another socket slot.
4939 handle1.Reset();
robpercival214763f2016-07-01 23:27:014940 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204941}
4942
4943TEST_F(ClientSocketPoolBaseTest,
4944 CloseMultipleIdleSocketsHeldByLayeredPoolWhenNeeded) {
4945 CreatePool(1, 1);
4946 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4947
Matt Menkec6b3edf72019-03-19 17:00:394948 MockLayeredPool mock_layered_pool1(pool_.get(), TestGroupId("foo"));
robpercival214763f2016-07-01 23:27:014949 EXPECT_THAT(mock_layered_pool1.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:204950 EXPECT_CALL(mock_layered_pool1, CloseOneIdleConnection())
4951 .WillRepeatedly(Invoke(&mock_layered_pool1,
4952 &MockLayeredPool::ReleaseOneConnection));
Matt Menkec6b3edf72019-03-19 17:00:394953 MockLayeredPool mock_layered_pool2(pool_.get(), TestGroupId("bar"));
robpercival214763f2016-07-01 23:27:014954 EXPECT_THAT(mock_layered_pool2.RequestSocketWithoutLimits(pool_.get()),
4955 IsOk());
[email protected]58e562f2013-04-22 17:32:204956 EXPECT_CALL(mock_layered_pool2, CloseOneIdleConnection())
4957 .WillRepeatedly(Invoke(&mock_layered_pool2,
4958 &MockLayeredPool::ReleaseOneConnection));
4959 ClientSocketHandle handle;
4960 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:504961 EXPECT_EQ(
4962 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:284963 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4964 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4965 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
4966 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:014967 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204968}
4969
[email protected]b021ece62013-06-11 11:06:334970// Test that when a socket pool and group are at their limits, a request
mmenked3641e12016-01-28 16:06:154971// with RespectLimits::DISABLED triggers creation of a new socket, and gets the
4972// socket instead of a request with the same priority that was issued earlier,
4973// but has RespectLimits::ENABLED.
[email protected]b021ece62013-06-11 11:06:334974TEST_F(ClientSocketPoolBaseTest, IgnoreLimits) {
[email protected]b021ece62013-06-11 11:06:334975 CreatePool(1, 1);
4976
4977 // Issue a request to reach the socket pool limit.
Matt Menkec6b3edf72019-03-19 17:00:394978 EXPECT_EQ(OK, StartRequestWithIgnoreLimits(
4979 TestGroupId("a"), MAXIMUM_PRIORITY,
4980 ClientSocketPool::RespectLimits::ENABLED));
Matt Menke9fa17d52019-03-25 19:12:264981 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]b021ece62013-06-11 11:06:334982
4983 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
4984
mmenked3641e12016-01-28 16:06:154985 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
Matt Menkec6b3edf72019-03-19 17:00:394986 TestGroupId("a"), MAXIMUM_PRIORITY,
mmenked3641e12016-01-28 16:06:154987 ClientSocketPool::RespectLimits::ENABLED));
Matt Menke9fa17d52019-03-25 19:12:264988 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]b021ece62013-06-11 11:06:334989
mmenked3641e12016-01-28 16:06:154990 // Issue a request that ignores the limits, so a new ConnectJob is
4991 // created.
4992 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
Matt Menkec6b3edf72019-03-19 17:00:394993 TestGroupId("a"), MAXIMUM_PRIORITY,
mmenked3641e12016-01-28 16:06:154994 ClientSocketPool::RespectLimits::DISABLED));
Matt Menke9fa17d52019-03-25 19:12:264995 ASSERT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]b021ece62013-06-11 11:06:334996
robpercival214763f2016-07-01 23:27:014997 EXPECT_THAT(request(2)->WaitForResult(), IsOk());
[email protected]b021ece62013-06-11 11:06:334998 EXPECT_FALSE(request(1)->have_result());
4999}
5000
[email protected]c55fabd2013-11-04 23:26:565001// Test that when a socket pool and group are at their limits, a ConnectJob
mmenked3641e12016-01-28 16:06:155002// issued for a request with RespectLimits::DISABLED is not cancelled when a
5003// request with RespectLimits::ENABLED issued to the same group is cancelled.
[email protected]c55fabd2013-11-04 23:26:565004TEST_F(ClientSocketPoolBaseTest, IgnoreLimitsCancelOtherJob) {
[email protected]c55fabd2013-11-04 23:26:565005 CreatePool(1, 1);
5006
5007 // Issue a request to reach the socket pool limit.
Matt Menkec6b3edf72019-03-19 17:00:395008 EXPECT_EQ(OK, StartRequestWithIgnoreLimits(
5009 TestGroupId("a"), MAXIMUM_PRIORITY,
5010 ClientSocketPool::RespectLimits::ENABLED));
Matt Menke9fa17d52019-03-25 19:12:265011 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]c55fabd2013-11-04 23:26:565012
5013 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
5014
mmenked3641e12016-01-28 16:06:155015 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
Matt Menkec6b3edf72019-03-19 17:00:395016 TestGroupId("a"), MAXIMUM_PRIORITY,
mmenked3641e12016-01-28 16:06:155017 ClientSocketPool::RespectLimits::ENABLED));
Matt Menke9fa17d52019-03-25 19:12:265018 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]c55fabd2013-11-04 23:26:565019
mmenked3641e12016-01-28 16:06:155020 // Issue a request with RespectLimits::DISABLED, so a new ConnectJob is
5021 // created.
5022 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
Matt Menkec6b3edf72019-03-19 17:00:395023 TestGroupId("a"), MAXIMUM_PRIORITY,
mmenked3641e12016-01-28 16:06:155024 ClientSocketPool::RespectLimits::DISABLED));
Matt Menke9fa17d52019-03-25 19:12:265025 ASSERT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]b021ece62013-06-11 11:06:335026
mmenked3641e12016-01-28 16:06:155027 // Cancel the pending request with RespectLimits::ENABLED. The ConnectJob
[email protected]b021ece62013-06-11 11:06:335028 // should not be cancelled.
5029 request(1)->handle()->Reset();
Matt Menke9fa17d52019-03-25 19:12:265030 ASSERT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
[email protected]b021ece62013-06-11 11:06:335031
robpercival214763f2016-07-01 23:27:015032 EXPECT_THAT(request(2)->WaitForResult(), IsOk());
[email protected]b021ece62013-06-11 11:06:335033 EXPECT_FALSE(request(1)->have_result());
5034}
5035
Matt Menkeb57663b32019-03-01 17:17:105036TEST_F(ClientSocketPoolBaseTest, ProxyAuthNoAuthCallback) {
5037 CreatePool(1, 1);
5038
5039 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5040
5041 ClientSocketHandle handle;
5042 TestCompletionCallback callback;
5043 EXPECT_EQ(
5044 ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:285045 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
5046 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5047 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5048 pool_.get(), NetLogWithSource()));
Matt Menkeb57663b32019-03-01 17:17:105049
Matt Menke9fa17d52019-03-25 19:12:265050 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105051
5052 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_PROXY_AUTH_REQUESTED));
5053 EXPECT_FALSE(handle.is_initialized());
5054 EXPECT_FALSE(handle.socket());
5055
5056 // The group should now be empty, and thus be deleted.
Matt Menke9fa17d52019-03-25 19:12:265057 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105058}
5059
5060class TestAuthHelper {
5061 public:
5062 TestAuthHelper() = default;
5063 ~TestAuthHelper() = default;
5064
Matt Menkec6b3edf72019-03-19 17:00:395065 void InitHandle(
Matt Menke84d11e562019-03-27 00:11:195066 scoped_refptr<ClientSocketPool::SocketParams> params,
Matt Menke9fa17d52019-03-25 19:12:265067 TransportClientSocketPool* pool,
Matt Menkec6b3edf72019-03-19 17:00:395068 RequestPriority priority = DEFAULT_PRIORITY,
5069 ClientSocketPool::RespectLimits respect_limits =
5070 ClientSocketPool::RespectLimits::ENABLED,
5071 const ClientSocketPool::GroupId& group_id_in = TestGroupId("a")) {
Matt Menkeb57663b32019-03-01 17:17:105072 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkef09e64c2019-04-23 22:16:285073 handle_.Init(group_id_in, params, base::nullopt, priority,
5074 SocketTag(), respect_limits, callback_.callback(),
Matt Menkeb57663b32019-03-01 17:17:105075 base::BindRepeating(&TestAuthHelper::AuthCallback,
5076 base::Unretained(this)),
5077 pool, NetLogWithSource()));
5078 }
5079
5080 void WaitForAuth() {
5081 run_loop_ = std::make_unique<base::RunLoop>();
5082 run_loop_->Run();
5083 run_loop_.reset();
5084 }
5085
5086 void WaitForAuthAndRestartSync() {
5087 restart_sync_ = true;
5088 WaitForAuth();
5089 restart_sync_ = false;
5090 }
5091
5092 void WaitForAuthAndResetHandleSync() {
5093 reset_handle_sync_ = true;
5094 WaitForAuth();
5095 reset_handle_sync_ = false;
5096 }
5097
5098 void RestartWithAuth() {
5099 DCHECK(restart_with_auth_callback_);
5100 std::move(restart_with_auth_callback_).Run();
5101 }
5102
5103 int WaitForResult() {
5104 int result = callback_.WaitForResult();
5105 // There shouldn't be any callback waiting to be invoked once the request is
5106 // complete.
5107 EXPECT_FALSE(restart_with_auth_callback_);
5108 // The socket should only be initialized on success.
5109 EXPECT_EQ(result == OK, handle_.is_initialized());
5110 EXPECT_EQ(result == OK, handle_.socket() != nullptr);
5111 return result;
5112 }
5113
5114 ClientSocketHandle* handle() { return &handle_; }
5115 int auth_count() const { return auth_count_; }
5116 int have_result() const { return callback_.have_result(); }
5117
5118 private:
5119 void AuthCallback(const HttpResponseInfo& response,
5120 HttpAuthController* auth_controller,
5121 base::OnceClosure restart_with_auth_callback) {
5122 EXPECT_FALSE(restart_with_auth_callback_);
5123 EXPECT_TRUE(restart_with_auth_callback);
5124
5125 // Once there's a result, this method shouldn't be invoked again.
5126 EXPECT_FALSE(callback_.have_result());
5127
5128 ++auth_count_;
5129 run_loop_->Quit();
5130 if (restart_sync_) {
5131 std::move(restart_with_auth_callback).Run();
5132 return;
5133 }
5134
5135 restart_with_auth_callback_ = std::move(restart_with_auth_callback);
5136
5137 if (reset_handle_sync_) {
5138 handle_.Reset();
5139 return;
5140 }
5141 }
5142
5143 std::unique_ptr<base::RunLoop> run_loop_;
5144 base::OnceClosure restart_with_auth_callback_;
5145
5146 bool restart_sync_ = false;
5147 bool reset_handle_sync_ = false;
5148
5149 ClientSocketHandle handle_;
5150 int auth_count_ = 0;
5151 TestCompletionCallback callback_;
5152
5153 DISALLOW_COPY_AND_ASSIGN(TestAuthHelper);
5154};
5155
5156TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnce) {
5157 CreatePool(1, 1);
5158 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5159
5160 TestAuthHelper auth_helper;
5161 auth_helper.InitHandle(params_, pool_.get());
Matt Menke9fa17d52019-03-25 19:12:265162 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menke4b69f932019-03-04 16:20:015163 EXPECT_EQ(LOAD_STATE_CONNECTING,
Matt Menkec6b3edf72019-03-19 17:00:395164 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:105165
5166 auth_helper.WaitForAuth();
Matt Menke9fa17d52019-03-25 19:12:265167 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menke4b69f932019-03-04 16:20:015168 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
Matt Menkec6b3edf72019-03-19 17:00:395169 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:105170
5171 auth_helper.RestartWithAuth();
Matt Menke9fa17d52019-03-25 19:12:265172 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menke4b69f932019-03-04 16:20:015173 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
Matt Menkec6b3edf72019-03-19 17:00:395174 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:105175
5176 EXPECT_THAT(auth_helper.WaitForResult(), IsOk());
5177 EXPECT_EQ(1, auth_helper.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265178 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5179 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:395180 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105181 EXPECT_EQ(0, pool_->IdleSocketCount());
5182}
5183
5184TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceSync) {
5185 CreatePool(1, 1);
5186 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5187
5188 TestAuthHelper auth_helper;
5189 auth_helper.InitHandle(params_, pool_.get());
Matt Menke9fa17d52019-03-25 19:12:265190 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menke4b69f932019-03-04 16:20:015191 EXPECT_EQ(LOAD_STATE_CONNECTING,
Matt Menkec6b3edf72019-03-19 17:00:395192 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:105193
5194 auth_helper.WaitForAuthAndRestartSync();
Matt Menke9fa17d52019-03-25 19:12:265195 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menke4b69f932019-03-04 16:20:015196 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
Matt Menkec6b3edf72019-03-19 17:00:395197 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:105198
5199 EXPECT_THAT(auth_helper.WaitForResult(), IsOk());
5200 EXPECT_EQ(1, auth_helper.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265201 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5202 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:395203 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105204 EXPECT_EQ(0, pool_->IdleSocketCount());
5205}
5206
5207TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceFails) {
5208 CreatePool(1, 1);
5209 connect_job_factory_->set_job_type(
5210 TestConnectJob::kMockAuthChallengeOnceFailingJob);
5211
5212 TestAuthHelper auth_helper;
5213 auth_helper.InitHandle(params_, pool_.get());
Matt Menke9fa17d52019-03-25 19:12:265214 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105215
5216 auth_helper.WaitForAuth();
5217 auth_helper.RestartWithAuth();
5218 EXPECT_THAT(auth_helper.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
5219
5220 EXPECT_EQ(1, auth_helper.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265221 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105222 EXPECT_EQ(0, pool_->IdleSocketCount());
5223}
5224
5225TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceSyncFails) {
5226 CreatePool(1, 1);
5227 connect_job_factory_->set_job_type(
5228 TestConnectJob::kMockAuthChallengeOnceFailingJob);
5229
5230 TestAuthHelper auth_helper;
5231 auth_helper.InitHandle(params_, pool_.get());
Matt Menke9fa17d52019-03-25 19:12:265232 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105233
5234 auth_helper.WaitForAuthAndRestartSync();
5235 EXPECT_THAT(auth_helper.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
5236
5237 EXPECT_EQ(1, auth_helper.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265238 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105239 EXPECT_EQ(0, pool_->IdleSocketCount());
5240}
5241
5242TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceDeleteHandle) {
5243 CreatePool(1, 1);
5244 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5245
5246 TestAuthHelper auth_helper;
5247 auth_helper.InitHandle(params_, pool_.get());
Matt Menke9fa17d52019-03-25 19:12:265248 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105249
5250 auth_helper.WaitForAuth();
Matt Menke9fa17d52019-03-25 19:12:265251 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105252
5253 auth_helper.handle()->Reset();
5254
5255 EXPECT_EQ(1, auth_helper.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265256 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105257 EXPECT_EQ(0, pool_->IdleSocketCount());
5258 EXPECT_FALSE(auth_helper.handle()->is_initialized());
5259 EXPECT_FALSE(auth_helper.handle()->socket());
5260}
5261
5262TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceDeleteHandleSync) {
5263 CreatePool(1, 1);
5264 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5265
5266 TestAuthHelper auth_helper;
5267 auth_helper.InitHandle(params_, pool_.get());
Matt Menke9fa17d52019-03-25 19:12:265268 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105269
5270 auth_helper.WaitForAuthAndResetHandleSync();
5271 EXPECT_EQ(1, auth_helper.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265272 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105273 EXPECT_EQ(0, pool_->IdleSocketCount());
5274 EXPECT_FALSE(auth_helper.handle()->is_initialized());
5275 EXPECT_FALSE(auth_helper.handle()->socket());
5276}
5277
5278TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceFlushWithError) {
5279 CreatePool(1, 1);
5280 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5281
5282 TestAuthHelper auth_helper;
5283 auth_helper.InitHandle(params_, pool_.get());
Matt Menke9fa17d52019-03-25 19:12:265284 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105285
5286 auth_helper.WaitForAuth();
5287
5288 pool_->FlushWithError(ERR_FAILED);
5289 base::RunLoop().RunUntilIdle();
5290
5291 // When flushing the socket pool, bound sockets should delay returning the
5292 // error until completion.
5293 EXPECT_FALSE(auth_helper.have_result());
Matt Menke9fa17d52019-03-25 19:12:265294 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105295 EXPECT_EQ(0, pool_->IdleSocketCount());
5296
5297 auth_helper.RestartWithAuth();
5298 // The callback should be called asynchronously.
5299 EXPECT_FALSE(auth_helper.have_result());
5300
5301 EXPECT_THAT(auth_helper.WaitForResult(), IsError(ERR_FAILED));
Matt Menke9fa17d52019-03-25 19:12:265302 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105303 EXPECT_EQ(0, pool_->IdleSocketCount());
5304}
5305
5306TEST_F(ClientSocketPoolBaseTest, ProxyAuthTwice) {
5307 CreatePool(1, 1);
5308 connect_job_factory_->set_job_type(
5309 TestConnectJob::kMockAuthChallengeTwiceJob);
5310
5311 TestAuthHelper auth_helper;
5312 auth_helper.InitHandle(params_, pool_.get());
Matt Menke9fa17d52019-03-25 19:12:265313 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menke4b69f932019-03-04 16:20:015314 EXPECT_EQ(LOAD_STATE_CONNECTING,
Matt Menkec6b3edf72019-03-19 17:00:395315 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:105316
5317 auth_helper.WaitForAuth();
5318 auth_helper.RestartWithAuth();
Matt Menke9fa17d52019-03-25 19:12:265319 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105320 EXPECT_EQ(1, auth_helper.auth_count());
Matt Menke4b69f932019-03-04 16:20:015321 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
Matt Menkec6b3edf72019-03-19 17:00:395322 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:105323
5324 auth_helper.WaitForAuth();
Matt Menke9fa17d52019-03-25 19:12:265325 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menke4b69f932019-03-04 16:20:015326 EXPECT_EQ(2, auth_helper.auth_count());
5327 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
Matt Menkec6b3edf72019-03-19 17:00:395328 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
Matt Menke4b69f932019-03-04 16:20:015329
Matt Menkeb57663b32019-03-01 17:17:105330 auth_helper.RestartWithAuth();
Matt Menke9fa17d52019-03-25 19:12:265331 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105332 EXPECT_EQ(2, auth_helper.auth_count());
Matt Menke4b69f932019-03-04 16:20:015333 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
Matt Menkec6b3edf72019-03-19 17:00:395334 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:105335
5336 EXPECT_THAT(auth_helper.WaitForResult(), IsOk());
5337 EXPECT_EQ(2, auth_helper.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265338 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5339 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:395340 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105341 EXPECT_EQ(0, pool_->IdleSocketCount());
5342}
5343
5344TEST_F(ClientSocketPoolBaseTest, ProxyAuthTwiceFails) {
5345 CreatePool(1, 1);
5346 connect_job_factory_->set_job_type(
5347 TestConnectJob::kMockAuthChallengeTwiceFailingJob);
5348
5349 TestAuthHelper auth_helper;
5350 auth_helper.InitHandle(params_, pool_.get());
Matt Menke9fa17d52019-03-25 19:12:265351 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105352
5353 auth_helper.WaitForAuth();
5354 auth_helper.RestartWithAuth();
Matt Menke9fa17d52019-03-25 19:12:265355 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105356 EXPECT_EQ(1, auth_helper.auth_count());
5357
5358 auth_helper.WaitForAuth();
5359 auth_helper.RestartWithAuth();
Matt Menke9fa17d52019-03-25 19:12:265360 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105361 EXPECT_EQ(2, auth_helper.auth_count());
5362
5363 EXPECT_THAT(auth_helper.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
5364 EXPECT_EQ(2, auth_helper.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265365 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105366 EXPECT_EQ(0, pool_->IdleSocketCount());
5367}
5368
5369// Makes sure that when a bound request is destroyed, a new ConnectJob is
5370// created, if needed.
5371TEST_F(ClientSocketPoolBaseTest,
5372 ProxyAuthCreateNewConnectJobOnDestroyBoundRequest) {
5373 CreatePool(1 /* max_sockets */, 1 /* max_sockets_per_group */);
5374 connect_job_factory_->set_job_type(
5375 TestConnectJob::kMockAuthChallengeOnceFailingJob);
5376
5377 // First request creates a ConnectJob.
5378 TestAuthHelper auth_helper1;
5379 auth_helper1.InitHandle(params_, pool_.get());
Matt Menke9fa17d52019-03-25 19:12:265380 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105381
5382 // A second request come in, but no new ConnectJob is needed, since the limit
5383 // has been reached.
5384 TestAuthHelper auth_helper2;
5385 auth_helper2.InitHandle(params_, pool_.get());
Matt Menke9fa17d52019-03-25 19:12:265386 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105387
5388 // Run until the auth callback for the first request is invoked.
5389 auth_helper1.WaitForAuth();
5390 EXPECT_EQ(0, auth_helper2.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265391 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5392 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:395393 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105394
5395 // Make connect jobs succeed, then cancel the first request, which should
5396 // destroy the bound ConnectJob, and cause a new ConnectJob to start.
5397 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
5398 auth_helper1.handle()->Reset();
5399 EXPECT_EQ(0, auth_helper2.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265400 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105401
5402 // The second ConnectJob should succeed.
5403 EXPECT_THAT(auth_helper2.WaitForResult(), IsOk());
5404 EXPECT_EQ(0, auth_helper2.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265405 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105406}
5407
5408// Makes sure that when a bound request is destroyed, a new ConnectJob is
5409// created for another group, if needed.
5410TEST_F(ClientSocketPoolBaseTest,
5411 ProxyAuthCreateNewConnectJobOnDestroyBoundRequestDifferentGroups) {
5412 CreatePool(1 /* max_sockets */, 1 /* max_sockets_per_group */);
5413 connect_job_factory_->set_job_type(
5414 TestConnectJob::kMockAuthChallengeOnceFailingJob);
5415
5416 // First request creates a ConnectJob.
5417 TestAuthHelper auth_helper1;
5418 auth_helper1.InitHandle(params_, pool_.get(), DEFAULT_PRIORITY);
Matt Menke9fa17d52019-03-25 19:12:265419 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105420
5421 // A second request come in, but no new ConnectJob is needed, since the limit
5422 // has been reached.
5423 TestAuthHelper auth_helper2;
5424 auth_helper2.InitHandle(params_, pool_.get(), DEFAULT_PRIORITY,
Matt Menkec6b3edf72019-03-19 17:00:395425 ClientSocketPool::RespectLimits::ENABLED,
5426 TestGroupId("b"));
Matt Menke9fa17d52019-03-25 19:12:265427 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5428 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
Matt Menkeb57663b32019-03-01 17:17:105429
5430 // Run until the auth callback for the first request is invoked.
5431 auth_helper1.WaitForAuth();
5432 EXPECT_EQ(0, auth_helper2.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265433 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5434 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkec6b3edf72019-03-19 17:00:395435 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menke9fa17d52019-03-25 19:12:265436 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
5437 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("b")));
Matt Menkec6b3edf72019-03-19 17:00:395438 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("b")));
Matt Menkeb57663b32019-03-01 17:17:105439
5440 // Make connect jobs succeed, then cancel the first request, which should
5441 // destroy the bound ConnectJob, and cause a new ConnectJob to start for the
5442 // other group.
5443 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
5444 auth_helper1.handle()->Reset();
5445 EXPECT_EQ(0, auth_helper2.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265446 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
5447 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
Matt Menkeb57663b32019-03-01 17:17:105448
5449 // The second ConnectJob should succeed.
5450 EXPECT_THAT(auth_helper2.WaitForResult(), IsOk());
5451 EXPECT_EQ(0, auth_helper2.auth_count());
Matt Menke9fa17d52019-03-25 19:12:265452 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
5453 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
Matt Menkeb57663b32019-03-01 17:17:105454}
5455
5456// Test that once an auth challenge is bound, that's the request that gets all
5457// subsequent calls and the socket itself.
5458TEST_F(ClientSocketPoolBaseTest, ProxyAuthStaysBound) {
5459 CreatePool(1, 1);
5460 connect_job_factory_->set_job_type(
5461 TestConnectJob::kMockAuthChallengeTwiceJob);
5462
5463 // First request creates a ConnectJob.
5464 TestAuthHelper auth_helper1;
5465 auth_helper1.InitHandle(params_, pool_.get(), LOWEST);
Matt Menke9fa17d52019-03-25 19:12:265466 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105467
5468 // A second, higher priority request is made.
5469 TestAuthHelper auth_helper2;
5470 auth_helper2.InitHandle(params_, pool_.get(), LOW);
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 second request is invoked.
5474 auth_helper2.WaitForAuth();
5475 EXPECT_EQ(0, auth_helper1.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 // Start a higher priority job. It shouldn't be able to steal |auth_helper2|'s
5481 // ConnectJob.
5482 TestAuthHelper auth_helper3;
5483 auth_helper3.InitHandle(params_, pool_.get(), HIGHEST);
Matt Menke9fa17d52019-03-25 19:12:265484 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105485
5486 // Start a higher job that ignores limits, creating a hanging socket. It
5487 // shouldn't be able to steal |auth_helper2|'s ConnectJob.
5488 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
5489 TestAuthHelper auth_helper4;
5490 auth_helper4.InitHandle(params_, pool_.get(), HIGHEST,
5491 ClientSocketPool::RespectLimits::DISABLED);
Matt Menke9fa17d52019-03-25 19:12:265492 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105493
5494 // Restart with auth, and |auth_helper2|'s auth method should be invoked
5495 // again.
5496 auth_helper2.RestartWithAuth();
5497 auth_helper2.WaitForAuth();
5498 EXPECT_EQ(0, auth_helper1.auth_count());
5499 EXPECT_FALSE(auth_helper1.have_result());
5500 EXPECT_EQ(2, auth_helper2.auth_count());
5501 EXPECT_FALSE(auth_helper2.have_result());
5502 EXPECT_EQ(0, auth_helper3.auth_count());
5503 EXPECT_FALSE(auth_helper3.have_result());
5504 EXPECT_EQ(0, auth_helper4.auth_count());
5505 EXPECT_FALSE(auth_helper4.have_result());
5506
5507 // Advance auth again, and |auth_helper2| should get the socket.
5508 auth_helper2.RestartWithAuth();
5509 EXPECT_THAT(auth_helper2.WaitForResult(), IsOk());
5510 // The hung ConnectJob for the RespectLimits::DISABLED request is still in the
5511 // socket pool.
Matt Menke9fa17d52019-03-25 19:12:265512 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5513 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105514 EXPECT_EQ(0, auth_helper1.auth_count());
5515 EXPECT_FALSE(auth_helper1.have_result());
5516 EXPECT_EQ(0, auth_helper3.auth_count());
5517 EXPECT_FALSE(auth_helper3.have_result());
5518 EXPECT_EQ(0, auth_helper4.auth_count());
5519 EXPECT_FALSE(auth_helper4.have_result());
5520
5521 // If the socket is returned to the socket pool, the RespectLimits::DISABLED
5522 // socket request should be able to claim it.
5523 auth_helper2.handle()->Reset();
5524 EXPECT_THAT(auth_helper4.WaitForResult(), IsOk());
5525 EXPECT_EQ(0, auth_helper1.auth_count());
5526 EXPECT_FALSE(auth_helper1.have_result());
5527 EXPECT_EQ(0, auth_helper3.auth_count());
5528 EXPECT_FALSE(auth_helper3.have_result());
5529 EXPECT_EQ(0, auth_helper4.auth_count());
5530}
5531
David Benjaminbac8dff2019-08-07 01:30:415532enum class RefreshType {
5533 kServer,
5534 kProxy,
5535};
5536
5537// Common base class to test RefreshGroup() when called from either
5538// OnSSLConfigForServerChanged() matching a specific group or the pool's proxy.
5539//
5540// Tests which test behavior specific to one or the other case should use
5541// ClientSocketPoolBaseTest directly. In particular, there is no "other group"
5542// when the pool's proxy matches.
5543class ClientSocketPoolBaseRefreshTest
5544 : public ClientSocketPoolBaseTest,
5545 public testing::WithParamInterface<RefreshType> {
5546 public:
5547 void CreatePoolForRefresh(int max_sockets,
5548 int max_sockets_per_group,
5549 bool enable_backup_connect_jobs = false) {
5550 switch (GetParam()) {
5551 case RefreshType::kServer:
5552 CreatePool(max_sockets, max_sockets_per_group,
5553 enable_backup_connect_jobs);
5554 break;
5555 case RefreshType::kProxy:
5556 CreatePoolWithIdleTimeouts(
5557 max_sockets, max_sockets_per_group, kUnusedIdleSocketTimeout,
5558 ClientSocketPool::used_idle_socket_timeout(),
5559 enable_backup_connect_jobs,
5560 ProxyServer::FromPacString("HTTPS myproxy:70"));
5561 break;
5562 }
5563 }
5564
5565 static ClientSocketPool::GroupId GetGroupId() {
5566 return TestGroupId("a", 443, ClientSocketPool::SocketType::kSsl);
5567 }
5568
David Benjamin6dd7e882019-10-10 02:35:235569 static ClientSocketPool::GroupId GetGroupIdInPartition() {
5570 // Note this GroupId will match GetGroupId() unless
5571 // kPartitionConnectionsByNetworkIsolationKey is enabled.
5572 const auto kOrigin = url::Origin::Create(GURL("https://b/"));
5573 const NetworkIsolationKey kNetworkIsolationKey(kOrigin, kOrigin);
5574 return TestGroupId("a", 443, ClientSocketPool::SocketType::kSsl,
5575 PrivacyMode::PRIVACY_MODE_DISABLED,
5576 kNetworkIsolationKey);
5577 }
5578
David Benjaminbac8dff2019-08-07 01:30:415579 void OnSSLConfigForServerChanged() {
5580 switch (GetParam()) {
5581 case RefreshType::kServer:
5582 pool_->OnSSLConfigForServerChanged(HostPortPair("a", 443));
5583 break;
5584 case RefreshType::kProxy:
5585 pool_->OnSSLConfigForServerChanged(HostPortPair("myproxy", 70));
5586 break;
5587 }
5588 }
5589};
5590
5591INSTANTIATE_TEST_SUITE_P(RefreshType,
5592 ClientSocketPoolBaseRefreshTest,
5593 ::testing::Values(RefreshType::kServer,
5594 RefreshType::kProxy));
5595
5596TEST_P(ClientSocketPoolBaseRefreshTest, RefreshGroupCreatesNewConnectJobs) {
5597 CreatePoolForRefresh(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
5598 const ClientSocketPool::GroupId kGroupId = GetGroupId();
Matt Menkebf3c767d2019-04-15 23:28:245599
5600 // First job will be waiting until it gets aborted.
5601 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
5602
5603 ClientSocketHandle handle;
5604 TestCompletionCallback callback;
5605 EXPECT_THAT(
Matt Menkef09e64c2019-04-23 22:16:285606 handle.Init(kGroupId, params_, base::nullopt, DEFAULT_PRIORITY,
5607 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5608 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5609 pool_.get(), NetLogWithSource()),
Matt Menkebf3c767d2019-04-15 23:28:245610 IsError(ERR_IO_PENDING));
5611
5612 // Switch connect job types, so creating a new ConnectJob will result in
5613 // success.
5614 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
5615
David Benjaminbac8dff2019-08-07 01:30:415616 OnSSLConfigForServerChanged();
Matt Menkebf3c767d2019-04-15 23:28:245617 EXPECT_EQ(OK, callback.WaitForResult());
5618 ASSERT_TRUE(handle.socket());
5619 EXPECT_EQ(0, pool_->IdleSocketCount());
5620 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId));
5621 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(kGroupId));
5622 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(kGroupId));
5623 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId));
5624}
5625
David Benjaminbac8dff2019-08-07 01:30:415626TEST_P(ClientSocketPoolBaseRefreshTest, RefreshGroupClosesIdleConnectJobs) {
David Benjamin6dd7e882019-10-10 02:35:235627 base::test::ScopedFeatureList feature_list;
5628 feature_list.InitAndEnableFeature(
5629 features::kPartitionConnectionsByNetworkIsolationKey);
5630
David Benjaminbac8dff2019-08-07 01:30:415631 CreatePoolForRefresh(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
5632 const ClientSocketPool::GroupId kGroupId = GetGroupId();
David Benjamin6dd7e882019-10-10 02:35:235633 const ClientSocketPool::GroupId kGroupIdInPartition = GetGroupIdInPartition();
Matt Menkebf3c767d2019-04-15 23:28:245634
Matt Menkef09e64c2019-04-23 22:16:285635 pool_->RequestSockets(kGroupId, params_, base::nullopt, 2,
5636 NetLogWithSource());
David Benjamin6dd7e882019-10-10 02:35:235637 pool_->RequestSockets(kGroupIdInPartition, params_, base::nullopt, 2,
5638 NetLogWithSource());
Matt Menkebf3c767d2019-04-15 23:28:245639 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId));
David Benjamin6dd7e882019-10-10 02:35:235640 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupIdInPartition));
5641 EXPECT_EQ(4, pool_->IdleSocketCount());
Matt Menkebf3c767d2019-04-15 23:28:245642 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(kGroupId));
David Benjamin6dd7e882019-10-10 02:35:235643 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(kGroupIdInPartition));
Matt Menkebf3c767d2019-04-15 23:28:245644
David Benjaminbac8dff2019-08-07 01:30:415645 OnSSLConfigForServerChanged();
Matt Menkebf3c767d2019-04-15 23:28:245646 EXPECT_EQ(0, pool_->IdleSocketCount());
5647 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupId));
David Benjamin6dd7e882019-10-10 02:35:235648 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupIdInPartition));
Matt Menkebf3c767d2019-04-15 23:28:245649}
5650
5651TEST_F(ClientSocketPoolBaseTest,
5652 RefreshGroupDoesNotCloseIdleConnectJobsInOtherGroup) {
5653 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
David Benjaminbac8dff2019-08-07 01:30:415654 const ClientSocketPool::GroupId kGroupId =
5655 TestGroupId("a", 443, ClientSocketPool::SocketType::kSsl);
5656 const ClientSocketPool::GroupId kOtherGroupId =
5657 TestGroupId("b", 443, ClientSocketPool::SocketType::kSsl);
Matt Menkebf3c767d2019-04-15 23:28:245658
Matt Menkef09e64c2019-04-23 22:16:285659 pool_->RequestSockets(kOtherGroupId, params_, base::nullopt, 2,
5660 NetLogWithSource());
Matt Menkebf3c767d2019-04-15 23:28:245661 ASSERT_TRUE(pool_->HasGroupForTesting(kOtherGroupId));
5662 EXPECT_EQ(2, pool_->IdleSocketCount());
5663 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(kOtherGroupId));
5664
David Benjaminbac8dff2019-08-07 01:30:415665 pool_->OnSSLConfigForServerChanged(HostPortPair("a", 443));
Matt Menkebf3c767d2019-04-15 23:28:245666 ASSERT_TRUE(pool_->HasGroupForTesting(kOtherGroupId));
5667 EXPECT_EQ(2, pool_->IdleSocketCount());
5668 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(kOtherGroupId));
5669}
5670
David Benjaminbac8dff2019-08-07 01:30:415671TEST_P(ClientSocketPoolBaseRefreshTest, RefreshGroupPreventsSocketReuse) {
5672 CreatePoolForRefresh(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
5673 const ClientSocketPool::GroupId kGroupId = GetGroupId();
Matt Menkebf3c767d2019-04-15 23:28:245674
5675 ClientSocketHandle handle;
5676 TestCompletionCallback callback;
5677 EXPECT_THAT(
Matt Menkef09e64c2019-04-23 22:16:285678 handle.Init(kGroupId, params_, base::nullopt, DEFAULT_PRIORITY,
5679 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5680 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5681 pool_.get(), NetLogWithSource()),
Matt Menkebf3c767d2019-04-15 23:28:245682 IsOk());
5683 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId));
5684 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId));
5685
David Benjaminbac8dff2019-08-07 01:30:415686 OnSSLConfigForServerChanged();
Matt Menkebf3c767d2019-04-15 23:28:245687
5688 handle.Reset();
5689 EXPECT_EQ(0, pool_->IdleSocketCount());
5690 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupId));
5691}
5692
5693TEST_F(ClientSocketPoolBaseTest,
5694 RefreshGroupDoesNotPreventSocketReuseInOtherGroup) {
5695 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
David Benjaminbac8dff2019-08-07 01:30:415696 const ClientSocketPool::GroupId kGroupId =
5697 TestGroupId("a", 443, ClientSocketPool::SocketType::kSsl);
5698 const ClientSocketPool::GroupId kOtherGroupId =
5699 TestGroupId("b", 443, ClientSocketPool::SocketType::kSsl);
Matt Menkebf3c767d2019-04-15 23:28:245700
5701 ClientSocketHandle handle;
5702 TestCompletionCallback callback;
5703 EXPECT_THAT(
Matt Menkef09e64c2019-04-23 22:16:285704 handle.Init(kOtherGroupId, params_, base::nullopt, DEFAULT_PRIORITY,
5705 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5706 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5707 pool_.get(), NetLogWithSource()),
Matt Menkebf3c767d2019-04-15 23:28:245708 IsOk());
5709 ASSERT_TRUE(pool_->HasGroupForTesting(kOtherGroupId));
5710 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kOtherGroupId));
5711
David Benjaminbac8dff2019-08-07 01:30:415712 pool_->OnSSLConfigForServerChanged(HostPortPair("a", 443));
Matt Menkebf3c767d2019-04-15 23:28:245713
5714 handle.Reset();
5715 EXPECT_EQ(1, pool_->IdleSocketCount());
5716 ASSERT_TRUE(pool_->HasGroupForTesting(kOtherGroupId));
5717 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(kOtherGroupId));
5718}
5719
David Benjaminbac8dff2019-08-07 01:30:415720TEST_P(ClientSocketPoolBaseRefreshTest,
5721 RefreshGroupReplacesBoundConnectJobOnConnect) {
5722 CreatePoolForRefresh(1, 1);
5723 const ClientSocketPool::GroupId kGroupId = GetGroupId();
Matt Menkebf3c767d2019-04-15 23:28:245724 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5725
5726 TestAuthHelper auth_helper;
5727 auth_helper.InitHandle(params_, pool_.get(), DEFAULT_PRIORITY,
5728 ClientSocketPool::RespectLimits::ENABLED, kGroupId);
5729 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(kGroupId));
5730
5731 auth_helper.WaitForAuth();
5732
5733 // This should update the generation, but not cancel the old ConnectJob - it's
5734 // not safe to do anything while waiting on the original ConnectJob.
David Benjaminbac8dff2019-08-07 01:30:415735 OnSSLConfigForServerChanged();
Matt Menkebf3c767d2019-04-15 23:28:245736
5737 // Providing auth credentials and restarting the request with them will cause
5738 // the ConnectJob to complete successfully, but the result will be discarded
5739 // because of the generation mismatch.
5740 auth_helper.RestartWithAuth();
5741
5742 // Despite using ConnectJobs that simulate a single challenge, a second
5743 // challenge will be seen, due to using a new ConnectJob.
5744 auth_helper.WaitForAuth();
5745 auth_helper.RestartWithAuth();
5746
5747 EXPECT_THAT(auth_helper.WaitForResult(), IsOk());
5748 EXPECT_TRUE(auth_helper.handle()->socket());
5749 EXPECT_EQ(2, auth_helper.auth_count());
5750
5751 // When released, the socket will be returned to the socket pool, and
5752 // available for reuse.
5753 auth_helper.handle()->Reset();
5754 EXPECT_EQ(1, pool_->IdleSocketCount());
5755 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId));
5756 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(kGroupId));
5757}
5758
David Benjaminbac8dff2019-08-07 01:30:415759TEST_F(ClientSocketPoolBaseTest, RefreshProxyRefreshesAllGroups) {
5760 CreatePoolWithIdleTimeouts(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
5761 kUnusedIdleSocketTimeout,
5762 ClientSocketPool::used_idle_socket_timeout(),
5763 false /* no backup connect jobs */,
5764 ProxyServer::FromPacString("HTTPS myproxy:70"));
5765
5766 const ClientSocketPool::GroupId kGroupId1 =
5767 TestGroupId("a", 443, ClientSocketPool::SocketType::kSsl);
5768 const ClientSocketPool::GroupId kGroupId2 =
5769 TestGroupId("b", 443, ClientSocketPool::SocketType::kSsl);
5770 const ClientSocketPool::GroupId kGroupId3 =
5771 TestGroupId("c", 443, ClientSocketPool::SocketType::kSsl);
5772
5773 // Make three sockets in three different groups. The third socket is released
5774 // to the pool as idle.
5775 ClientSocketHandle handle1, handle2, handle3;
5776 TestCompletionCallback callback;
5777 EXPECT_THAT(
5778 handle1.Init(kGroupId1, params_, base::nullopt, DEFAULT_PRIORITY,
5779 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5780 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5781 pool_.get(), NetLogWithSource()),
5782 IsOk());
5783 EXPECT_THAT(
5784 handle2.Init(kGroupId2, params_, base::nullopt, DEFAULT_PRIORITY,
5785 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5786 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5787 pool_.get(), NetLogWithSource()),
5788 IsOk());
5789 EXPECT_THAT(
5790 handle3.Init(kGroupId3, params_, base::nullopt, DEFAULT_PRIORITY,
5791 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5792 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5793 pool_.get(), NetLogWithSource()),
5794 IsOk());
5795 handle3.Reset();
5796 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId1));
5797 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId1));
5798 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId2));
5799 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId2));
5800 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId3));
5801 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(kGroupId3));
5802
5803 // Changes to some other proxy do not affect the pool. The idle socket remains
5804 // alive and closing |handle2| makes the socket available for the pool.
5805 pool_->OnSSLConfigForServerChanged(HostPortPair("someotherproxy", 70));
5806
5807 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId1));
5808 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId1));
5809 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId2));
5810 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId2));
5811 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId3));
5812 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(kGroupId3));
5813
5814 handle2.Reset();
5815 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId2));
5816 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(kGroupId2));
5817
5818 // Changes to the matching proxy refreshes all groups.
5819 pool_->OnSSLConfigForServerChanged(HostPortPair("myproxy", 70));
5820
5821 // Idle sockets are closed.
5822 EXPECT_EQ(0, pool_->IdleSocketCount());
5823 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupId2));
5824 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupId3));
5825
5826 // The active socket, however, continues to be active.
5827 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId1));
5828 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId1));
5829
5830 // Closing it does not make it available for the pool.
5831 handle1.Reset();
5832 EXPECT_EQ(0, pool_->IdleSocketCount());
5833 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupId1));
5834}
5835
5836TEST_F(ClientSocketPoolBaseTest, RefreshBothPrivacyAndNormalSockets) {
5837 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
5838
5839 const ClientSocketPool::GroupId kGroupId =
5840 TestGroupId("a", 443, ClientSocketPool::SocketType::kSsl,
5841 PrivacyMode::PRIVACY_MODE_DISABLED);
5842 const ClientSocketPool::GroupId kGroupIdPrivacy =
5843 TestGroupId("a", 443, ClientSocketPool::SocketType::kSsl,
5844 PrivacyMode::PRIVACY_MODE_ENABLED);
5845 const ClientSocketPool::GroupId kOtherGroupId =
5846 TestGroupId("b", 443, ClientSocketPool::SocketType::kSsl);
5847
5848 // Make a socket in each groups.
5849 ClientSocketHandle handle1, handle2, handle3;
5850 TestCompletionCallback callback;
5851 EXPECT_THAT(
5852 handle1.Init(kGroupId, params_, base::nullopt, DEFAULT_PRIORITY,
5853 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5854 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5855 pool_.get(), NetLogWithSource()),
5856 IsOk());
5857 EXPECT_THAT(
5858 handle2.Init(kGroupIdPrivacy, params_, base::nullopt, DEFAULT_PRIORITY,
5859 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5860 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5861 pool_.get(), NetLogWithSource()),
5862 IsOk());
5863 EXPECT_THAT(
5864 handle3.Init(kOtherGroupId, params_, base::nullopt, DEFAULT_PRIORITY,
5865 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5866 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5867 pool_.get(), NetLogWithSource()),
5868 IsOk());
5869 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId));
5870 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId));
5871 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupIdPrivacy));
5872 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupIdPrivacy));
5873 ASSERT_TRUE(pool_->HasGroupForTesting(kOtherGroupId));
5874 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kOtherGroupId));
5875
5876 pool_->OnSSLConfigForServerChanged(HostPortPair("a", 443));
5877
5878 // Active sockets continue to be active.
5879 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId));
5880 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId));
5881 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupIdPrivacy));
5882 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupIdPrivacy));
5883 ASSERT_TRUE(pool_->HasGroupForTesting(kOtherGroupId));
5884 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kOtherGroupId));
5885
5886 // Closing them leaves kOtherGroupId alone, but kGroupId and kGroupIdPrivacy
5887 // are unusable.
5888 handle1.Reset();
5889 handle2.Reset();
5890 handle3.Reset();
5891 EXPECT_EQ(1, pool_->IdleSocketCount());
5892 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupId));
5893 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupIdPrivacy));
5894 EXPECT_TRUE(pool_->HasGroupForTesting(kOtherGroupId));
5895 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(kOtherGroupId));
5896}
5897
[email protected]f6d1d6eb2009-06-24 20:16:095898} // namespace
5899
5900} // namespace net