blob: a1b679a0de53d669b6346efc6312163bd73bd190 [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
[email protected]ab838892009-06-30 18:49:055#include "net/socket/client_socket_pool_base.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"
[email protected]034df0f32013-01-07 23:17:4819#include "base/run_loop.h"
skyostil4891b25b2015-06-11 11:43:4520#include "base/single_thread_task_runner.h"
Avi Drissman4365a4782018-12-28 19:26:2421#include "base/stl_util.h"
[email protected]fc9be5802013-06-11 10:56:5122#include "base/strings/string_number_conversions.h"
[email protected]18b577412013-07-18 04:19:1523#include "base/strings/stringprintf.h"
[email protected]f214f8792011-01-01 02:17:0824#include "base/threading/platform_thread.h"
gabf767595f2016-05-11 18:50:3525#include "base/threading/thread_task_runner_handle.h"
[email protected]f3a1c642011-07-12 19:15:0326#include "base/values.h"
[email protected]034df0f32013-01-07 23:17:4827#include "net/base/load_timing_info.h"
[email protected]b258e0792013-01-12 07:11:5928#include "net/base/load_timing_info_test_util.h"
[email protected]d8eb84242010-09-25 02:25:0629#include "net/base/net_errors.h"
[email protected]ac790b42009-12-02 04:31:3130#include "net/base/request_priority.h"
[email protected]f6d1d6eb2009-06-24 20:16:0931#include "net/base/test_completion_callback.h"
[email protected]277d5942010-08-11 21:02:3532#include "net/http/http_response_headers.h"
eroman87c53d62015-04-02 06:51:0733#include "net/log/net_log.h"
mikecirone8b85c432016-09-08 19:11:0034#include "net/log/net_log_event_type.h"
mikecironef22f9812016-10-04 03:40:1935#include "net/log/net_log_source.h"
mikecirone8b85c432016-09-08 19:11:0036#include "net/log/net_log_source_type.h"
mmenke16a7cbdd2015-04-24 23:00:5637#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4638#include "net/log/test_net_log_entry.h"
39#include "net/log/test_net_log_util.h"
[email protected]f6d1d6eb2009-06-24 20:16:0940#include "net/socket/client_socket_factory.h"
41#include "net/socket/client_socket_handle.h"
tfarina5dd13c22016-11-16 12:08:2642#include "net/socket/datagram_client_socket.h"
tbansalca83c002016-04-28 20:56:2843#include "net/socket/socket_performance_watcher.h"
Paul Jensen8d6f87ec2018-01-13 00:46:5444#include "net/socket/socket_tag.h"
[email protected]75439d3b2009-07-23 22:11:1745#include "net/socket/socket_test_util.h"
[email protected]18ccfdb2013-08-15 00:13:4446#include "net/socket/ssl_client_socket.h"
[email protected]3268023f2011-05-05 00:08:1047#include "net/socket/stream_socket.h"
robpercival214763f2016-07-01 23:27:0148#include "net/test/gtest_util.h"
Bence Béky98447b12018-05-08 03:14:0149#include "net/test/test_with_scoped_task_environment.h"
Ramin Halavati0a08cc82018-02-06 07:46:3850#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
[email protected]51fdc7c2012-04-10 19:19:4851#include "testing/gmock/include/gmock/gmock.h"
[email protected]f6d1d6eb2009-06-24 20:16:0952#include "testing/gtest/include/gtest/gtest.h"
53
robpercival214763f2016-07-01 23:27:0154using net::test::IsError;
55using net::test::IsOk;
56
[email protected]51fdc7c2012-04-10 19:19:4857using ::testing::Invoke;
58using ::testing::Return;
59
[email protected]f6d1d6eb2009-06-24 20:16:0960namespace net {
61
62namespace {
63
[email protected]211d21722009-07-22 15:48:5364const int kDefaultMaxSockets = 4;
[email protected]c9d6a1d2009-07-14 16:15:2065const int kDefaultMaxSocketsPerGroup = 2;
Tarun Bansala7635092019-02-20 10:00:5966constexpr base::TimeDelta kUnusedIdleSocketTimeout =
67 base::TimeDelta::FromSeconds(10);
[email protected]0b7648c2009-07-06 20:14:0168
Matt Menkec6b3edf72019-03-19 17:00:3969ClientSocketPool::GroupId TestGroupId(const std::string& host,
70 int port = 80,
71 ClientSocketPool::SocketType socket_type =
72 ClientSocketPool::SocketType::kHttp,
73 bool privacy_mode = false) {
74 return ClientSocketPool::GroupId(HostPortPair(host, port), socket_type,
75 privacy_mode);
76}
77
[email protected]034df0f32013-01-07 23:17:4878// Make sure |handle| sets load times correctly when it has been assigned a
79// reused socket.
80void TestLoadTimingInfoConnectedReused(const ClientSocketHandle& handle) {
81 LoadTimingInfo load_timing_info;
82 // Only pass true in as |is_reused|, as in general, HttpStream types should
83 // have stricter concepts of reuse than socket pools.
84 EXPECT_TRUE(handle.GetLoadTimingInfo(true, &load_timing_info));
85
86 EXPECT_EQ(true, load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:1987 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]034df0f32013-01-07 23:17:4888
[email protected]b258e0792013-01-12 07:11:5989 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
90 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:4891}
92
93// Make sure |handle| sets load times correctly when it has been assigned a
[email protected]b021ece62013-06-11 11:06:3394// fresh socket. Also runs TestLoadTimingInfoConnectedReused, since the owner
[email protected]034df0f32013-01-07 23:17:4895// of a connection where |is_reused| is false may consider the connection
96// reused.
97void TestLoadTimingInfoConnectedNotReused(const ClientSocketHandle& handle) {
98 EXPECT_FALSE(handle.is_reused());
99
100 LoadTimingInfo load_timing_info;
101 EXPECT_TRUE(handle.GetLoadTimingInfo(false, &load_timing_info));
102
103 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19104 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]034df0f32013-01-07 23:17:48105
[email protected]b258e0792013-01-12 07:11:59106 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
107 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
108 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:48109
110 TestLoadTimingInfoConnectedReused(handle);
111}
112
113// Make sure |handle| sets load times correctly, in the case that it does not
114// currently have a socket.
115void TestLoadTimingInfoNotConnected(const ClientSocketHandle& handle) {
116 // Should only be set to true once a socket is assigned, if at all.
117 EXPECT_FALSE(handle.is_reused());
118
119 LoadTimingInfo load_timing_info;
120 EXPECT_FALSE(handle.GetLoadTimingInfo(false, &load_timing_info));
121
122 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19123 EXPECT_EQ(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]034df0f32013-01-07 23:17:48124
[email protected]b258e0792013-01-12 07:11:59125 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
126 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:48127}
128
[email protected]df4b4ef2010-07-12 18:25:21129class TestSocketParams : public base::RefCounted<TestSocketParams> {
[email protected]5acdce12011-03-30 13:00:20130 public:
Chris Watkins7a41d3552017-12-01 02:13:27131 explicit TestSocketParams() = default;
[email protected]51fdc7c2012-04-10 19:19:48132
[email protected]df4b4ef2010-07-12 18:25:21133 private:
134 friend class base::RefCounted<TestSocketParams>;
Chris Watkins7a41d3552017-12-01 02:13:27135 ~TestSocketParams() = default;
[email protected]df4b4ef2010-07-12 18:25:21136};
[email protected]7fc5b09a2010-02-27 00:07:38137typedef ClientSocketPoolBase<TestSocketParams> TestClientSocketPoolBase;
[email protected]d80a4322009-08-14 07:07:49138
[email protected]3268023f2011-05-05 00:08:10139class MockClientSocket : public StreamSocket {
[email protected]f6d1d6eb2009-06-24 20:16:09140 public:
[email protected]034df0f32013-01-07 23:17:48141 explicit MockClientSocket(net::NetLog* net_log)
142 : connected_(false),
[email protected]0dc88b32014-03-26 20:12:28143 has_unread_data_(false),
tfarina428341112016-09-22 13:38:20144 net_log_(NetLogWithSource::Make(net_log, NetLogSourceType::SOCKET)),
Charlie Harrison3e4c0622018-05-13 15:44:30145 was_used_to_convey_data_(false) {}
[email protected]f6d1d6eb2009-06-24 20:16:09146
[email protected]0dc88b32014-03-26 20:12:28147 // Sets whether the socket has unread data. If true, the next call to Read()
148 // will return 1 byte and IsConnectedAndIdle() will return false.
149 void set_has_unread_data(bool has_unread_data) {
150 has_unread_data_ = has_unread_data;
151 }
152
[email protected]3f55aa12011-12-07 02:03:33153 // Socket implementation.
dchengb03027d2014-10-21 12:00:20154 int Read(IOBuffer* /* buf */,
155 int len,
Brad Lassey3a814172018-04-26 03:30:21156 CompletionOnceCallback /* callback */) override {
[email protected]0dc88b32014-03-26 20:12:28157 if (has_unread_data_ && len > 0) {
158 has_unread_data_ = false;
159 was_used_to_convey_data_ = true;
160 return 1;
161 }
[email protected]e86df8dc2013-03-30 13:18:28162 return ERR_UNEXPECTED;
[email protected]3f55aa12011-12-07 02:03:33163 }
[email protected]ab838892009-06-30 18:49:05164
[email protected]a2b2cfc2017-12-06 09:06:08165 int Write(
166 IOBuffer* /* buf */,
167 int len,
Brad Lassey3a814172018-04-26 03:30:21168 CompletionOnceCallback /* callback */,
[email protected]a2b2cfc2017-12-06 09:06:08169 const NetworkTrafficAnnotationTag& /*traffic_annotation*/) override {
[email protected]0f873e82010-09-02 16:09:01170 was_used_to_convey_data_ = true;
171 return len;
[email protected]ab838892009-06-30 18:49:05172 }
Avi Drissman13fc8932015-12-20 04:40:46173 int SetReceiveBufferSize(int32_t size) override { return OK; }
174 int SetSendBufferSize(int32_t size) override { return OK; }
[email protected]ab838892009-06-30 18:49:05175
[email protected]dbf036f2011-12-06 23:33:24176 // StreamSocket implementation.
Brad Lassey3a814172018-04-26 03:30:21177 int Connect(CompletionOnceCallback callback) override {
[email protected]dbf036f2011-12-06 23:33:24178 connected_ = true;
179 return OK;
180 }
[email protected]f6d1d6eb2009-06-24 20:16:09181
dchengb03027d2014-10-21 12:00:20182 void Disconnect() override { connected_ = false; }
183 bool IsConnected() const override { return connected_; }
184 bool IsConnectedAndIdle() const override {
[email protected]0dc88b32014-03-26 20:12:28185 return connected_ && !has_unread_data_;
186 }
[email protected]0b7648c2009-07-06 20:14:01187
dchengb03027d2014-10-21 12:00:20188 int GetPeerAddress(IPEndPoint* /* address */) const override {
[email protected]9f864b32010-01-20 15:01:16189 return ERR_UNEXPECTED;
[email protected]f6d1d6eb2009-06-24 20:16:09190 }
[email protected]f6d1d6eb2009-06-24 20:16:09191
dchengb03027d2014-10-21 12:00:20192 int GetLocalAddress(IPEndPoint* /* address */) const override {
[email protected]e7f74da2011-04-19 23:49:35193 return ERR_UNEXPECTED;
194 }
195
tfarina428341112016-09-22 13:38:20196 const NetLogWithSource& NetLog() const override { return net_log_; }
[email protected]a2006ece2010-04-23 16:44:02197
dchengb03027d2014-10-21 12:00:20198 bool WasEverUsed() const override { return was_used_to_convey_data_; }
tfarina2846404c2016-12-25 14:31:37199 bool WasAlpnNegotiated() const override { return false; }
dchengb03027d2014-10-21 12:00:20200 NextProto GetNegotiatedProtocol() const override { return kProtoUnknown; }
201 bool GetSSLInfo(SSLInfo* ssl_info) override { return false; }
ttuttle23fdb7b2015-05-15 01:28:03202 void GetConnectionAttempts(ConnectionAttempts* out) const override {
203 out->clear();
204 }
205 void ClearConnectionAttempts() override {}
206 void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
tbansalf82cc8e2015-10-14 20:05:49207 int64_t GetTotalReceivedBytes() const override {
208 NOTIMPLEMENTED();
209 return 0;
210 }
Paul Jensen0f49dec2017-12-12 23:39:58211 void ApplySocketTag(const SocketTag& tag) override {}
[email protected]9b5614a2010-08-25 20:29:45212
[email protected]f6d1d6eb2009-06-24 20:16:09213 private:
214 bool connected_;
[email protected]0dc88b32014-03-26 20:12:28215 bool has_unread_data_;
tfarina428341112016-09-22 13:38:20216 NetLogWithSource net_log_;
[email protected]0f873e82010-09-02 16:09:01217 bool was_used_to_convey_data_;
[email protected]f6d1d6eb2009-06-24 20:16:09218
[email protected]ab838892009-06-30 18:49:05219 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
[email protected]f6d1d6eb2009-06-24 20:16:09220};
221
[email protected]5fc08e32009-07-15 17:09:57222class TestConnectJob;
223
[email protected]f6d1d6eb2009-06-24 20:16:09224class MockClientSocketFactory : public ClientSocketFactory {
225 public:
[email protected]ab838892009-06-30 18:49:05226 MockClientSocketFactory() : allocation_count_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:09227
danakj655b66c2016-04-16 00:51:38228 std::unique_ptr<DatagramClientSocket> CreateDatagramClientSocket(
[email protected]5370c012011-06-29 03:47:04229 DatagramSocket::BindType bind_type,
[email protected]98b0e582011-06-22 14:31:41230 NetLog* net_log,
mikecironef22f9812016-10-04 03:40:19231 const NetLogSource& source) override {
[email protected]98b0e582011-06-22 14:31:41232 NOTREACHED();
danakj655b66c2016-04-16 00:51:38233 return std::unique_ptr<DatagramClientSocket>();
[email protected]98b0e582011-06-22 14:31:41234 }
235
Helen Lid5bb9222018-04-12 15:33:09236 std::unique_ptr<TransportClientSocket> CreateTransportClientSocket(
[email protected]0a0b7682010-08-25 17:08:07237 const AddressList& addresses,
danakj655b66c2016-04-16 00:51:38238 std::unique_ptr<
239 SocketPerformanceWatcher> /* socket_performance_watcher */,
[email protected]0a0b7682010-08-25 17:08:07240 NetLog* /* net_log */,
mikecironef22f9812016-10-04 03:40:19241 const NetLogSource& /*source*/) override {
[email protected]f6d1d6eb2009-06-24 20:16:09242 allocation_count_++;
Helen Lid5bb9222018-04-12 15:33:09243 return nullptr;
[email protected]f6d1d6eb2009-06-24 20:16:09244 }
245
danakj655b66c2016-04-16 00:51:38246 std::unique_ptr<SSLClientSocket> CreateSSLClientSocket(
Matt Menke841fc412019-03-05 23:20:12247 std::unique_ptr<StreamSocket> stream_socket,
[email protected]4f4de7e62010-11-12 19:55:27248 const HostPortPair& host_and_port,
[email protected]7ab5bbd12010-10-19 13:33:21249 const SSLConfig& ssl_config,
mostynbba063d6032014-10-09 11:01:13250 const SSLClientSocketContext& context) override {
[email protected]f6d1d6eb2009-06-24 20:16:09251 NOTIMPLEMENTED();
danakj655b66c2016-04-16 00:51:38252 return std::unique_ptr<SSLClientSocket>();
[email protected]f6d1d6eb2009-06-24 20:16:09253 }
Matt Menkefd956922019-02-04 23:44:03254
Matt Menke52cd95a2019-02-08 06:16:27255 std::unique_ptr<ProxyClientSocket> CreateProxyClientSocket(
256 std::unique_ptr<StreamSocket> stream_socket,
257 const std::string& user_agent,
258 const HostPortPair& endpoint,
259 const ProxyServer& proxy_server,
260 HttpAuthController* http_auth_controller,
261 bool tunnel,
262 bool using_spdy,
263 NextProto negotiated_protocol,
264 ProxyDelegate* proxy_delegate,
265 bool is_https_proxy,
266 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,
[email protected]d80a4322009-08-14 07:07:49318 const TestClientSocketPoolBase::Request& request,
[email protected]974ebd62009-08-03 23:14:34319 base::TimeDelta timeout_duration,
Matt Menkea6f99ad2019-03-08 02:26:43320 const CommonConnectJobParams* common_connect_job_params,
[email protected]ab838892009-06-30 18:49:05321 ConnectJob::Delegate* delegate,
Matt Menkea6f99ad2019-03-08 02:26:43322 MockClientSocketFactory* client_socket_factory)
Matt Menke1a6c92d2019-02-23 00:25:38323 : ConnectJob(request.priority(),
Matt Menkea6f99ad2019-03-08 02:26:43324 request.socket_tag(),
Matt Menke1a6c92d2019-02-23 00:25:38325 timeout_duration,
Matt Menkea6f99ad2019-03-08 02:26:43326 common_connect_job_params,
Matt Menke1a6c92d2019-02-23 00:25:38327 delegate,
328 nullptr /* net_log */,
329 NetLogSourceType::TRANSPORT_CONNECT_JOB,
330 NetLogEventType::TRANSPORT_CONNECT_JOB_CONNECT),
[email protected]2ab05b52009-07-01 23:57:58331 job_type_(job_type),
[email protected]ab838892009-06-30 18:49:05332 client_socket_factory_(client_socket_factory),
[email protected]e60e47a2010-07-14 03:37:18333 load_state_(LOAD_STATE_IDLE),
Matt Menke141b87f22019-01-30 02:43:03334 has_established_connection_(false),
[email protected]d5492c52013-11-10 20:44:39335 store_additional_error_state_(false),
mmenked3641e12016-01-28 16:06:15336 weak_factory_(this) {}
[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
dchengb03027d2014-10-21 12:00:20357 void GetAdditionalErrorState(ClientSocketHandle* handle) override {
[email protected]e60e47a2010-07-14 03:37:18358 if (store_additional_error_state_) {
359 // Set all of the additional error state fields in some way.
360 handle->set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43361 HttpResponseInfo info;
[email protected]007b3f82013-04-09 08:46:45362 info.headers = new HttpResponseHeaders(std::string());
[email protected]8b498692010-07-16 17:11:43363 handle->set_ssl_error_response_info(info);
[email protected]e60e47a2010-07-14 03:37:18364 }
365 }
366
[email protected]974ebd62009-08-03 23:14:34367 private:
[email protected]03b7c8c2013-07-20 04:38:55368 // From ConnectJob:
[email protected]ab838892009-06-30 18:49:05369
dchengb03027d2014-10-21 12:00:20370 int ConnectInternal() override {
[email protected]ab838892009-06-30 18:49:05371 AddressList ignored;
Raul Tambre94493c652019-03-11 17:18:35372 client_socket_factory_->CreateTransportClientSocket(
373 ignored, nullptr, nullptr, NetLogSource());
[email protected]ab838892009-06-30 18:49:05374 switch (job_type_) {
375 case kMockJob:
[email protected]e772db3f2010-07-12 18:11:13376 return DoConnect(true /* successful */, false /* sync */,
Matt Menkeb57663b32019-03-01 17:17:10377 false /* cert_error */);
[email protected]ab838892009-06-30 18:49:05378 case kMockFailingJob:
[email protected]e772db3f2010-07-12 18:11:13379 return DoConnect(false /* error */, false /* sync */,
Matt Menkeb57663b32019-03-01 17:17:10380 false /* cert_error */);
[email protected]ab838892009-06-30 18:49:05381 case kMockPendingJob:
[email protected]5fc08e32009-07-15 17:09:57382 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47383
384 // Depending on execution timings, posting a delayed task can result
385 // in the task getting executed the at the earliest possible
386 // opportunity or only after returning once from the message loop and
387 // then a second call into the message loop. In order to make behavior
388 // more deterministic, we change the default delay to 2ms. This should
389 // always require us to wait for the second call into the message loop.
390 //
391 // N.B. The correct fix for this and similar timing problems is to
392 // abstract time for the purpose of unittests. Unfortunately, we have
393 // a lot of third-party components that directly call the various
394 // time functions, so this change would be rather invasive.
skyostil4891b25b2015-06-11 11:43:45395 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05396 FROM_HERE,
kylecharf4fe5172019-02-15 18:53:49397 base::BindOnce(base::IgnoreResult(&TestConnectJob::DoConnect),
398 weak_factory_.GetWeakPtr(), true /* successful */,
Matt Menkeb57663b32019-03-01 17:17:10399 true /* async */, false /* cert_error */),
[email protected]5761ab9c2012-02-04 16:44:53400 base::TimeDelta::FromMilliseconds(kPendingConnectDelay));
[email protected]ab838892009-06-30 18:49:05401 return ERR_IO_PENDING;
402 case kMockPendingFailingJob:
[email protected]5fc08e32009-07-15 17:09:57403 set_load_state(LOAD_STATE_CONNECTING);
skyostil4891b25b2015-06-11 11:43:45404 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05405 FROM_HERE,
kylecharf4fe5172019-02-15 18:53:49406 base::BindOnce(base::IgnoreResult(&TestConnectJob::DoConnect),
407 weak_factory_.GetWeakPtr(), false /* error */,
Matt Menkeb57663b32019-03-01 17:17:10408 true /* async */, false /* cert_error */),
[email protected]5761ab9c2012-02-04 16:44:53409 base::TimeDelta::FromMilliseconds(2));
[email protected]ab838892009-06-30 18:49:05410 return ERR_IO_PENDING;
[email protected]5fc08e32009-07-15 17:09:57411 case kMockWaitingJob:
[email protected]03b7c8c2013-07-20 04:38:55412 set_load_state(LOAD_STATE_CONNECTING);
[email protected]5fc08e32009-07-15 17:09:57413 client_socket_factory_->WaitForSignal(this);
414 waiting_success_ = true;
415 return ERR_IO_PENDING;
Matt Menkeb57663b32019-03-01 17:17:10416 case kMockCertErrorJob:
[email protected]e772db3f2010-07-12 18:11:13417 return DoConnect(false /* error */, false /* sync */,
Matt Menkeb57663b32019-03-01 17:17:10418 true /* cert_error */);
419 case kMockPendingCertErrorJob:
[email protected]e772db3f2010-07-12 18:11:13420 set_load_state(LOAD_STATE_CONNECTING);
skyostil4891b25b2015-06-11 11:43:45421 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]e772db3f2010-07-12 18:11:13422 FROM_HERE,
kylecharf4fe5172019-02-15 18:53:49423 base::BindOnce(base::IgnoreResult(&TestConnectJob::DoConnect),
424 weak_factory_.GetWeakPtr(), false /* error */,
Matt Menkeb57663b32019-03-01 17:17:10425 true /* async */, true /* cert_error */),
[email protected]5761ab9c2012-02-04 16:44:53426 base::TimeDelta::FromMilliseconds(2));
[email protected]e772db3f2010-07-12 18:11:13427 return ERR_IO_PENDING;
[email protected]e60e47a2010-07-14 03:37:18428 case kMockAdditionalErrorStateJob:
429 store_additional_error_state_ = true;
430 return DoConnect(false /* error */, false /* sync */,
Matt Menkeb57663b32019-03-01 17:17:10431 false /* cert_error */);
[email protected]e60e47a2010-07-14 03:37:18432 case kMockPendingAdditionalErrorStateJob:
433 set_load_state(LOAD_STATE_CONNECTING);
434 store_additional_error_state_ = true;
skyostil4891b25b2015-06-11 11:43:45435 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]e60e47a2010-07-14 03:37:18436 FROM_HERE,
kylecharf4fe5172019-02-15 18:53:49437 base::BindOnce(base::IgnoreResult(&TestConnectJob::DoConnect),
438 weak_factory_.GetWeakPtr(), false /* error */,
Matt Menkeb57663b32019-03-01 17:17:10439 true /* async */, false /* cert_error */),
[email protected]5761ab9c2012-02-04 16:44:53440 base::TimeDelta::FromMilliseconds(2));
[email protected]e60e47a2010-07-14 03:37:18441 return ERR_IO_PENDING;
[email protected]0dc88b32014-03-26 20:12:28442 case kMockUnreadDataJob: {
443 int ret = DoConnect(true /* successful */, false /* sync */,
Matt Menkeb57663b32019-03-01 17:17:10444 false /* cert_error */);
[email protected]0dc88b32014-03-26 20:12:28445 static_cast<MockClientSocket*>(socket())->set_has_unread_data(true);
446 return ret;
447 }
Matt Menkeb57663b32019-03-01 17:17:10448 case kMockAuthChallengeOnceJob:
Matt Menke4b69f932019-03-04 16:20:01449 set_load_state(LOAD_STATE_CONNECTING);
Matt Menkeb57663b32019-03-01 17:17:10450 DoAdvanceAuthChallenge(1, true /* succeed_after_last_challenge */);
451 return ERR_IO_PENDING;
452 case kMockAuthChallengeTwiceJob:
Matt Menke4b69f932019-03-04 16:20:01453 set_load_state(LOAD_STATE_CONNECTING);
Matt Menkeb57663b32019-03-01 17:17:10454 DoAdvanceAuthChallenge(2, true /* succeed_after_last_challenge */);
455 return ERR_IO_PENDING;
456 case kMockAuthChallengeOnceFailingJob:
Matt Menke4b69f932019-03-04 16:20:01457 set_load_state(LOAD_STATE_CONNECTING);
Matt Menkeb57663b32019-03-01 17:17:10458 DoAdvanceAuthChallenge(1, false /* succeed_after_last_challenge */);
459 return ERR_IO_PENDING;
460 case kMockAuthChallengeTwiceFailingJob:
Matt Menke4b69f932019-03-04 16:20:01461 set_load_state(LOAD_STATE_CONNECTING);
Matt Menkeb57663b32019-03-01 17:17:10462 DoAdvanceAuthChallenge(2, false /* succeed_after_last_challenge */);
463 return ERR_IO_PENDING;
[email protected]ab838892009-06-30 18:49:05464 default:
465 NOTREACHED();
danakj655b66c2016-04-16 00:51:38466 SetSocket(std::unique_ptr<StreamSocket>());
[email protected]ab838892009-06-30 18:49:05467 return ERR_FAILED;
468 }
469 }
470
Lily Chen02ef29a2018-11-30 16:31:43471 void ChangePriorityInternal(RequestPriority priority) override {}
472
Matt Menkeb57663b32019-03-01 17:17:10473 int DoConnect(bool succeed, bool was_async, bool cert_error) {
[email protected]e772db3f2010-07-12 18:11:13474 int result = OK;
Matt Menke141b87f22019-01-30 02:43:03475 has_established_connection_ = true;
[email protected]ab838892009-06-30 18:49:05476 if (succeed) {
Matt Menkeb57663b32019-03-01 17:17:10477 SetSocket(std::make_unique<MockClientSocket>(net_log().net_log()));
Bence Békybdbb0e72018-08-07 21:42:59478 socket()->Connect(CompletionOnceCallback());
Matt Menkeb57663b32019-03-01 17:17:10479 } else if (cert_error) {
480 SetSocket(std::make_unique<MockClientSocket>(net_log().net_log()));
481 result = ERR_CERT_COMMON_NAME_INVALID;
[email protected]6e713f02009-08-06 02:56:40482 } else {
[email protected]e772db3f2010-07-12 18:11:13483 result = ERR_CONNECTION_FAILED;
danakj655b66c2016-04-16 00:51:38484 SetSocket(std::unique_ptr<StreamSocket>());
[email protected]ab838892009-06-30 18:49:05485 }
[email protected]2ab05b52009-07-01 23:57:58486
487 if (was_async)
[email protected]fd7b7c92009-08-20 19:38:30488 NotifyDelegateOfCompletion(result);
[email protected]ab838892009-06-30 18:49:05489 return result;
490 }
491
Matt Menkeb57663b32019-03-01 17:17:10492 void DoAdvanceAuthChallenge(int remaining_challenges,
493 bool succeed_after_last_challenge) {
494 base::ThreadTaskRunnerHandle::Get()->PostTask(
495 FROM_HERE,
496 base::BindOnce(&TestConnectJob::InvokeNextProxyAuthCallback,
497 weak_factory_.GetWeakPtr(), remaining_challenges,
498 succeed_after_last_challenge));
499 }
500
501 void InvokeNextProxyAuthCallback(int remaining_challenges,
502 bool succeed_after_last_challenge) {
Matt Menke4b69f932019-03-04 16:20:01503 set_load_state(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL);
Matt Menkeb57663b32019-03-01 17:17:10504 if (remaining_challenges == 0) {
505 DoConnect(succeed_after_last_challenge, true /* was_async */,
506 false /* cert_error */);
507 return;
508 }
509
510 // Integration tests make sure HttpResponseInfo and HttpAuthController work.
511 // The auth tests here are just focused on ConnectJob bookkeeping.
512 HttpResponseInfo info;
513 NotifyDelegateOfProxyAuth(
514 info, nullptr /* http_auth_controller */,
515 base::BindOnce(&TestConnectJob::DoAdvanceAuthChallenge,
516 weak_factory_.GetWeakPtr(), remaining_challenges - 1,
517 succeed_after_last_challenge));
518 }
519
[email protected]5fc08e32009-07-15 17:09:57520 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05521 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57522 MockClientSocketFactory* const client_socket_factory_;
[email protected]46451352009-09-01 14:54:21523 LoadState load_state_;
Matt Menke141b87f22019-01-30 02:43:03524 bool has_established_connection_;
[email protected]e60e47a2010-07-14 03:37:18525 bool store_additional_error_state_;
[email protected]ab838892009-06-30 18:49:05526
[email protected]d5492c52013-11-10 20:44:39527 base::WeakPtrFactory<TestConnectJob> weak_factory_;
528
[email protected]ab838892009-06-30 18:49:05529 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
530};
531
[email protected]d80a4322009-08-14 07:07:49532class TestConnectJobFactory
533 : public TestClientSocketPoolBase::ConnectJobFactory {
[email protected]ab838892009-06-30 18:49:05534 public:
[email protected]034df0f32013-01-07 23:17:48535 TestConnectJobFactory(MockClientSocketFactory* client_socket_factory,
536 NetLog* net_log)
Matt Menkea6f99ad2019-03-08 02:26:43537 : common_connect_job_params_(
538 nullptr /* client_socket_factory */,
539 nullptr /* host_resolver */,
Matt Menkeb88837e2019-03-20 11:50:40540 nullptr /* http_auth_cache */,
541 nullptr /* http_auth_handler_factory */,
542 nullptr /* spdy_session_pool */,
543 nullptr /* quic_stream_factory */,
Matt Menkea6f99ad2019-03-08 02:26:43544 nullptr /* proxy_delegate */,
Matt Menked732ea42019-03-08 12:05:00545 nullptr /* http_user_agent_settings */,
Matt Menkea6f99ad2019-03-08 02:26:43546 SSLClientSocketContext(),
547 SSLClientSocketContext(),
548 nullptr /* socket_performance_watcher_factory */,
549 nullptr /* network_quality_estimator */,
550 net_log,
551 nullptr /* websocket_endpoint_lock_manager */),
552 job_type_(TestConnectJob::kMockJob),
Raul Tambre94493c652019-03-11 17:18:35553 job_types_(nullptr),
Matt Menkea6f99ad2019-03-08 02:26:43554 client_socket_factory_(client_socket_factory) {}
[email protected]ab838892009-06-30 18:49:05555
Chris Watkins7a41d3552017-12-01 02:13:27556 ~TestConnectJobFactory() override = default;
[email protected]ab838892009-06-30 18:49:05557
558 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
559
[email protected]51fdc7c2012-04-10 19:19:48560 void set_job_types(std::list<TestConnectJob::JobType>* job_types) {
561 job_types_ = job_types;
562 CHECK(!job_types_->empty());
563 }
564
[email protected]974ebd62009-08-03 23:14:34565 void set_timeout_duration(base::TimeDelta timeout_duration) {
566 timeout_duration_ = timeout_duration;
567 }
568
[email protected]3f55aa12011-12-07 02:03:33569 // ConnectJobFactory implementation.
[email protected]83039bb2011-12-09 18:43:55570
danakj655b66c2016-04-16 00:51:38571 std::unique_ptr<ConnectJob> NewConnectJob(
[email protected]d80a4322009-08-14 07:07:49572 const TestClientSocketPoolBase::Request& request,
mostynbba063d6032014-10-09 11:01:13573 ConnectJob::Delegate* delegate) const override {
[email protected]51fdc7c2012-04-10 19:19:48574 EXPECT_TRUE(!job_types_ || !job_types_->empty());
575 TestConnectJob::JobType job_type = job_type_;
576 if (job_types_ && !job_types_->empty()) {
577 job_type = job_types_->front();
578 job_types_->pop_front();
579 }
Matt Menkea6f99ad2019-03-08 02:26:43580 return std::make_unique<TestConnectJob>(
581 job_type, request, timeout_duration_, &common_connect_job_params_,
582 delegate, client_socket_factory_);
[email protected]ab838892009-06-30 18:49:05583 }
584
585 private:
Matt Menkea6f99ad2019-03-08 02:26:43586 const CommonConnectJobParams common_connect_job_params_;
[email protected]ab838892009-06-30 18:49:05587 TestConnectJob::JobType job_type_;
[email protected]51fdc7c2012-04-10 19:19:48588 std::list<TestConnectJob::JobType>* job_types_;
[email protected]974ebd62009-08-03 23:14:34589 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57590 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05591
592 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
593};
594
595class TestClientSocketPool : public ClientSocketPool {
596 public:
[email protected]12322e7e2013-08-15 17:49:26597 typedef TestSocketParams SocketParams;
598
[email protected]ab838892009-06-30 18:49:05599 TestClientSocketPool(
[email protected]211d21722009-07-22 15:48:53600 int max_sockets,
[email protected]ab838892009-06-30 18:49:05601 int max_sockets_per_group,
[email protected]9bf28db2009-08-29 01:35:16602 base::TimeDelta unused_idle_socket_timeout,
603 base::TimeDelta used_idle_socket_timeout,
[email protected]d80a4322009-08-14 07:07:49604 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
Matt Menke833678642019-03-05 22:05:51605 : base_(max_sockets,
rkaplowd90695c2015-03-25 22:12:41606 max_sockets_per_group,
607 unused_idle_socket_timeout,
608 used_idle_socket_timeout,
[email protected]66761b952010-06-25 21:30:38609 connect_job_factory) {}
[email protected]ab838892009-06-30 18:49:05610
Chris Watkins7a41d3552017-12-01 02:13:27611 ~TestClientSocketPool() override = default;
[email protected]2431756e2010-09-29 20:26:13612
Matt Menkef6edce752019-03-19 17:21:56613 int RequestSocket(const GroupId& group_id,
dchengb03027d2014-10-21 12:00:20614 const void* params,
ttuttle859dc7a2015-04-23 19:42:29615 RequestPriority priority,
Paul Jensen8d6f87ec2018-01-13 00:46:54616 const SocketTag& socket_tag,
mmenked3641e12016-01-28 16:06:15617 RespectLimits respect_limits,
dchengb03027d2014-10-21 12:00:20618 ClientSocketHandle* handle,
Bence Béky5a8662b2018-07-03 13:04:03619 CompletionOnceCallback callback,
Matt Menke28ac03e2019-02-25 22:25:50620 const ProxyAuthCallback& proxy_auth_callback,
tfarina428341112016-09-22 13:38:20621 const NetLogWithSource& net_log) override {
[email protected]df4b4ef2010-07-12 18:25:21622 const scoped_refptr<TestSocketParams>* casted_socket_params =
623 static_cast<const scoped_refptr<TestSocketParams>*>(params);
Matt Menke28ac03e2019-02-25 22:25:50624 return base_.RequestSocket(
Matt Menkef6edce752019-03-19 17:21:56625 group_id, *casted_socket_params, priority, socket_tag, respect_limits,
Matt Menke28ac03e2019-02-25 22:25:50626 handle, std::move(callback), proxy_auth_callback, net_log);
[email protected]ab838892009-06-30 18:49:05627 }
628
Matt Menkef6edce752019-03-19 17:21:56629 void RequestSockets(const GroupId& group_id,
dchengb03027d2014-10-21 12:00:20630 const void* params,
631 int num_sockets,
Charlie Harrison55ce6082018-05-14 02:25:57632 const NetLogWithSource& net_log) override {
[email protected]2c2bef152010-10-13 00:55:03633 const scoped_refptr<TestSocketParams>* casted_params =
634 static_cast<const scoped_refptr<TestSocketParams>*>(params);
635
Matt Menkef6edce752019-03-19 17:21:56636 base_.RequestSockets(group_id, *casted_params, num_sockets, net_log);
[email protected]2c2bef152010-10-13 00:55:03637 }
638
Matt Menkef6edce752019-03-19 17:21:56639 void SetPriority(const GroupId& group_id,
rdsmith29dbad12017-02-17 02:22:18640 ClientSocketHandle* handle,
641 RequestPriority priority) override {
Matt Menkef6edce752019-03-19 17:21:56642 base_.SetPriority(group_id, handle, priority);
rdsmith29dbad12017-02-17 02:22:18643 }
644
Matt Menkef6edce752019-03-19 17:21:56645 void CancelRequest(const GroupId& group_id,
dchengb03027d2014-10-21 12:00:20646 ClientSocketHandle* handle) override {
Matt Menkef6edce752019-03-19 17:21:56647 base_.CancelRequest(group_id, handle);
[email protected]ab838892009-06-30 18:49:05648 }
649
Matt Menkef6edce752019-03-19 17:21:56650 void ReleaseSocket(const GroupId& group_id,
danakj655b66c2016-04-16 00:51:38651 std::unique_ptr<StreamSocket> socket,
dchengb03027d2014-10-21 12:00:20652 int id) override {
Matt Menkef6edce752019-03-19 17:21:56653 base_.ReleaseSocket(group_id, std::move(socket), id);
[email protected]a7e38572010-06-07 18:22:24654 }
655
dchengb03027d2014-10-21 12:00:20656 void FlushWithError(int error) override { base_.FlushWithError(error); }
[email protected]ab838892009-06-30 18:49:05657
dchengb03027d2014-10-21 12:00:20658 bool IsStalled() const override { return base_.IsStalled(); }
[email protected]51fdc7c2012-04-10 19:19:48659
dchengb03027d2014-10-21 12:00:20660 void CloseIdleSockets() override { base_.CloseIdleSockets(); }
[email protected]ab838892009-06-30 18:49:05661
Matt Menkef6edce752019-03-19 17:21:56662 void CloseIdleSocketsInGroup(const GroupId& group_id) override {
663 base_.CloseIdleSocketsInGroup(group_id);
xunjieli92feb332017-03-03 17:19:23664 }
665
dchengb03027d2014-10-21 12:00:20666 int IdleSocketCount() const override { return base_.idle_socket_count(); }
[email protected]ab838892009-06-30 18:49:05667
Matt Menkef6edce752019-03-19 17:21:56668 size_t IdleSocketCountInGroup(const GroupId& group_id) const override {
669 return base_.IdleSocketCountInGroup(group_id);
[email protected]ab838892009-06-30 18:49:05670 }
671
Matt Menkef6edce752019-03-19 17:21:56672 LoadState GetLoadState(const GroupId& group_id,
dchengb03027d2014-10-21 12:00:20673 const ClientSocketHandle* handle) const override {
Matt Menkef6edce752019-03-19 17:21:56674 return base_.GetLoadState(group_id, handle);
[email protected]ab838892009-06-30 18:49:05675 }
676
dchengb03027d2014-10-21 12:00:20677 void AddHigherLayeredPool(HigherLayeredPool* higher_pool) override {
[email protected]043b68c82013-08-22 23:41:52678 base_.AddHigherLayeredPool(higher_pool);
[email protected]51fdc7c2012-04-10 19:19:48679 }
680
dchengb03027d2014-10-21 12:00:20681 void RemoveHigherLayeredPool(HigherLayeredPool* higher_pool) override {
[email protected]043b68c82013-08-22 23:41:52682 base_.RemoveHigherLayeredPool(higher_pool);
[email protected]51fdc7c2012-04-10 19:19:48683 }
684
danakj655b66c2016-04-16 00:51:38685 std::unique_ptr<base::DictionaryValue> GetInfoAsValue(
[email protected]d4dfdab2011-12-07 16:56:59686 const std::string& name,
Matt Menke833678642019-03-05 22:05:51687 const std::string& type) const override {
[email protected]59d7a5a2010-08-30 16:44:27688 return base_.GetInfoAsValue(name, type);
689 }
690
[email protected]d80a4322009-08-14 07:07:49691 const TestClientSocketPoolBase* base() const { return &base_; }
[email protected]c9d6a1d2009-07-14 16:15:20692
Matt Menkef6edce752019-03-19 17:21:56693 size_t NumNeverAssignedConnectJobsInGroup(const GroupId& group_id) const {
694 return base_.NumNeverAssignedConnectJobsInGroup(group_id);
Lily Chenecebf932018-11-02 17:15:43695 }
696
Matt Menkef6edce752019-03-19 17:21:56697 size_t NumUnassignedConnectJobsInGroup(const GroupId& group_id) const {
698 return base_.NumUnassignedConnectJobsInGroup(group_id);
[email protected]8159a1c2012-06-07 00:00:10699 }
700
Matt Menkef6edce752019-03-19 17:21:56701 size_t NumConnectJobsInGroup(const GroupId& group_id) const {
702 return base_.NumConnectJobsInGroup(group_id);
[email protected]974ebd62009-08-03 23:14:34703 }
704
Matt Menkef6edce752019-03-19 17:21:56705 int NumActiveSocketsInGroup(const GroupId& group_id) const {
706 return base_.NumActiveSocketsInGroup(group_id);
[email protected]2c2bef152010-10-13 00:55:03707 }
708
Lily Chenecebf932018-11-02 17:15:43709 bool RequestInGroupWithHandleHasJobForTesting(
Matt Menkef6edce752019-03-19 17:21:56710 const GroupId& group_id,
Lily Chenecebf932018-11-02 17:15:43711 const ClientSocketHandle* handle) const {
Matt Menkef6edce752019-03-19 17:21:56712 return base_.RequestInGroupWithHandleHasJobForTesting(group_id, handle);
Lily Chenecebf932018-11-02 17:15:43713 }
714
Matt Menkef6edce752019-03-19 17:21:56715 bool HasGroup(const GroupId& group_id) const {
716 return base_.HasGroup(group_id);
[email protected]2abfe90a2010-08-25 17:49:51717 }
718
[email protected]9bf28db2009-08-29 01:35:16719 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
720
[email protected]06d94042010-08-25 01:45:22721 void EnableConnectBackupJobs() { base_.EnableConnectBackupJobs(); }
[email protected]43a21b82010-06-10 21:30:54722
[email protected]ab838892009-06-30 18:49:05723 private:
[email protected]d80a4322009-08-14 07:07:49724 TestClientSocketPoolBase base_;
[email protected]ab838892009-06-30 18:49:05725
726 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
727};
728
[email protected]a937a06d2009-08-19 21:19:24729} // namespace
730
[email protected]a937a06d2009-08-19 21:19:24731namespace {
732
[email protected]5fc08e32009-07-15 17:09:57733void MockClientSocketFactory::SignalJobs() {
jdoerrie22a91d8b92018-10-05 08:43:26734 for (auto it = waiting_jobs_.begin(); it != waiting_jobs_.end(); ++it) {
[email protected]5fc08e32009-07-15 17:09:57735 (*it)->Signal();
736 }
737 waiting_jobs_.clear();
738}
739
[email protected]03b7c8c2013-07-20 04:38:55740void MockClientSocketFactory::SignalJob(size_t job) {
741 ASSERT_LT(job, waiting_jobs_.size());
742 waiting_jobs_[job]->Signal();
743 waiting_jobs_.erase(waiting_jobs_.begin() + job);
744}
745
746void MockClientSocketFactory::SetJobLoadState(size_t job,
747 LoadState load_state) {
748 ASSERT_LT(job, waiting_jobs_.size());
749 waiting_jobs_[job]->set_load_state(load_state);
750}
751
Matt Menke141b87f22019-01-30 02:43:03752void MockClientSocketFactory::SetJobHasEstablishedConnection(size_t job) {
753 ASSERT_LT(job, waiting_jobs_.size());
754 waiting_jobs_[job]->set_has_established_connection();
755}
756
Bence Béky98447b12018-05-08 03:14:01757class ClientSocketPoolBaseTest : public TestWithScopedTaskEnvironment {
[email protected]f6d1d6eb2009-06-24 20:16:09758 protected:
Alex Clarke0def2092018-12-10 12:01:45759 ClientSocketPoolBaseTest()
760 : TestWithScopedTaskEnvironment(
761 base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME),
762 params_(new TestSocketParams()) {
[email protected]636b8252011-04-08 19:56:54763 connect_backup_jobs_enabled_ =
764 internal::ClientSocketPoolBaseHelper::connect_backup_jobs_enabled();
765 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(true);
766 }
[email protected]2431756e2010-09-29 20:26:13767
dcheng67be2b1f2014-10-27 21:47:29768 ~ClientSocketPoolBaseTest() override {
[email protected]636b8252011-04-08 19:56:54769 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(
770 connect_backup_jobs_enabled_);
771 }
[email protected]c9d6a1d2009-07-14 16:15:20772
[email protected]211d21722009-07-22 15:48:53773 void CreatePool(int max_sockets, int max_sockets_per_group) {
Tarun Bansala7635092019-02-20 10:00:59774 CreatePoolWithIdleTimeouts(max_sockets, max_sockets_per_group,
775 kUnusedIdleSocketTimeout,
776 ClientSocketPool::used_idle_socket_timeout());
[email protected]9bf28db2009-08-29 01:35:16777 }
778
779 void CreatePoolWithIdleTimeouts(
780 int max_sockets, int max_sockets_per_group,
781 base::TimeDelta unused_idle_socket_timeout,
782 base::TimeDelta used_idle_socket_timeout) {
[email protected]c9d6a1d2009-07-14 16:15:20783 DCHECK(!pool_.get());
[email protected]034df0f32013-01-07 23:17:48784 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_,
785 &net_log_);
[email protected]2431756e2010-09-29 20:26:13786 pool_.reset(new TestClientSocketPool(max_sockets,
787 max_sockets_per_group,
[email protected]2431756e2010-09-29 20:26:13788 unused_idle_socket_timeout,
789 used_idle_socket_timeout,
790 connect_job_factory_));
[email protected]c9d6a1d2009-07-14 16:15:20791 }
[email protected]f6d1d6eb2009-06-24 20:16:09792
mmenked3641e12016-01-28 16:06:15793 int StartRequestWithIgnoreLimits(
Matt Menkec6b3edf72019-03-19 17:00:39794 const ClientSocketPool::GroupId& group_id,
[email protected]b021ece62013-06-11 11:06:33795 RequestPriority priority,
mmenked3641e12016-01-28 16:06:15796 ClientSocketPool::RespectLimits respect_limits) {
Matt Menkec6b3edf72019-03-19 17:00:39797 return test_base_.StartRequestUsingPool(pool_.get(), group_id, priority,
mmenked3641e12016-01-28 16:06:15798 respect_limits, params_);
[email protected]b021ece62013-06-11 11:06:33799 }
800
Matt Menkec6b3edf72019-03-19 17:00:39801 int StartRequest(const ClientSocketPool::GroupId& group_id,
802 RequestPriority priority) {
mmenked3641e12016-01-28 16:06:15803 return StartRequestWithIgnoreLimits(
Matt Menkec6b3edf72019-03-19 17:00:39804 group_id, priority, ClientSocketPool::RespectLimits::ENABLED);
[email protected]f6d1d6eb2009-06-24 20:16:09805 }
806
[email protected]2431756e2010-09-29 20:26:13807 int GetOrderOfRequest(size_t index) const {
808 return test_base_.GetOrderOfRequest(index);
[email protected]f6d1d6eb2009-06-24 20:16:09809 }
810
[email protected]2431756e2010-09-29 20:26:13811 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
812 return test_base_.ReleaseOneConnection(keep_alive);
813 }
814
815 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
816 test_base_.ReleaseAllConnections(keep_alive);
817 }
818
819 TestSocketRequest* request(int i) { return test_base_.request(i); }
820 size_t requests_size() const { return test_base_.requests_size(); }
danakj655b66c2016-04-16 00:51:38821 std::vector<std::unique_ptr<TestSocketRequest>>* requests() {
olli.raula9d66b7d2015-11-23 08:30:42822 return test_base_.requests();
823 }
rdsmith29dbad12017-02-17 02:22:18824 // Only counts the requests that get sockets asynchronously;
825 // synchronous completions are not registered by this count.
[email protected]2431756e2010-09-29 20:26:13826 size_t completion_count() const { return test_base_.completion_count(); }
827
vishal.b62985ca92015-04-17 08:45:51828 TestNetLog net_log_;
[email protected]636b8252011-04-08 19:56:54829 bool connect_backup_jobs_enabled_;
[email protected]f6d1d6eb2009-06-24 20:16:09830 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04831 TestConnectJobFactory* connect_job_factory_;
[email protected]df4b4ef2010-07-12 18:25:21832 scoped_refptr<TestSocketParams> params_;
danakj655b66c2016-04-16 00:51:38833 std::unique_ptr<TestClientSocketPool> pool_;
[email protected]2431756e2010-09-29 20:26:13834 ClientSocketPoolTest test_base_;
[email protected]f6d1d6eb2009-06-24 20:16:09835};
836
[email protected]5fc08e32009-07-15 17:09:57837TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53838 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20839
[email protected]6ecf2b92011-12-15 01:14:52840 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06841 ClientSocketHandle handle;
vishal.b62985ca92015-04-17 08:45:51842 BoundTestNetLog log;
[email protected]034df0f32013-01-07 23:17:48843 TestLoadTimingInfoNotConnected(handle);
[email protected]9e743cd2010-03-16 07:03:53844
Matt Menkec6b3edf72019-03-19 17:00:39845 EXPECT_EQ(
846 OK, handle.Init(
847 TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
848 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
849 ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound()));
[email protected]f6d1d6eb2009-06-24 20:16:09850 EXPECT_TRUE(handle.is_initialized());
851 EXPECT_TRUE(handle.socket());
[email protected]034df0f32013-01-07 23:17:48852 TestLoadTimingInfoConnectedNotReused(handle);
853
[email protected]f6d1d6eb2009-06-24 20:16:09854 handle.Reset();
[email protected]034df0f32013-01-07 23:17:48855 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:30856
mmenke43758e62015-05-04 21:09:46857 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40858 log.GetEntries(&entries);
859
860 EXPECT_EQ(4u, entries.size());
mikecirone8b85c432016-09-08 19:11:00861 EXPECT_TRUE(LogContainsBeginEvent(entries, 0, NetLogEventType::SOCKET_POOL));
[email protected]9e743cd2010-03-16 07:03:53862 EXPECT_TRUE(LogContainsEvent(
mikecirone8b85c432016-09-08 19:11:00863 entries, 1, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
864 NetLogEventPhase::NONE));
865 EXPECT_TRUE(LogContainsEvent(entries, 2,
866 NetLogEventType::SOCKET_POOL_BOUND_TO_SOCKET,
867 NetLogEventPhase::NONE));
868 EXPECT_TRUE(LogContainsEndEvent(entries, 3, NetLogEventType::SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09869}
870
[email protected]ab838892009-06-30 18:49:05871TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53872 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20873
[email protected]ab838892009-06-30 18:49:05874 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
vishal.b62985ca92015-04-17 08:45:51875 BoundTestNetLog log;
[email protected]9e743cd2010-03-16 07:03:53876
[email protected]2431756e2010-09-29 20:26:13877 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:52878 TestCompletionCallback callback;
[email protected]e60e47a2010-07-14 03:37:18879 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:13880 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43881 HttpResponseInfo info;
[email protected]007b3f82013-04-09 08:46:45882 info.headers = new HttpResponseHeaders(std::string());
[email protected]2431756e2010-09-29 20:26:13883 handle.set_ssl_error_response_info(info);
Matt Menke28ac03e2019-02-25 22:25:50884 EXPECT_EQ(
885 ERR_CONNECTION_FAILED,
Matt Menkec6b3edf72019-03-19 17:00:39886 handle.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:50887 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
888 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
889 log.bound()));
[email protected]2431756e2010-09-29 20:26:13890 EXPECT_FALSE(handle.socket());
891 EXPECT_FALSE(handle.is_ssl_error());
Raul Tambre94493c652019-03-11 17:18:35892 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == nullptr);
[email protected]034df0f32013-01-07 23:17:48893 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:30894
mmenke43758e62015-05-04 21:09:46895 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40896 log.GetEntries(&entries);
897
898 EXPECT_EQ(3u, entries.size());
mikecirone8b85c432016-09-08 19:11:00899 EXPECT_TRUE(LogContainsBeginEvent(entries, 0, NetLogEventType::SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:17900 EXPECT_TRUE(LogContainsEvent(
mikecirone8b85c432016-09-08 19:11:00901 entries, 1, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
902 NetLogEventPhase::NONE));
903 EXPECT_TRUE(LogContainsEndEvent(entries, 2, NetLogEventType::SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09904}
905
Matt Menkef6edce752019-03-19 17:21:56906// Make sure different groups do not share sockets.
907TEST_F(ClientSocketPoolBaseTest, GroupSeparation) {
908 CreatePool(1000 /* max_sockets */, 2 /* max_sockets_per_group */);
909
910 const HostPortPair kHostPortPairs[] = {
911 {"a", 80},
912 {"a", 443},
913 {"b", 80},
914 };
915
916 const ClientSocketPool::SocketType kSocketTypes[] = {
917 ClientSocketPool::SocketType::kHttp,
918 ClientSocketPool::SocketType::kSsl,
919 ClientSocketPool::SocketType::kSslVersionInterferenceProbe,
920 ClientSocketPool::SocketType::kFtp,
921 };
922
923 const bool kPrivacyModes[] = {false, true};
924
925 int total_idle_sockets = 0;
926
927 // Walk through each GroupId, making sure that requesting a socket for one
928 // group does not return a previously connected socket for another group.
929 for (const auto& host_port_pair : kHostPortPairs) {
930 SCOPED_TRACE(host_port_pair.ToString());
931 for (const auto& socket_type : kSocketTypes) {
932 SCOPED_TRACE(static_cast<int>(socket_type));
933 for (const auto& privacy_mode : kPrivacyModes) {
934 SCOPED_TRACE(privacy_mode);
935
936 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
937
938 ClientSocketPool::GroupId group_id(host_port_pair, socket_type,
939 privacy_mode);
940
941 EXPECT_FALSE(pool_->HasGroup(group_id));
942
943 TestCompletionCallback callback;
944 ClientSocketHandle handle;
945
946 // Since the group is empty, requesting a socket should not complete
947 // synchronously.
948 EXPECT_THAT(
949 handle.Init(group_id, params_, DEFAULT_PRIORITY, SocketTag(),
950 ClientSocketPool::RespectLimits::ENABLED,
951 callback.callback(),
952 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
953 NetLogWithSource()),
954 IsError(ERR_IO_PENDING));
955 EXPECT_TRUE(pool_->HasGroup(group_id));
956 EXPECT_EQ(total_idle_sockets, pool_->IdleSocketCount());
957
958 EXPECT_THAT(callback.WaitForResult(), IsOk());
959 EXPECT_TRUE(handle.socket());
960 EXPECT_TRUE(pool_->HasGroup(group_id));
961 EXPECT_EQ(total_idle_sockets, pool_->IdleSocketCount());
962
963 // Return socket to pool.
964 handle.Reset();
965 EXPECT_EQ(total_idle_sockets + 1, pool_->IdleSocketCount());
966
967 // Requesting a socket again should return the same socket as before, so
968 // should complete synchronously.
969 EXPECT_THAT(
970 handle.Init(group_id, params_, DEFAULT_PRIORITY, SocketTag(),
971 ClientSocketPool::RespectLimits::ENABLED,
972 callback.callback(),
973 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
974 NetLogWithSource()),
975 IsOk());
976 EXPECT_TRUE(handle.socket());
977 EXPECT_EQ(total_idle_sockets, pool_->IdleSocketCount());
978
979 // Return socket to pool again.
980 handle.Reset();
981 EXPECT_EQ(total_idle_sockets + 1, pool_->IdleSocketCount());
982
983 ++total_idle_sockets;
984 }
985 }
986 }
987}
988
[email protected]211d21722009-07-22 15:48:53989TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
990 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
991
[email protected]9e743cd2010-03-16 07:03:53992 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30993
Matt Menkec6b3edf72019-03-19 17:00:39994 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
995 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
996 EXPECT_THAT(StartRequest(TestGroupId("c"), DEFAULT_PRIORITY), IsOk());
997 EXPECT_THAT(StartRequest(TestGroupId("d"), DEFAULT_PRIORITY), IsOk());
[email protected]211d21722009-07-22 15:48:53998
[email protected]2431756e2010-09-29 20:26:13999 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531000 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131001 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:531002
Matt Menkec6b3edf72019-03-19 17:00:391003 EXPECT_THAT(StartRequest(TestGroupId("e"), DEFAULT_PRIORITY),
1004 IsError(ERR_IO_PENDING));
1005 EXPECT_THAT(StartRequest(TestGroupId("f"), DEFAULT_PRIORITY),
1006 IsError(ERR_IO_PENDING));
1007 EXPECT_THAT(StartRequest(TestGroupId("g"), DEFAULT_PRIORITY),
1008 IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:531009
[email protected]2431756e2010-09-29 20:26:131010 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:531011
[email protected]2431756e2010-09-29 20:26:131012 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531013 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131014 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:531015
1016 EXPECT_EQ(1, GetOrderOfRequest(1));
1017 EXPECT_EQ(2, GetOrderOfRequest(2));
1018 EXPECT_EQ(3, GetOrderOfRequest(3));
1019 EXPECT_EQ(4, GetOrderOfRequest(4));
1020 EXPECT_EQ(5, GetOrderOfRequest(5));
1021 EXPECT_EQ(6, GetOrderOfRequest(6));
1022 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171023
1024 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131025 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:531026}
1027
1028TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
1029 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1030
[email protected]9e743cd2010-03-16 07:03:531031 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:301032
[email protected]211d21722009-07-22 15:48:531033 // Reach all limits: max total sockets, and max sockets per group.
Matt Menkec6b3edf72019-03-19 17:00:391034 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1035 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1036 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
1037 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
[email protected]211d21722009-07-22 15:48:531038
[email protected]2431756e2010-09-29 20:26:131039 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531040 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131041 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:531042
1043 // Now create a new group and verify that we don't starve it.
Matt Menkec6b3edf72019-03-19 17:00:391044 EXPECT_THAT(StartRequest(TestGroupId("c"), DEFAULT_PRIORITY),
1045 IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:531046
[email protected]2431756e2010-09-29 20:26:131047 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:531048
[email protected]2431756e2010-09-29 20:26:131049 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531050 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131051 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:531052
1053 EXPECT_EQ(1, GetOrderOfRequest(1));
1054 EXPECT_EQ(2, GetOrderOfRequest(2));
1055 EXPECT_EQ(3, GetOrderOfRequest(3));
1056 EXPECT_EQ(4, GetOrderOfRequest(4));
1057 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:171058
1059 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131060 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:531061}
1062
1063TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
1064 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1065
Matt Menkec6b3edf72019-03-19 17:00:391066 EXPECT_THAT(StartRequest(TestGroupId("b"), LOWEST), IsOk());
1067 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsOk());
1068 EXPECT_THAT(StartRequest(TestGroupId("b"), HIGHEST), IsOk());
1069 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsOk());
[email protected]211d21722009-07-22 15:48:531070
[email protected]2431756e2010-09-29 20:26:131071 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531072 client_socket_factory_.allocation_count());
1073
Matt Menkec6b3edf72019-03-19 17:00:391074 EXPECT_THAT(StartRequest(TestGroupId("c"), LOWEST), IsError(ERR_IO_PENDING));
1075 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1076 EXPECT_THAT(StartRequest(TestGroupId("b"), HIGHEST), IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:531077
[email protected]2431756e2010-09-29 20:26:131078 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:531079
[email protected]2431756e2010-09-29 20:26:131080 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:531081
1082 // First 4 requests don't have to wait, and finish in order.
1083 EXPECT_EQ(1, GetOrderOfRequest(1));
1084 EXPECT_EQ(2, GetOrderOfRequest(2));
1085 EXPECT_EQ(3, GetOrderOfRequest(3));
1086 EXPECT_EQ(4, GetOrderOfRequest(4));
1087
Matt Menkec6b3edf72019-03-19 17:00:391088 // Request ("b", HIGHEST) has the highest priority, then (TestGroupId("a"),
1089 // MEDIUM), and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:531090 EXPECT_EQ(7, GetOrderOfRequest(5));
1091 EXPECT_EQ(6, GetOrderOfRequest(6));
1092 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171093
1094 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131095 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]211d21722009-07-22 15:48:531096}
1097
rdsmith29dbad12017-02-17 02:22:181098// Test reprioritizing a request before completion doesn't interfere with
1099// its completion.
1100TEST_F(ClientSocketPoolBaseTest, ReprioritizeOne) {
1101 CreatePool(kDefaultMaxSockets, 1);
1102
Matt Menkec6b3edf72019-03-19 17:00:391103 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(OK));
1104 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
rdsmith29dbad12017-02-17 02:22:181105 EXPECT_TRUE(request(0)->handle()->socket());
1106 EXPECT_FALSE(request(1)->handle()->socket());
1107
Lily Chenecebf932018-11-02 17:15:431108 request(1)->handle()->SetPriority(HIGHEST);
rdsmith29dbad12017-02-17 02:22:181109
1110 ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE);
1111
1112 EXPECT_TRUE(request(1)->handle()->socket());
1113}
1114
1115// Reprioritize a request up past another one and make sure that changes the
1116// completion order.
1117TEST_F(ClientSocketPoolBaseTest, ReprioritizeUpReorder) {
1118 CreatePool(kDefaultMaxSockets, 1);
1119
Matt Menkec6b3edf72019-03-19 17:00:391120 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(OK));
1121 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1122 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
rdsmith29dbad12017-02-17 02:22:181123 EXPECT_TRUE(request(0)->handle()->socket());
1124 EXPECT_FALSE(request(1)->handle()->socket());
1125 EXPECT_FALSE(request(2)->handle()->socket());
1126
1127 request(2)->handle()->SetPriority(HIGHEST);
1128
1129 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1130
1131 EXPECT_EQ(1, GetOrderOfRequest(1));
1132 EXPECT_EQ(3, GetOrderOfRequest(2));
1133 EXPECT_EQ(2, GetOrderOfRequest(3));
1134}
1135
1136// Reprioritize a request without changing relative priorities and check
1137// that the order doesn't change.
1138TEST_F(ClientSocketPoolBaseTest, ReprioritizeUpNoReorder) {
1139 CreatePool(kDefaultMaxSockets, 1);
1140
Matt Menkec6b3edf72019-03-19 17:00:391141 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(OK));
1142 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1143 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsError(ERR_IO_PENDING));
rdsmith29dbad12017-02-17 02:22:181144 EXPECT_TRUE(request(0)->handle()->socket());
1145 EXPECT_FALSE(request(1)->handle()->socket());
1146 EXPECT_FALSE(request(2)->handle()->socket());
1147
1148 request(2)->handle()->SetPriority(MEDIUM);
1149
1150 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1151
1152 EXPECT_EQ(1, GetOrderOfRequest(1));
1153 EXPECT_EQ(2, GetOrderOfRequest(2));
1154 EXPECT_EQ(3, GetOrderOfRequest(3));
1155}
1156
1157// Reprioritize a request past down another one and make sure that changes the
1158// completion order.
1159TEST_F(ClientSocketPoolBaseTest, ReprioritizeDownReorder) {
1160 CreatePool(kDefaultMaxSockets, 1);
1161
Matt Menkec6b3edf72019-03-19 17:00:391162 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(OK));
1163 EXPECT_THAT(StartRequest(TestGroupId("a"), HIGHEST), IsError(ERR_IO_PENDING));
1164 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
rdsmith29dbad12017-02-17 02:22:181165 EXPECT_TRUE(request(0)->handle()->socket());
1166 EXPECT_FALSE(request(1)->handle()->socket());
1167 EXPECT_FALSE(request(2)->handle()->socket());
1168
1169 request(1)->handle()->SetPriority(LOW);
1170
1171 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1172
1173 EXPECT_EQ(1, GetOrderOfRequest(1));
1174 EXPECT_EQ(3, GetOrderOfRequest(2));
1175 EXPECT_EQ(2, GetOrderOfRequest(3));
1176}
1177
1178// Reprioritize a request to the same level as another and confirm it is
1179// put after the old request.
1180TEST_F(ClientSocketPoolBaseTest, ReprioritizeResetFIFO) {
1181 CreatePool(kDefaultMaxSockets, 1);
1182
Matt Menkec6b3edf72019-03-19 17:00:391183 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(OK));
1184 EXPECT_THAT(StartRequest(TestGroupId("a"), HIGHEST), IsError(ERR_IO_PENDING));
1185 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
rdsmith29dbad12017-02-17 02:22:181186 EXPECT_TRUE(request(0)->handle()->socket());
1187 EXPECT_FALSE(request(1)->handle()->socket());
1188 EXPECT_FALSE(request(2)->handle()->socket());
1189
1190 request(1)->handle()->SetPriority(MEDIUM);
1191
1192 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1193
1194 EXPECT_EQ(1, GetOrderOfRequest(1));
1195 EXPECT_EQ(3, GetOrderOfRequest(2));
1196 EXPECT_EQ(2, GetOrderOfRequest(3));
1197}
1198
[email protected]211d21722009-07-22 15:48:531199TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
1200 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1201
Matt Menkec6b3edf72019-03-19 17:00:391202 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsOk());
1203 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsOk());
1204 EXPECT_THAT(StartRequest(TestGroupId("b"), HIGHEST), IsOk());
1205 EXPECT_THAT(StartRequest(TestGroupId("b"), MEDIUM), IsOk());
[email protected]211d21722009-07-22 15:48:531206
[email protected]2431756e2010-09-29 20:26:131207 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531208 client_socket_factory_.allocation_count());
1209
Matt Menkec6b3edf72019-03-19 17:00:391210 EXPECT_THAT(StartRequest(TestGroupId("c"), MEDIUM), IsError(ERR_IO_PENDING));
1211 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsError(ERR_IO_PENDING));
1212 EXPECT_THAT(StartRequest(TestGroupId("b"), HIGHEST), IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:531213
[email protected]2431756e2010-09-29 20:26:131214 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:531215
[email protected]2431756e2010-09-29 20:26:131216 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531217 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131218 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:531219
1220 // First 4 requests don't have to wait, and finish in order.
1221 EXPECT_EQ(1, GetOrderOfRequest(1));
1222 EXPECT_EQ(2, GetOrderOfRequest(2));
1223 EXPECT_EQ(3, GetOrderOfRequest(3));
1224 EXPECT_EQ(4, GetOrderOfRequest(4));
1225
1226 // Request ("b", 7) has the highest priority, but we can't make new socket for
1227 // group "b", because it has reached the per-group limit. Then we make
1228 // socket for ("c", 6), because it has higher priority than ("a", 4),
1229 // and we still can't make a socket for group "b".
1230 EXPECT_EQ(5, GetOrderOfRequest(5));
1231 EXPECT_EQ(6, GetOrderOfRequest(6));
1232 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171233
1234 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131235 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:531236}
1237
1238// Make sure that we count connecting sockets against the total limit.
1239TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
1240 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1241
Matt Menkec6b3edf72019-03-19 17:00:391242 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1243 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
1244 EXPECT_THAT(StartRequest(TestGroupId("c"), DEFAULT_PRIORITY), IsOk());
[email protected]211d21722009-07-22 15:48:531245
1246 // Create one asynchronous request.
1247 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
Matt Menkec6b3edf72019-03-19 17:00:391248 EXPECT_THAT(StartRequest(TestGroupId("d"), DEFAULT_PRIORITY),
1249 IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:531250
[email protected]6b175382009-10-13 06:47:471251 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1252 // actually become pending until 2ms after they have been created. In order
1253 // to flush all tasks, we need to wait so that we know there are no
1254 // soon-to-be-pending tasks waiting.
Alex Clarke0def2092018-12-10 12:01:451255 FastForwardBy(base::TimeDelta::FromMilliseconds(10));
[email protected]6b175382009-10-13 06:47:471256
[email protected]211d21722009-07-22 15:48:531257 // The next synchronous request should wait for its turn.
1258 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
Matt Menkec6b3edf72019-03-19 17:00:391259 EXPECT_THAT(StartRequest(TestGroupId("e"), DEFAULT_PRIORITY),
1260 IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:531261
[email protected]2431756e2010-09-29 20:26:131262 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:531263
[email protected]2431756e2010-09-29 20:26:131264 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531265 client_socket_factory_.allocation_count());
1266
1267 EXPECT_EQ(1, GetOrderOfRequest(1));
1268 EXPECT_EQ(2, GetOrderOfRequest(2));
1269 EXPECT_EQ(3, GetOrderOfRequest(3));
1270 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:171271 EXPECT_EQ(5, GetOrderOfRequest(5));
1272
1273 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131274 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:531275}
1276
[email protected]6427fe22010-04-16 22:27:411277TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
1278 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1279 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1280
Matt Menkec6b3edf72019-03-19 17:00:391281 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1282 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1283 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1284 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
[email protected]6427fe22010-04-16 22:27:411285
1286 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1287
1288 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1289
Matt Menkec6b3edf72019-03-19 17:00:391290 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY),
1291 IsError(ERR_IO_PENDING));
1292 EXPECT_THAT(StartRequest(TestGroupId("c"), DEFAULT_PRIORITY),
1293 IsError(ERR_IO_PENDING));
[email protected]6427fe22010-04-16 22:27:411294
1295 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1296
[email protected]2431756e2010-09-29 20:26:131297 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411298 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131299 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411300 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131301 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1302 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411303 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
1304}
1305
[email protected]d7027bb2010-05-10 18:58:541306TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
1307 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1308 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1309
1310 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521311 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:501312 EXPECT_EQ(
1313 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:391314 handle.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:501315 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1316 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
1317 NetLogWithSource()));
[email protected]d7027bb2010-05-10 18:58:541318
1319 ClientSocketHandle handles[4];
Avi Drissman4365a4782018-12-28 19:26:241320 for (size_t i = 0; i < base::size(handles); ++i) {
[email protected]6ecf2b92011-12-15 01:14:521321 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:501322 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:391323 handles[i].Init(
1324 TestGroupId("b"), params_, DEFAULT_PRIORITY, SocketTag(),
1325 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1326 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
1327 NetLogWithSource()));
[email protected]d7027bb2010-05-10 18:58:541328 }
1329
1330 // One will be stalled, cancel all the handles now.
1331 // This should hit the OnAvailableSocketSlot() code where we previously had
1332 // stalled groups, but no longer have any.
Avi Drissman4365a4782018-12-28 19:26:241333 for (size_t i = 0; i < base::size(handles); ++i)
[email protected]d7027bb2010-05-10 18:58:541334 handles[i].Reset();
1335}
1336
[email protected]eb5a99382010-07-11 03:18:261337TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
[email protected]43a21b82010-06-10 21:30:541338 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1339 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1340
[email protected]eb5a99382010-07-11 03:18:261341 {
1342 ClientSocketHandle handles[kDefaultMaxSockets];
[email protected]6ecf2b92011-12-15 01:14:521343 TestCompletionCallback callbacks[kDefaultMaxSockets];
[email protected]eb5a99382010-07-11 03:18:261344 for (int i = 0; i < kDefaultMaxSockets; ++i) {
Matt Menkec6b3edf72019-03-19 17:00:391345 EXPECT_EQ(OK, handles[i].Init(TestGroupId(base::NumberToString(i)),
1346 params_, DEFAULT_PRIORITY, SocketTag(),
Paul Jensen8d6f87ec2018-01-13 00:46:541347 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501348 callbacks[i].callback(),
1349 ClientSocketPool::ProxyAuthCallback(),
1350 pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261351 }
1352
1353 // Force a stalled group.
1354 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521355 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:201356 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:391357 stalled_handle.Init(
1358 TestGroupId("foo"), params_, DEFAULT_PRIORITY, SocketTag(),
1359 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1360 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
1361 NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261362
1363 // Cancel the stalled request.
1364 stalled_handle.Reset();
1365
1366 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1367 EXPECT_EQ(0, pool_->IdleSocketCount());
1368
1369 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541370 }
1371
[email protected]43a21b82010-06-10 21:30:541372 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1373 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
[email protected]eb5a99382010-07-11 03:18:261374}
[email protected]43a21b82010-06-10 21:30:541375
[email protected]eb5a99382010-07-11 03:18:261376TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
1377 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1378 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1379
1380 {
1381 ClientSocketHandle handles[kDefaultMaxSockets];
1382 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:521383 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:201384 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:391385 handles[i].Init(TestGroupId(base::NumberToString(i)), params_,
1386 DEFAULT_PRIORITY, SocketTag(),
1387 ClientSocketPool::RespectLimits::ENABLED,
1388 callback.callback(),
1389 ClientSocketPool::ProxyAuthCallback(),
1390 pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261391 }
1392
1393 // Force a stalled group.
1394 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1395 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521396 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:201397 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:391398 stalled_handle.Init(
1399 TestGroupId("foo"), params_, DEFAULT_PRIORITY, SocketTag(),
1400 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1401 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
1402 NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261403
1404 // Since it is stalled, it should have no connect jobs.
Matt Menkec6b3edf72019-03-19 17:00:391405 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup(TestGroupId("foo")));
1406 EXPECT_EQ(0u,
1407 pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("foo")));
1408 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("foo")));
[email protected]eb5a99382010-07-11 03:18:261409
1410 // Cancel the stalled request.
1411 handles[0].Reset();
1412
[email protected]eb5a99382010-07-11 03:18:261413 // Now we should have a connect job.
Matt Menkec6b3edf72019-03-19 17:00:391414 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("foo")));
1415 EXPECT_EQ(0u,
1416 pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("foo")));
1417 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("foo")));
[email protected]eb5a99382010-07-11 03:18:261418
1419 // The stalled socket should connect.
robpercival214763f2016-07-01 23:27:011420 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:261421
1422 EXPECT_EQ(kDefaultMaxSockets + 1,
1423 client_socket_factory_.allocation_count());
1424 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menkec6b3edf72019-03-19 17:00:391425 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup(TestGroupId("foo")));
1426 EXPECT_EQ(0u,
1427 pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("foo")));
1428 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("foo")));
[email protected]eb5a99382010-07-11 03:18:261429
1430 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541431 }
1432
[email protected]eb5a99382010-07-11 03:18:261433 EXPECT_EQ(1, pool_->IdleSocketCount());
1434}
[email protected]43a21b82010-06-10 21:30:541435
[email protected]eb5a99382010-07-11 03:18:261436TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
1437 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1438 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]43a21b82010-06-10 21:30:541439
[email protected]eb5a99382010-07-11 03:18:261440 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521441 TestCompletionCallback callback;
[email protected]eb5a99382010-07-11 03:18:261442 {
[email protected]51fdc7c2012-04-10 19:19:481443 EXPECT_FALSE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261444 ClientSocketHandle handles[kDefaultMaxSockets];
1445 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:521446 TestCompletionCallback callback;
Matt Menkec6b3edf72019-03-19 17:00:391447 EXPECT_EQ(
1448 OK, handles[i].Init(TestGroupId(base::StringPrintf("Take 2: %d", i)),
1449 params_, DEFAULT_PRIORITY, SocketTag(),
1450 ClientSocketPool::RespectLimits::ENABLED,
1451 callback.callback(),
1452 ClientSocketPool::ProxyAuthCallback(),
1453 pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261454 }
1455
1456 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1457 EXPECT_EQ(0, pool_->IdleSocketCount());
[email protected]51fdc7c2012-04-10 19:19:481458 EXPECT_FALSE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261459
1460 // Now we will hit the socket limit.
tfarina428341112016-09-22 13:38:201461 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:391462 stalled_handle.Init(
1463 TestGroupId("foo"), params_, DEFAULT_PRIORITY, SocketTag(),
1464 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1465 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
1466 NetLogWithSource()));
[email protected]51fdc7c2012-04-10 19:19:481467 EXPECT_TRUE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261468
1469 // Dropping out of scope will close all handles and return them to idle.
1470 }
[email protected]43a21b82010-06-10 21:30:541471
1472 // But if we wait for it, the released idle sockets will be closed in
1473 // preference of the waiting request.
robpercival214763f2016-07-01 23:27:011474 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:261475
1476 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1477 EXPECT_EQ(3, pool_->IdleSocketCount());
[email protected]43a21b82010-06-10 21:30:541478}
1479
1480// Regression test for http://crbug.com/40952.
1481TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
1482 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]06d94042010-08-25 01:45:221483 pool_->EnableConnectBackupJobs();
[email protected]43a21b82010-06-10 21:30:541484 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1485
1486 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1487 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521488 TestCompletionCallback callback;
Matt Menkec6b3edf72019-03-19 17:00:391489 EXPECT_EQ(OK, handle.Init(TestGroupId(base::NumberToString(i)), params_,
1490 DEFAULT_PRIORITY, SocketTag(),
1491 ClientSocketPool::RespectLimits::ENABLED,
1492 callback.callback(),
1493 ClientSocketPool::ProxyAuthCallback(),
1494 pool_.get(), NetLogWithSource()));
[email protected]43a21b82010-06-10 21:30:541495 }
1496
1497 // Flush all the DoReleaseSocket tasks.
fdoray5eeb7642016-06-22 16:11:281498 base::RunLoop().RunUntilIdle();
[email protected]43a21b82010-06-10 21:30:541499
1500 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
1501 // reuse a socket.
1502 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1503 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521504 TestCompletionCallback callback;
[email protected]43a21b82010-06-10 21:30:541505
1506 // "0" is special here, since it should be the first entry in the sorted map,
1507 // which is the one which we would close an idle socket for. We shouldn't
1508 // close an idle socket though, since we should reuse the idle socket.
Matt Menkec6b3edf72019-03-19 17:00:391509 EXPECT_EQ(OK, handle.Init(
1510 TestGroupId("0"), params_, DEFAULT_PRIORITY, SocketTag(),
1511 ClientSocketPool::RespectLimits::ENABLED,
1512 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1513 pool_.get(), NetLogWithSource()));
[email protected]43a21b82010-06-10 21:30:541514
1515 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1516 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
1517}
1518
[email protected]ab838892009-06-30 18:49:051519TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:531520 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091521
Matt Menkec6b3edf72019-03-19 17:00:391522 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1523 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1524 EXPECT_THAT(StartRequest(TestGroupId("a"), IDLE), IsError(ERR_IO_PENDING));
1525 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
1526 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1527 EXPECT_THAT(StartRequest(TestGroupId("a"), HIGHEST), IsError(ERR_IO_PENDING));
1528 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsError(ERR_IO_PENDING));
1529 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091530
[email protected]2431756e2010-09-29 20:26:131531 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]c9d6a1d2009-07-14 16:15:201532 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1533 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131534 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1535 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091536
[email protected]c9d6a1d2009-07-14 16:15:201537 EXPECT_EQ(1, GetOrderOfRequest(1));
1538 EXPECT_EQ(2, GetOrderOfRequest(2));
[email protected]c9c6f5c2010-07-31 01:30:031539 EXPECT_EQ(8, GetOrderOfRequest(3));
1540 EXPECT_EQ(6, GetOrderOfRequest(4));
1541 EXPECT_EQ(4, GetOrderOfRequest(5));
1542 EXPECT_EQ(3, GetOrderOfRequest(6));
1543 EXPECT_EQ(5, GetOrderOfRequest(7));
1544 EXPECT_EQ(7, GetOrderOfRequest(8));
[email protected]75439d3b2009-07-23 22:11:171545
1546 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131547 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]f6d1d6eb2009-06-24 20:16:091548}
1549
[email protected]ab838892009-06-30 18:49:051550TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:531551 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091552
Matt Menkec6b3edf72019-03-19 17:00:391553 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1554 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1555 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
1556 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1557 EXPECT_THAT(StartRequest(TestGroupId("a"), HIGHEST), IsError(ERR_IO_PENDING));
1558 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsError(ERR_IO_PENDING));
1559 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091560
[email protected]2431756e2010-09-29 20:26:131561 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091562
[email protected]2431756e2010-09-29 20:26:131563 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i)
robpercival214763f2016-07-01 23:27:011564 EXPECT_THAT(request(i)->WaitForResult(), IsOk());
[email protected]c9d6a1d2009-07-14 16:15:201565
[email protected]2431756e2010-09-29 20:26:131566 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]c9d6a1d2009-07-14 16:15:201567 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131568 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1569 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091570}
1571
1572// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:051573// The pending connect job will be cancelled and should not call back into
1574// ClientSocketPoolBase.
1575TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:531576 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201577
[email protected]ab838892009-06-30 18:49:051578 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131579 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521580 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:501581 EXPECT_EQ(
1582 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:391583 handle.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:501584 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1585 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
1586 NetLogWithSource()));
[email protected]2431756e2010-09-29 20:26:131587 handle.Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091588}
1589
[email protected]ab838892009-06-30 18:49:051590TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531591 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201592
[email protected]ab838892009-06-30 18:49:051593 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061594 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521595 TestCompletionCallback callback;
[email protected]f6d1d6eb2009-06-24 20:16:091596
Matt Menke28ac03e2019-02-25 22:25:501597 EXPECT_EQ(
1598 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:391599 handle.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:501600 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1601 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
1602 NetLogWithSource()));
[email protected]f6d1d6eb2009-06-24 20:16:091603
1604 handle.Reset();
1605
[email protected]6ecf2b92011-12-15 01:14:521606 TestCompletionCallback callback2;
Matt Menke28ac03e2019-02-25 22:25:501607 EXPECT_EQ(
1608 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:391609 handle.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:501610 ClientSocketPool::RespectLimits::ENABLED,
1611 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
1612 pool_.get(), NetLogWithSource()));
[email protected]f6d1d6eb2009-06-24 20:16:091613
robpercival214763f2016-07-01 23:27:011614 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]f6d1d6eb2009-06-24 20:16:091615 EXPECT_FALSE(callback.have_result());
1616
1617 handle.Reset();
1618}
1619
[email protected]ab838892009-06-30 18:49:051620TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531621 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091622
Matt Menkec6b3edf72019-03-19 17:00:391623 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1624 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1625 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
1626 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1627 EXPECT_THAT(StartRequest(TestGroupId("a"), HIGHEST), IsError(ERR_IO_PENDING));
1628 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsError(ERR_IO_PENDING));
1629 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091630
1631 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:201632 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]2431756e2010-09-29 20:26:131633 EXPECT_FALSE((*requests())[index_to_cancel]->handle()->is_initialized());
1634 (*requests())[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091635
[email protected]2431756e2010-09-29 20:26:131636 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091637
[email protected]c9d6a1d2009-07-14 16:15:201638 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1639 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131640 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup - 1,
1641 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091642
[email protected]c9d6a1d2009-07-14 16:15:201643 EXPECT_EQ(1, GetOrderOfRequest(1));
1644 EXPECT_EQ(2, GetOrderOfRequest(2));
1645 EXPECT_EQ(5, GetOrderOfRequest(3));
1646 EXPECT_EQ(3, GetOrderOfRequest(4));
[email protected]2431756e2010-09-29 20:26:131647 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
1648 GetOrderOfRequest(5)); // Canceled request.
[email protected]c9d6a1d2009-07-14 16:15:201649 EXPECT_EQ(4, GetOrderOfRequest(6));
1650 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171651
1652 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131653 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:091654}
1655
mmenke33d24423d2015-05-19 19:41:091656// Function to be used as a callback on socket request completion. It first
1657// disconnects the successfully connected socket from the first request, and
1658// then reuses the ClientSocketHandle to request another socket.
1659//
1660// |nested_callback| is called with the result of the second socket request.
1661void RequestSocketOnComplete(ClientSocketHandle* handle,
1662 TestClientSocketPool* pool,
1663 TestConnectJobFactory* test_connect_job_factory,
1664 TestConnectJob::JobType next_job_type,
Bence Békya4a50932018-08-10 13:39:411665 TestCompletionCallback* nested_callback,
mmenke33d24423d2015-05-19 19:41:091666 int first_request_result) {
robpercival214763f2016-07-01 23:27:011667 EXPECT_THAT(first_request_result, IsOk());
mmenke33d24423d2015-05-19 19:41:091668
1669 test_connect_job_factory->set_job_type(next_job_type);
1670
1671 // Don't allow reuse of the socket. Disconnect it and then release it.
1672 if (handle->socket())
1673 handle->socket()->Disconnect();
1674 handle->Reset();
1675
mmenked3641e12016-01-28 16:06:151676 scoped_refptr<TestSocketParams> params(new TestSocketParams());
mmenke33d24423d2015-05-19 19:41:091677 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:501678 int rv = handle->Init(
Matt Menkec6b3edf72019-03-19 17:00:391679 TestGroupId("a"), params, LOWEST, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:501680 ClientSocketPool::RespectLimits::ENABLED, nested_callback->callback(),
1681 ClientSocketPool::ProxyAuthCallback(), pool, NetLogWithSource());
mmenke33d24423d2015-05-19 19:41:091682 if (rv != ERR_IO_PENDING) {
1683 DCHECK_EQ(TestConnectJob::kMockJob, next_job_type);
Bence Békya4a50932018-08-10 13:39:411684 nested_callback->callback().Run(rv);
mmenke33d24423d2015-05-19 19:41:091685 } else {
1686 DCHECK_EQ(TestConnectJob::kMockPendingJob, next_job_type);
[email protected]6ecf2b92011-12-15 01:14:521687 }
mmenke33d24423d2015-05-19 19:41:091688}
[email protected]f6d1d6eb2009-06-24 20:16:091689
mmenke33d24423d2015-05-19 19:41:091690// Tests the case where a second socket is requested in a completion callback,
1691// and the second socket connects asynchronously. Reuses the same
1692// ClientSocketHandle for the second socket, after disconnecting the first.
[email protected]2ab05b52009-07-01 23:57:581693TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531694 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201695
[email protected]0b7648c2009-07-06 20:14:011696 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061697 ClientSocketHandle handle;
mmenke33d24423d2015-05-19 19:41:091698 TestCompletionCallback second_result_callback;
1699 int rv = handle.Init(
Matt Menkec6b3edf72019-03-19 17:00:391700 TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
Paul Jensen8d6f87ec2018-01-13 00:46:541701 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501702 base::BindOnce(&RequestSocketOnComplete, &handle, pool_.get(),
1703 connect_job_factory_, TestConnectJob::kMockPendingJob,
1704 &second_result_callback),
1705 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011706 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091707
robpercival214763f2016-07-01 23:27:011708 EXPECT_THAT(second_result_callback.WaitForResult(), IsOk());
[email protected]2ab05b52009-07-01 23:57:581709}
[email protected]f6d1d6eb2009-06-24 20:16:091710
mmenke33d24423d2015-05-19 19:41:091711// Tests the case where a second socket is requested in a completion callback,
1712// and the second socket connects synchronously. Reuses the same
1713// ClientSocketHandle for the second socket, after disconnecting the first.
[email protected]2ab05b52009-07-01 23:57:581714TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531715 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201716
[email protected]0b7648c2009-07-06 20:14:011717 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061718 ClientSocketHandle handle;
mmenke33d24423d2015-05-19 19:41:091719 TestCompletionCallback second_result_callback;
1720 int rv = handle.Init(
Matt Menkec6b3edf72019-03-19 17:00:391721 TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
Paul Jensen8d6f87ec2018-01-13 00:46:541722 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501723 base::BindOnce(&RequestSocketOnComplete, &handle, pool_.get(),
1724 connect_job_factory_, TestConnectJob::kMockPendingJob,
1725 &second_result_callback),
1726 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011727 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2ab05b52009-07-01 23:57:581728
robpercival214763f2016-07-01 23:27:011729 EXPECT_THAT(second_result_callback.WaitForResult(), IsOk());
[email protected]f6d1d6eb2009-06-24 20:16:091730}
1731
1732// Make sure that pending requests get serviced after active requests get
1733// cancelled.
[email protected]ab838892009-06-30 18:49:051734TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531735 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201736
[email protected]0b7648c2009-07-06 20:14:011737 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091738
Matt Menkec6b3edf72019-03-19 17:00:391739 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1740 IsError(ERR_IO_PENDING));
1741 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1742 IsError(ERR_IO_PENDING));
1743 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1744 IsError(ERR_IO_PENDING));
1745 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1746 IsError(ERR_IO_PENDING));
1747 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1748 IsError(ERR_IO_PENDING));
1749 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1750 IsError(ERR_IO_PENDING));
1751 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1752 IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091753
[email protected]c9d6a1d2009-07-14 16:15:201754 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1755 // Let's cancel them.
1756 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]2431756e2010-09-29 20:26:131757 ASSERT_FALSE(request(i)->handle()->is_initialized());
1758 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091759 }
1760
[email protected]f6d1d6eb2009-06-24 20:16:091761 // Let's wait for the rest to complete now.
[email protected]2431756e2010-09-29 20:26:131762 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i) {
robpercival214763f2016-07-01 23:27:011763 EXPECT_THAT(request(i)->WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:131764 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091765 }
1766
[email protected]2431756e2010-09-29 20:26:131767 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1768 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091769}
1770
1771// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051772TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531773 const size_t kMaxSockets = 5;
1774 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201775
[email protected]0b7648c2009-07-06 20:14:011776 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091777
[email protected]211d21722009-07-22 15:48:531778 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1779 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091780
1781 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531782 for (size_t i = 0; i < kNumberOfRequests; ++i)
Matt Menkec6b3edf72019-03-19 17:00:391783 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1784 IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091785
[email protected]211d21722009-07-22 15:48:531786 for (size_t i = 0; i < kNumberOfRequests; ++i)
robpercival214763f2016-07-01 23:27:011787 EXPECT_THAT(request(i)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]f6d1d6eb2009-06-24 20:16:091788}
1789
mmenke9d72fe42017-05-18 22:36:071790// Make sure that pending requests that complete synchronously get serviced
1791// after active requests fail. See https://crbug.com/723748
1792TEST_F(ClientSocketPoolBaseTest, HandleMultipleSyncFailuresAfterAsyncFailure) {
1793 const size_t kNumberOfRequests = 10;
1794 const size_t kMaxSockets = 1;
1795 CreatePool(kMaxSockets, kMaxSockets);
1796
1797 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1798
Matt Menkec6b3edf72019-03-19 17:00:391799 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1800 IsError(ERR_IO_PENDING));
mmenke9d72fe42017-05-18 22:36:071801
1802 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
1803
1804 // Queue up all the other requests
1805 for (size_t i = 1; i < kNumberOfRequests; ++i)
Matt Menkec6b3edf72019-03-19 17:00:391806 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1807 IsError(ERR_IO_PENDING));
mmenke9d72fe42017-05-18 22:36:071808
1809 // Make sure all requests fail, instead of hanging.
1810 for (size_t i = 0; i < kNumberOfRequests; ++i)
1811 EXPECT_THAT(request(i)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
1812}
1813
[email protected]5fc08e32009-07-15 17:09:571814TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531815 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571816
1817 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1818
[email protected]2431756e2010-09-29 20:26:131819 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521820 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:501821 int rv = handle.Init(
Matt Menkec6b3edf72019-03-19 17:00:391822 TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:501823 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1824 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011825 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:571826
1827 // Cancel the active request.
[email protected]2431756e2010-09-29 20:26:131828 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571829
Matt Menkec6b3edf72019-03-19 17:00:391830 rv = handle.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:151831 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501832 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1833 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011834 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1835 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]5fc08e32009-07-15 17:09:571836
[email protected]2431756e2010-09-29 20:26:131837 EXPECT_FALSE(handle.is_reused());
[email protected]034df0f32013-01-07 23:17:481838 TestLoadTimingInfoConnectedNotReused(handle);
[email protected]5fc08e32009-07-15 17:09:571839 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1840}
1841
xunjieli26619e72016-11-23 19:39:551842TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsForced) {
xunjieli26619e72016-11-23 19:39:551843 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1844 ClientSocketHandle handle;
1845 TestCompletionCallback callback;
1846 BoundTestNetLog log;
Matt Menke28ac03e2019-02-25 22:25:501847 int rv = handle.Init(
Matt Menkec6b3edf72019-03-19 17:00:391848 TestGroupId("a"), params_, LOWEST, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:501849 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1850 ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound());
xunjieli26619e72016-11-23 19:39:551851 EXPECT_THAT(rv, IsOk());
1852 handle.Reset();
1853 EXPECT_EQ(1, pool_->IdleSocketCount());
1854 pool_->CloseIdleSockets();
xunjieli26619e72016-11-23 19:39:551855}
1856
xunjieli92feb332017-03-03 17:19:231857TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsInGroupForced) {
xunjieli92feb332017-03-03 17:19:231858 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1859 TestCompletionCallback callback;
1860 BoundTestNetLog log;
1861 ClientSocketHandle handle1;
Matt Menke28ac03e2019-02-25 22:25:501862 int rv = handle1.Init(
Matt Menkec6b3edf72019-03-19 17:00:391863 TestGroupId("a"), params_, LOWEST, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:501864 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1865 ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound());
xunjieli92feb332017-03-03 17:19:231866 EXPECT_THAT(rv, IsOk());
1867 ClientSocketHandle handle2;
Matt Menkec6b3edf72019-03-19 17:00:391868 rv = handle2.Init(TestGroupId("a"), params_, LOWEST, SocketTag(),
xunjieli92feb332017-03-03 17:19:231869 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501870 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1871 pool_.get(), log.bound());
xunjieli92feb332017-03-03 17:19:231872 ClientSocketHandle handle3;
Matt Menkec6b3edf72019-03-19 17:00:391873 rv = handle3.Init(TestGroupId("b"), params_, LOWEST, SocketTag(),
xunjieli92feb332017-03-03 17:19:231874 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501875 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1876 pool_.get(), log.bound());
xunjieli92feb332017-03-03 17:19:231877 EXPECT_THAT(rv, IsOk());
1878 handle1.Reset();
1879 handle2.Reset();
1880 handle3.Reset();
1881 EXPECT_EQ(3, pool_->IdleSocketCount());
Matt Menkec6b3edf72019-03-19 17:00:391882 pool_->CloseIdleSocketsInGroup(TestGroupId("a"));
xunjieli92feb332017-03-03 17:19:231883 EXPECT_EQ(1, pool_->IdleSocketCount());
xunjieli92feb332017-03-03 17:19:231884}
1885
xunjieli26619e72016-11-23 19:39:551886TEST_F(ClientSocketPoolBaseTest, CleanUpUnusableIdleSockets) {
xunjieli26619e72016-11-23 19:39:551887 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1888 ClientSocketHandle handle;
1889 TestCompletionCallback callback;
1890 BoundTestNetLog log;
Matt Menke28ac03e2019-02-25 22:25:501891 int rv = handle.Init(
Matt Menkec6b3edf72019-03-19 17:00:391892 TestGroupId("a"), params_, LOWEST, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:501893 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1894 ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound());
xunjieli26619e72016-11-23 19:39:551895 EXPECT_THAT(rv, IsOk());
1896 StreamSocket* socket = handle.socket();
1897 handle.Reset();
1898 EXPECT_EQ(1, pool_->IdleSocketCount());
1899
1900 // Disconnect socket now to make the socket unusable.
1901 socket->Disconnect();
1902 ClientSocketHandle handle2;
Matt Menkec6b3edf72019-03-19 17:00:391903 rv = handle2.Init(TestGroupId("a"), params_, LOWEST, SocketTag(),
xunjieli26619e72016-11-23 19:39:551904 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501905 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1906 pool_.get(), log.bound());
xunjieli26619e72016-11-23 19:39:551907 EXPECT_THAT(rv, IsOk());
1908 EXPECT_FALSE(handle2.is_reused());
xunjieli26619e72016-11-23 19:39:551909}
1910
[email protected]2b7523d2009-07-29 20:29:231911// Regression test for http://crbug.com/17985.
1912TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1913 const int kMaxSockets = 3;
1914 const int kMaxSocketsPerGroup = 2;
1915 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1916
[email protected]ac790b42009-12-02 04:31:311917 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231918
Matt Menkec6b3edf72019-03-19 17:00:391919 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1920 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
[email protected]2b7523d2009-07-29 20:29:231921
1922 // This is going to be a pending request in an otherwise empty group.
Matt Menkec6b3edf72019-03-19 17:00:391923 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1924 IsError(ERR_IO_PENDING));
[email protected]2b7523d2009-07-29 20:29:231925
1926 // Reach the maximum socket limit.
Matt Menkec6b3edf72019-03-19 17:00:391927 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
[email protected]2b7523d2009-07-29 20:29:231928
1929 // Create a stalled group with high priorities.
Matt Menkec6b3edf72019-03-19 17:00:391930 EXPECT_THAT(StartRequest(TestGroupId("c"), kHighPriority),
1931 IsError(ERR_IO_PENDING));
1932 EXPECT_THAT(StartRequest(TestGroupId("c"), kHighPriority),
1933 IsError(ERR_IO_PENDING));
[email protected]2b7523d2009-07-29 20:29:231934
Matt Menkec6b3edf72019-03-19 17:00:391935 // Release the first two sockets from TestGroupId("a"). Because this is a
1936 // keepalive, the first release will unblock the pending request for
1937 // TestGroupId("a"). The second release will unblock a request for "c",
1938 // because it is the next high priority socket.
[email protected]2431756e2010-09-29 20:26:131939 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1940 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]2b7523d2009-07-29 20:29:231941
1942 // Closing idle sockets should not get us into trouble, but in the bug
1943 // we were hitting a CHECK here.
Matt Menkec6b3edf72019-03-19 17:00:391944 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]43a21b82010-06-10 21:30:541945 pool_->CloseIdleSockets();
[email protected]eb5a99382010-07-11 03:18:261946
[email protected]2da659e2013-05-23 20:51:341947 // Run the released socket wakeups.
fdoray5eeb7642016-06-22 16:11:281948 base::RunLoop().RunUntilIdle();
[email protected]2b7523d2009-07-29 20:29:231949}
1950
[email protected]4d3b05d2010-01-27 21:27:291951TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531952 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571953
1954 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131955 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521956 TestCompletionCallback callback;
vishal.b62985ca92015-04-17 08:45:511957 BoundTestNetLog log;
Matt Menke28ac03e2019-02-25 22:25:501958 int rv = handle.Init(
Matt Menkec6b3edf72019-03-19 17:00:391959 TestGroupId("a"), params_, LOWEST, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:501960 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1961 ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound());
robpercival214763f2016-07-01 23:27:011962 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Matt Menkec6b3edf72019-03-19 17:00:391963 EXPECT_EQ(LOAD_STATE_CONNECTING,
1964 pool_->GetLoadState(TestGroupId("a"), &handle));
[email protected]034df0f32013-01-07 23:17:481965 TestLoadTimingInfoNotConnected(handle);
1966
robpercival214763f2016-07-01 23:27:011967 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:131968 EXPECT_TRUE(handle.is_initialized());
1969 EXPECT_TRUE(handle.socket());
[email protected]034df0f32013-01-07 23:17:481970 TestLoadTimingInfoConnectedNotReused(handle);
1971
[email protected]2431756e2010-09-29 20:26:131972 handle.Reset();
[email protected]034df0f32013-01-07 23:17:481973 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:301974
mmenke43758e62015-05-04 21:09:461975 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:401976 log.GetEntries(&entries);
1977
1978 EXPECT_EQ(4u, entries.size());
mikecirone8b85c432016-09-08 19:11:001979 EXPECT_TRUE(LogContainsBeginEvent(entries, 0, NetLogEventType::SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171980 EXPECT_TRUE(LogContainsEvent(
mikecirone8b85c432016-09-08 19:11:001981 entries, 1, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
1982 NetLogEventPhase::NONE));
1983 EXPECT_TRUE(LogContainsEvent(entries, 2,
1984 NetLogEventType::SOCKET_POOL_BOUND_TO_SOCKET,
1985 NetLogEventPhase::NONE));
1986 EXPECT_TRUE(LogContainsEndEvent(entries, 3, NetLogEventType::SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571987}
1988
[email protected]4d3b05d2010-01-27 21:27:291989TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:571990 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531991 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571992
1993 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]2431756e2010-09-29 20:26:131994 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521995 TestCompletionCallback callback;
vishal.b62985ca92015-04-17 08:45:511996 BoundTestNetLog log;
[email protected]e60e47a2010-07-14 03:37:181997 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:131998 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:431999 HttpResponseInfo info;
[email protected]007b3f82013-04-09 08:46:452000 info.headers = new HttpResponseHeaders(std::string());
[email protected]2431756e2010-09-29 20:26:132001 handle.set_ssl_error_response_info(info);
Matt Menke28ac03e2019-02-25 22:25:502002 EXPECT_EQ(
2003 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:392004 handle.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502005 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2006 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2007 log.bound()));
Matt Menkec6b3edf72019-03-19 17:00:392008 EXPECT_EQ(LOAD_STATE_CONNECTING,
2009 pool_->GetLoadState(TestGroupId("a"), &handle));
robpercival214763f2016-07-01 23:27:012010 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]2431756e2010-09-29 20:26:132011 EXPECT_FALSE(handle.is_ssl_error());
Raul Tambre94493c652019-03-11 17:18:352012 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == nullptr);
[email protected]fd7b7c92009-08-20 19:38:302013
mmenke43758e62015-05-04 21:09:462014 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:402015 log.GetEntries(&entries);
2016
2017 EXPECT_EQ(3u, entries.size());
mikecirone8b85c432016-09-08 19:11:002018 EXPECT_TRUE(LogContainsBeginEvent(entries, 0, NetLogEventType::SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:172019 EXPECT_TRUE(LogContainsEvent(
mikecirone8b85c432016-09-08 19:11:002020 entries, 1, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
2021 NetLogEventPhase::NONE));
2022 EXPECT_TRUE(LogContainsEndEvent(entries, 2, NetLogEventType::SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:572023}
2024
mmenke6be122f2015-03-09 22:22:472025// Check that an async ConnectJob failure does not result in creation of a new
2026// ConnectJob when there's another pending request also waiting on its own
2027// ConnectJob. See http://crbug.com/463960.
2028TEST_F(ClientSocketPoolBaseTest, AsyncFailureWithPendingRequestWithJob) {
2029 CreatePool(2, 2);
2030 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2031
Matt Menkec6b3edf72019-03-19 17:00:392032 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2033 IsError(ERR_IO_PENDING));
2034 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2035 IsError(ERR_IO_PENDING));
mmenke6be122f2015-03-09 22:22:472036
robpercival214763f2016-07-01 23:27:012037 EXPECT_THAT(request(0)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
2038 EXPECT_THAT(request(1)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
mmenke6be122f2015-03-09 22:22:472039
2040 EXPECT_EQ(2, client_socket_factory_.allocation_count());
2041}
2042
[email protected]4d3b05d2010-01-27 21:27:292043TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]b22b5162010-03-16 07:53:102044 // TODO(eroman): Add back the log expectations! Removed them because the
2045 // ordering is difficult, and some may fire during destructor.
[email protected]211d21722009-07-22 15:48:532046 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:572047
2048 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:132049 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522050 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132051 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522052 TestCompletionCallback callback2;
[email protected]5fc08e32009-07-15 17:09:572053
Matt Menke28ac03e2019-02-25 22:25:502054 EXPECT_EQ(
2055 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:392056 handle.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502057 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2058 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2059 NetLogWithSource()));
vishal.b62985ca92015-04-17 08:45:512060 BoundTestNetLog log2;
tfarina428341112016-09-22 13:38:202061 EXPECT_EQ(
2062 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:392063 handle2.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:202064 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502065 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2066 pool_.get(), NetLogWithSource()));
[email protected]5fc08e32009-07-15 17:09:572067
[email protected]2431756e2010-09-29 20:26:132068 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:572069
[email protected]fd7b7c92009-08-20 19:38:302070
2071 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]fd7b7c92009-08-20 19:38:302072
robpercival214763f2016-07-01 23:27:012073 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132074 handle2.Reset();
[email protected]fd7b7c92009-08-20 19:38:302075
2076 // Now request 2 has actually finished.
[email protected]9e743cd2010-03-16 07:03:532077 // TODO(eroman): Add back log expectations.
[email protected]5fc08e32009-07-15 17:09:572078}
2079
[email protected]4d3b05d2010-01-27 21:27:292080TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:342081 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2082
[email protected]17a0c6c2009-08-04 00:07:042083 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2084
Matt Menkec6b3edf72019-03-19 17:00:392085 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
2086 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsError(ERR_IO_PENDING));
2087 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
2088 EXPECT_THAT(StartRequest(TestGroupId("a"), HIGHEST), IsError(ERR_IO_PENDING));
[email protected]974ebd62009-08-03 23:14:342089
Raul Tambre8335a6d2019-02-21 16:57:432090 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
Matt Menkec6b3edf72019-03-19 17:00:392091 static_cast<int>(pool_->NumConnectJobsInGroup(TestGroupId("a"))));
[email protected]2431756e2010-09-29 20:26:132092 (*requests())[2]->handle()->Reset();
2093 (*requests())[3]->handle()->Reset();
Raul Tambre8335a6d2019-02-21 16:57:432094 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
Matt Menkec6b3edf72019-03-19 17:00:392095 static_cast<int>(pool_->NumConnectJobsInGroup(TestGroupId("a"))));
[email protected]974ebd62009-08-03 23:14:342096
[email protected]2431756e2010-09-29 20:26:132097 (*requests())[1]->handle()->Reset();
Raul Tambre8335a6d2019-02-21 16:57:432098 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
Matt Menkec6b3edf72019-03-19 17:00:392099 static_cast<int>(pool_->NumConnectJobsInGroup(TestGroupId("a"))));
[email protected]974ebd62009-08-03 23:14:342100
[email protected]2431756e2010-09-29 20:26:132101 (*requests())[0]->handle()->Reset();
Raul Tambre8335a6d2019-02-21 16:57:432102 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
Matt Menkec6b3edf72019-03-19 17:00:392103 static_cast<int>(pool_->NumConnectJobsInGroup(TestGroupId("a"))));
[email protected]974ebd62009-08-03 23:14:342104}
2105
[email protected]5fc08e32009-07-15 17:09:572106// When requests and ConnectJobs are not coupled, the request will get serviced
2107// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:292108TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:532109 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:572110
2111 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:322112 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:572113
[email protected]2431756e2010-09-29 20:26:132114 std::vector<TestSocketRequest*> request_order;
2115 size_t completion_count; // unused
2116 TestSocketRequest req1(&request_order, &completion_count);
Matt Menke28ac03e2019-02-25 22:25:502117 int rv = req1.handle()->Init(
Matt Menkec6b3edf72019-03-19 17:00:392118 TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502119 ClientSocketPool::RespectLimits::ENABLED, req1.callback(),
2120 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012121 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2122 EXPECT_THAT(req1.WaitForResult(), IsOk());
[email protected]5fc08e32009-07-15 17:09:572123
2124 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
2125 // without a job.
2126 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2127
[email protected]2431756e2010-09-29 20:26:132128 TestSocketRequest req2(&request_order, &completion_count);
Matt Menke28ac03e2019-02-25 22:25:502129 rv = req2.handle()->Init(
Matt Menkec6b3edf72019-03-19 17:00:392130 TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502131 ClientSocketPool::RespectLimits::ENABLED, req2.callback(),
2132 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012133 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2431756e2010-09-29 20:26:132134 TestSocketRequest req3(&request_order, &completion_count);
Matt Menke28ac03e2019-02-25 22:25:502135 rv = req3.handle()->Init(
Matt Menkec6b3edf72019-03-19 17:00:392136 TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502137 ClientSocketPool::RespectLimits::ENABLED, req3.callback(),
2138 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012139 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:572140
2141 // Both Requests 2 and 3 are pending. We release socket 1 which should
2142 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:332143 req1.handle()->Reset();
[email protected]2da659e2013-05-23 20:51:342144 // Run the released socket wakeups.
fdoray5eeb7642016-06-22 16:11:282145 base::RunLoop().RunUntilIdle();
[email protected]a6c59f62009-07-29 16:33:332146 ASSERT_TRUE(req2.handle()->socket());
robpercival214763f2016-07-01 23:27:012147 EXPECT_THAT(req2.WaitForResult(), IsOk());
[email protected]a6c59f62009-07-29 16:33:332148 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:572149
2150 // Signal job 2, which should service request 3.
2151
2152 client_socket_factory_.SignalJobs();
robpercival214763f2016-07-01 23:27:012153 EXPECT_THAT(req3.WaitForResult(), IsOk());
[email protected]5fc08e32009-07-15 17:09:572154
Raul Tambre8335a6d2019-02-21 16:57:432155 ASSERT_EQ(3u, request_order.size());
[email protected]2431756e2010-09-29 20:26:132156 EXPECT_EQ(&req1, request_order[0]);
2157 EXPECT_EQ(&req2, request_order[1]);
2158 EXPECT_EQ(&req3, request_order[2]);
Matt Menkec6b3edf72019-03-19 17:00:392159 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]5fc08e32009-07-15 17:09:572160}
2161
2162// The requests are not coupled to the jobs. So, the requests should finish in
2163// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:292164TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:532165 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:572166 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:322167 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:572168
[email protected]2431756e2010-09-29 20:26:132169 std::vector<TestSocketRequest*> request_order;
2170 size_t completion_count; // unused
2171 TestSocketRequest req1(&request_order, &completion_count);
Matt Menke28ac03e2019-02-25 22:25:502172 int rv = req1.handle()->Init(
Matt Menkec6b3edf72019-03-19 17:00:392173 TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502174 ClientSocketPool::RespectLimits::ENABLED, req1.callback(),
2175 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012176 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:572177
[email protected]2431756e2010-09-29 20:26:132178 TestSocketRequest req2(&request_order, &completion_count);
Matt Menke28ac03e2019-02-25 22:25:502179 rv = req2.handle()->Init(
Matt Menkec6b3edf72019-03-19 17:00:392180 TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502181 ClientSocketPool::RespectLimits::ENABLED, req2.callback(),
2182 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012183 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:572184
2185 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:322186 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:572187
[email protected]2431756e2010-09-29 20:26:132188 TestSocketRequest req3(&request_order, &completion_count);
Matt Menke28ac03e2019-02-25 22:25:502189 rv = req3.handle()->Init(
Matt Menkec6b3edf72019-03-19 17:00:392190 TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502191 ClientSocketPool::RespectLimits::ENABLED, req3.callback(),
2192 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012193 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:572194
robpercival214763f2016-07-01 23:27:012195 EXPECT_THAT(req1.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
2196 EXPECT_THAT(req2.WaitForResult(), IsOk());
2197 EXPECT_THAT(req3.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]5fc08e32009-07-15 17:09:572198
Raul Tambre8335a6d2019-02-21 16:57:432199 ASSERT_EQ(3u, request_order.size());
[email protected]2431756e2010-09-29 20:26:132200 EXPECT_EQ(&req1, request_order[0]);
2201 EXPECT_EQ(&req2, request_order[1]);
2202 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:572203}
2204
[email protected]03b7c8c2013-07-20 04:38:552205// Test GetLoadState in the case there's only one socket request.
2206TEST_F(ClientSocketPoolBaseTest, LoadStateOneRequest) {
[email protected]211d21722009-07-22 15:48:532207 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]03b7c8c2013-07-20 04:38:552208 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
[email protected]5fc08e32009-07-15 17:09:572209
[email protected]2431756e2010-09-29 20:26:132210 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522211 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502212 int rv = handle.Init(
Matt Menkec6b3edf72019-03-19 17:00:392213 TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502214 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2215 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012216 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552217 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:572218
[email protected]03b7c8c2013-07-20 04:38:552219 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2220 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
2221
2222 // No point in completing the connection, since ClientSocketHandles only
2223 // expect the LoadState to be checked while connecting.
2224}
2225
2226// Test GetLoadState in the case there are two socket requests.
2227TEST_F(ClientSocketPoolBaseTest, LoadStateTwoRequests) {
2228 CreatePool(2, 2);
2229 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2230
2231 ClientSocketHandle handle;
2232 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502233 int rv = handle.Init(
Matt Menkec6b3edf72019-03-19 17:00:392234 TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502235 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2236 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012237 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
haavardm835c1d62015-04-22 08:18:002238 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_RESOLVING_HOST);
2239
2240 ClientSocketHandle handle2;
2241 TestCompletionCallback callback2;
Matt Menkec6b3edf72019-03-19 17:00:392242 rv = handle2.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152243 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502244 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2245 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012246 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
haavardm835c1d62015-04-22 08:18:002247 client_socket_factory_.SetJobLoadState(1, LOAD_STATE_RESOLVING_HOST);
2248
Matt Menke4b69f932019-03-04 16:20:012249 // Each handle should reflect the state of its own job.
haavardm835c1d62015-04-22 08:18:002250 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle.GetLoadState());
2251 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle2.GetLoadState());
2252
Matt Menke4b69f932019-03-04 16:20:012253 // Update the state of the first job.
haavardm835c1d62015-04-22 08:18:002254 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_CONNECTING);
2255
Matt Menke4b69f932019-03-04 16:20:012256 // Only the state of the first request should have changed.
haavardm835c1d62015-04-22 08:18:002257 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
haavardm835c1d62015-04-22 08:18:002258 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle2.GetLoadState());
Matt Menke4b69f932019-03-04 16:20:012259
2260 // Update the state of the second job.
2261 client_socket_factory_.SetJobLoadState(1, LOAD_STATE_SSL_HANDSHAKE);
2262
2263 // Only the state of the second request should have changed.
2264 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2265 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle2.GetLoadState());
2266
2267 // Second job connects and the first request gets the socket. The
2268 // second handle switches to the state of the remaining ConnectJob.
2269 client_socket_factory_.SignalJob(1);
2270 EXPECT_THAT(callback.WaitForResult(), IsOk());
2271 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
[email protected]03b7c8c2013-07-20 04:38:552272}
2273
2274// Test GetLoadState in the case the per-group limit is reached.
2275TEST_F(ClientSocketPoolBaseTest, LoadStateGroupLimit) {
2276 CreatePool(2, 1);
2277 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2278
2279 ClientSocketHandle handle;
2280 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502281 int rv = handle.Init(
Matt Menkec6b3edf72019-03-19 17:00:392282 TestGroupId("a"), params_, MEDIUM, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502283 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2284 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012285 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552286 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2287
2288 // Request another socket from the same pool, buth with a higher priority.
2289 // The first request should now be stalled at the socket group limit.
2290 ClientSocketHandle handle2;
2291 TestCompletionCallback callback2;
Matt Menkec6b3edf72019-03-19 17:00:392292 rv = handle2.Init(TestGroupId("a"), params_, HIGHEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152293 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502294 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2295 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012296 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552297 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2298 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
2299
2300 // The first handle should remain stalled as the other socket goes through
2301 // the connect process.
2302
2303 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2304 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2305 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle2.GetLoadState());
2306
2307 client_socket_factory_.SignalJob(0);
robpercival214763f2016-07-01 23:27:012308 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]03b7c8c2013-07-20 04:38:552309 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2310
2311 // Closing the second socket should cause the stalled handle to finally get a
2312 // ConnectJob.
2313 handle2.socket()->Disconnect();
2314 handle2.Reset();
2315 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2316}
2317
2318// Test GetLoadState in the case the per-pool limit is reached.
2319TEST_F(ClientSocketPoolBaseTest, LoadStatePoolLimit) {
2320 CreatePool(2, 2);
2321 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2322
2323 ClientSocketHandle handle;
2324 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502325 int rv = handle.Init(
Matt Menkec6b3edf72019-03-19 17:00:392326 TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502327 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2328 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012329 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552330
2331 // Request for socket from another pool.
2332 ClientSocketHandle handle2;
2333 TestCompletionCallback callback2;
Matt Menkec6b3edf72019-03-19 17:00:392334 rv = handle2.Init(TestGroupId("b"), params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152335 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502336 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2337 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012338 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552339
2340 // Request another socket from the first pool. Request should stall at the
2341 // socket pool limit.
2342 ClientSocketHandle handle3;
2343 TestCompletionCallback callback3;
Matt Menkec6b3edf72019-03-19 17:00:392344 rv = handle3.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152345 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
2350 // The third handle should remain stalled as the other sockets in its group
2351 // goes through the connect process.
2352
2353 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2354 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2355
2356 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2357 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
2358 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2359
2360 client_socket_factory_.SignalJob(0);
robpercival214763f2016-07-01 23:27:012361 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]03b7c8c2013-07-20 04:38:552362 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2363
2364 // Closing a socket should allow the stalled handle to finally get a new
2365 // ConnectJob.
2366 handle.socket()->Disconnect();
2367 handle.Reset();
2368 EXPECT_EQ(LOAD_STATE_CONNECTING, handle3.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:572369}
2370
Matt Menkeb57663b32019-03-01 17:17:102371TEST_F(ClientSocketPoolBaseTest, CertError) {
[email protected]e772db3f2010-07-12 18:11:132372 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
Matt Menkeb57663b32019-03-01 17:17:102373 connect_job_factory_->set_job_type(TestConnectJob::kMockCertErrorJob);
[email protected]e772db3f2010-07-12 18:11:132374
[email protected]2431756e2010-09-29 20:26:132375 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522376 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502377 EXPECT_EQ(
Matt Menkeb57663b32019-03-01 17:17:102378 ERR_CERT_COMMON_NAME_INVALID,
Matt Menkec6b3edf72019-03-19 17:00:392379 handle.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502380 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2381 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2382 NetLogWithSource()));
[email protected]2431756e2010-09-29 20:26:132383 EXPECT_TRUE(handle.is_initialized());
2384 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:132385}
2386
Matt Menkeb57663b32019-03-01 17:17:102387TEST_F(ClientSocketPoolBaseTest, AsyncCertError) {
[email protected]e772db3f2010-07-12 18:11:132388 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2389
Matt Menkeb57663b32019-03-01 17:17:102390 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingCertErrorJob);
[email protected]2431756e2010-09-29 20:26:132391 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522392 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502393 EXPECT_EQ(
2394 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:392395 handle.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502396 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2397 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2398 NetLogWithSource()));
Matt Menkec6b3edf72019-03-19 17:00:392399 EXPECT_EQ(LOAD_STATE_CONNECTING,
2400 pool_->GetLoadState(TestGroupId("a"), &handle));
Matt Menkeb57663b32019-03-01 17:17:102401 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CERT_COMMON_NAME_INVALID));
[email protected]2431756e2010-09-29 20:26:132402 EXPECT_TRUE(handle.is_initialized());
2403 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:132404}
2405
[email protected]e60e47a2010-07-14 03:37:182406TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) {
2407 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2408 connect_job_factory_->set_job_type(
2409 TestConnectJob::kMockAdditionalErrorStateJob);
2410
[email protected]2431756e2010-09-29 20:26:132411 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522412 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502413 EXPECT_EQ(
2414 ERR_CONNECTION_FAILED,
Matt Menkec6b3edf72019-03-19 17:00:392415 handle.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502416 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2417 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2418 NetLogWithSource()));
[email protected]2431756e2010-09-29 20:26:132419 EXPECT_FALSE(handle.is_initialized());
2420 EXPECT_FALSE(handle.socket());
2421 EXPECT_TRUE(handle.is_ssl_error());
Raul Tambre94493c652019-03-11 17:18:352422 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == nullptr);
[email protected]e60e47a2010-07-14 03:37:182423}
2424
2425TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) {
2426 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2427
2428 connect_job_factory_->set_job_type(
2429 TestConnectJob::kMockPendingAdditionalErrorStateJob);
[email protected]2431756e2010-09-29 20:26:132430 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522431 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502432 EXPECT_EQ(
2433 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:392434 handle.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502435 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2436 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2437 NetLogWithSource()));
Matt Menkec6b3edf72019-03-19 17:00:392438 EXPECT_EQ(LOAD_STATE_CONNECTING,
2439 pool_->GetLoadState(TestGroupId("a"), &handle));
robpercival214763f2016-07-01 23:27:012440 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]2431756e2010-09-29 20:26:132441 EXPECT_FALSE(handle.is_initialized());
2442 EXPECT_FALSE(handle.socket());
2443 EXPECT_TRUE(handle.is_ssl_error());
Raul Tambre94493c652019-03-11 17:18:352444 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == nullptr);
[email protected]e60e47a2010-07-14 03:37:182445}
2446
martijn003cd612016-05-19 22:24:382447// Make sure we can reuse sockets.
2448TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSocketsReuse) {
[email protected]64770b7d2011-11-16 04:30:412449 CreatePoolWithIdleTimeouts(
2450 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
[email protected]e7b1c6d2c2012-05-05 00:54:032451 base::TimeDelta(), // Time out unused sockets immediately.
2452 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2453
2454 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2455
2456 ClientSocketHandle handle;
2457 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502458 int rv = handle.Init(
Matt Menkec6b3edf72019-03-19 17:00:392459 TestGroupId("a"), params_, LOWEST, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502460 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2461 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012462 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
Matt Menkec6b3edf72019-03-19 17:00:392463 EXPECT_EQ(LOAD_STATE_CONNECTING,
2464 pool_->GetLoadState(TestGroupId("a"), &handle));
robpercival214763f2016-07-01 23:27:012465 ASSERT_THAT(callback.WaitForResult(), IsOk());
[email protected]e7b1c6d2c2012-05-05 00:54:032466
2467 // Use and release the socket.
Raul Tambre94493c652019-03-11 17:18:352468 EXPECT_EQ(1, handle.socket()->Write(nullptr, 1, CompletionOnceCallback(),
Ramin Halavati0a08cc82018-02-06 07:46:382469 TRAFFIC_ANNOTATION_FOR_TESTS));
[email protected]034df0f32013-01-07 23:17:482470 TestLoadTimingInfoConnectedNotReused(handle);
[email protected]e7b1c6d2c2012-05-05 00:54:032471 handle.Reset();
2472
2473 // Should now have one idle socket.
2474 ASSERT_EQ(1, pool_->IdleSocketCount());
2475
2476 // Request a new socket. This should reuse the old socket and complete
2477 // synchronously.
vishal.b62985ca92015-04-17 08:45:512478 BoundTestNetLog log;
Matt Menke28ac03e2019-02-25 22:25:502479 rv = handle.Init(
Matt Menkec6b3edf72019-03-19 17:00:392480 TestGroupId("a"), params_, LOWEST, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502481 ClientSocketPool::RespectLimits::ENABLED, CompletionOnceCallback(),
2482 ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound());
robpercival214763f2016-07-01 23:27:012483 ASSERT_THAT(rv, IsOk());
[email protected]e7b1c6d2c2012-05-05 00:54:032484 EXPECT_TRUE(handle.is_reused());
[email protected]034df0f32013-01-07 23:17:482485 TestLoadTimingInfoConnectedReused(handle);
[email protected]e7b1c6d2c2012-05-05 00:54:032486
Matt Menkec6b3edf72019-03-19 17:00:392487 ASSERT_TRUE(pool_->HasGroup(TestGroupId("a")));
2488 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
2489 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup(TestGroupId("a")));
[email protected]e7b1c6d2c2012-05-05 00:54:032490
mmenke43758e62015-05-04 21:09:462491 TestNetLogEntry::List entries;
[email protected]e7b1c6d2c2012-05-05 00:54:032492 log.GetEntries(&entries);
2493 EXPECT_TRUE(LogContainsEntryWithType(
mikecirone8b85c432016-09-08 19:11:002494 entries, 1, NetLogEventType::SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]e7b1c6d2c2012-05-05 00:54:032495}
2496
martijn003cd612016-05-19 22:24:382497// Make sure we cleanup old unused sockets.
Eric Romanb49715e2018-04-24 22:41:172498TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSocketsNoReuse) {
[email protected]e7b1c6d2c2012-05-05 00:54:032499 CreatePoolWithIdleTimeouts(
2500 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2501 base::TimeDelta(), // Time out unused sockets immediately
2502 base::TimeDelta()); // Time out used sockets immediately
[email protected]64770b7d2011-11-16 04:30:412503
2504 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2505
2506 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
2507
2508 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522509 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502510 int rv = handle.Init(
Matt Menkec6b3edf72019-03-19 17:00:392511 TestGroupId("a"), params_, 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));
[email protected]64770b7d2011-11-16 04:30:412517
2518 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522519 TestCompletionCallback callback2;
Matt Menkec6b3edf72019-03-19 17:00:392520 rv = handle2.Init(TestGroupId("a"), params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152521 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502522 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2523 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012524 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
Matt Menkec6b3edf72019-03-19 17:00:392525 EXPECT_EQ(LOAD_STATE_CONNECTING,
2526 pool_->GetLoadState(TestGroupId("a"), &handle2));
[email protected]64770b7d2011-11-16 04:30:412527
2528 // Cancel one of the requests. Wait for the other, which will get the first
2529 // job. Release the socket. Run the loop again to make sure the second
2530 // socket is sitting idle and the first one is released (since ReleaseSocket()
2531 // just posts a DoReleaseSocket() task).
2532
2533 handle.Reset();
robpercival214763f2016-07-01 23:27:012534 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]64770b7d2011-11-16 04:30:412535 // Use the socket.
Raul Tambre94493c652019-03-11 17:18:352536 EXPECT_EQ(1, handle2.socket()->Write(nullptr, 1, CompletionOnceCallback(),
Ramin Halavati0a08cc82018-02-06 07:46:382537 TRAFFIC_ANNOTATION_FOR_TESTS));
[email protected]64770b7d2011-11-16 04:30:412538 handle2.Reset();
2539
[email protected]e7b1c6d2c2012-05-05 00:54:032540 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
2541 // actually become pending until 2ms after they have been created. In order
2542 // to flush all tasks, we need to wait so that we know there are no
2543 // soon-to-be-pending tasks waiting.
Alex Clarke0def2092018-12-10 12:01:452544 FastForwardBy(base::TimeDelta::FromMilliseconds(10));
[email protected]64770b7d2011-11-16 04:30:412545
[email protected]e7b1c6d2c2012-05-05 00:54:032546 // Both sockets should now be idle.
[email protected]64770b7d2011-11-16 04:30:412547 ASSERT_EQ(2, pool_->IdleSocketCount());
2548
2549 // Request a new socket. This should cleanup the unused and timed out ones.
2550 // A new socket will be created rather than reusing the idle one.
vishal.b62985ca92015-04-17 08:45:512551 BoundTestNetLog log;
[email protected]6ecf2b92011-12-15 01:14:522552 TestCompletionCallback callback3;
Matt Menkec6b3edf72019-03-19 17:00:392553 rv = handle.Init(TestGroupId("a"), params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152554 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502555 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
2556 pool_.get(), log.bound());
robpercival214763f2016-07-01 23:27:012557 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
2558 ASSERT_THAT(callback3.WaitForResult(), IsOk());
[email protected]64770b7d2011-11-16 04:30:412559 EXPECT_FALSE(handle.is_reused());
2560
[email protected]e7b1c6d2c2012-05-05 00:54:032561 // Make sure the idle socket is closed.
Matt Menkec6b3edf72019-03-19 17:00:392562 ASSERT_TRUE(pool_->HasGroup(TestGroupId("a")));
2563 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
2564 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup(TestGroupId("a")));
[email protected]64770b7d2011-11-16 04:30:412565
mmenke43758e62015-05-04 21:09:462566 TestNetLogEntry::List entries;
[email protected]64770b7d2011-11-16 04:30:412567 log.GetEntries(&entries);
2568 EXPECT_FALSE(LogContainsEntryWithType(
mikecirone8b85c432016-09-08 19:11:002569 entries, 1, NetLogEventType::SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]64770b7d2011-11-16 04:30:412570}
2571
[email protected]2041cf342010-02-19 03:15:592572// Make sure that we process all pending requests even when we're stalling
[email protected]4f2abec2010-02-03 18:10:162573// because of multiple releasing disconnected sockets.
2574TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
2575 CreatePoolWithIdleTimeouts(
2576 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2577 base::TimeDelta(), // Time out unused sockets immediately.
2578 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2579
2580 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2581
2582 // Startup 4 connect jobs. Two of them will be pending.
2583
[email protected]2431756e2010-09-29 20:26:132584 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522585 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502586 int rv = handle.Init(
Matt Menkec6b3edf72019-03-19 17:00:392587 TestGroupId("a"), params_, LOWEST, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502588 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2589 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012590 EXPECT_THAT(rv, IsOk());
[email protected]4f2abec2010-02-03 18:10:162591
[email protected]2431756e2010-09-29 20:26:132592 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522593 TestCompletionCallback callback2;
Matt Menkec6b3edf72019-03-19 17:00:392594 rv = handle2.Init(TestGroupId("a"), params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152595 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502596 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2597 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012598 EXPECT_THAT(rv, IsOk());
[email protected]4f2abec2010-02-03 18:10:162599
[email protected]2431756e2010-09-29 20:26:132600 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:522601 TestCompletionCallback callback3;
Matt Menkec6b3edf72019-03-19 17:00:392602 rv = handle3.Init(TestGroupId("a"), params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152603 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502604 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
2605 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012606 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4f2abec2010-02-03 18:10:162607
[email protected]2431756e2010-09-29 20:26:132608 ClientSocketHandle handle4;
[email protected]6ecf2b92011-12-15 01:14:522609 TestCompletionCallback callback4;
Matt Menkec6b3edf72019-03-19 17:00:392610 rv = handle4.Init(TestGroupId("a"), params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152611 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502612 callback4.callback(), ClientSocketPool::ProxyAuthCallback(),
2613 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012614 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4f2abec2010-02-03 18:10:162615
2616 // Release two disconnected sockets.
2617
[email protected]2431756e2010-09-29 20:26:132618 handle.socket()->Disconnect();
2619 handle.Reset();
2620 handle2.socket()->Disconnect();
2621 handle2.Reset();
[email protected]4f2abec2010-02-03 18:10:162622
robpercival214763f2016-07-01 23:27:012623 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132624 EXPECT_FALSE(handle3.is_reused());
robpercival214763f2016-07-01 23:27:012625 EXPECT_THAT(callback4.WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132626 EXPECT_FALSE(handle4.is_reused());
[email protected]4f2abec2010-02-03 18:10:162627}
2628
[email protected]d7027bb2010-05-10 18:58:542629// Regression test for http://crbug.com/42267.
2630// When DoReleaseSocket() is processed for one socket, it is blocked because the
2631// other stalled groups all have releasing sockets, so no progress can be made.
2632TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
2633 CreatePoolWithIdleTimeouts(
2634 4 /* socket limit */, 4 /* socket limit per group */,
2635 base::TimeDelta(), // Time out unused sockets immediately.
2636 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2637
2638 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2639
2640 // Max out the socket limit with 2 per group.
2641
[email protected]2431756e2010-09-29 20:26:132642 ClientSocketHandle handle_a[4];
[email protected]6ecf2b92011-12-15 01:14:522643 TestCompletionCallback callback_a[4];
[email protected]2431756e2010-09-29 20:26:132644 ClientSocketHandle handle_b[4];
[email protected]6ecf2b92011-12-15 01:14:522645 TestCompletionCallback callback_b[4];
[email protected]d7027bb2010-05-10 18:58:542646
2647 for (int i = 0; i < 2; ++i) {
Matt Menkec6b3edf72019-03-19 17:00:392648 EXPECT_EQ(
2649 OK, handle_a[i].Init(TestGroupId("a"), params_, LOWEST, SocketTag(),
2650 ClientSocketPool::RespectLimits::ENABLED,
2651 callback_a[i].callback(),
2652 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2653 NetLogWithSource()));
2654 EXPECT_EQ(
2655 OK, handle_b[i].Init(TestGroupId("b"), params_, LOWEST, SocketTag(),
2656 ClientSocketPool::RespectLimits::ENABLED,
2657 callback_b[i].callback(),
2658 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2659 NetLogWithSource()));
[email protected]d7027bb2010-05-10 18:58:542660 }
[email protected]b89f7e42010-05-20 20:37:002661
[email protected]d7027bb2010-05-10 18:58:542662 // Make 4 pending requests, 2 per group.
2663
2664 for (int i = 2; i < 4; ++i) {
tfarina428341112016-09-22 13:38:202665 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:392666 handle_a[i].Init(TestGroupId("a"), params_, LOWEST, SocketTag(),
tfarina428341112016-09-22 13:38:202667 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502668 callback_a[i].callback(),
2669 ClientSocketPool::ProxyAuthCallback(),
2670 pool_.get(), NetLogWithSource()));
tfarina428341112016-09-22 13:38:202671 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:392672 handle_b[i].Init(TestGroupId("b"), params_, LOWEST, SocketTag(),
tfarina428341112016-09-22 13:38:202673 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502674 callback_b[i].callback(),
2675 ClientSocketPool::ProxyAuthCallback(),
2676 pool_.get(), NetLogWithSource()));
[email protected]d7027bb2010-05-10 18:58:542677 }
2678
2679 // Release b's socket first. The order is important, because in
2680 // DoReleaseSocket(), we'll process b's released socket, and since both b and
2681 // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
2682 // first, which has a releasing socket, so it refuses to start up another
2683 // ConnectJob. So, we used to infinite loop on this.
[email protected]2431756e2010-09-29 20:26:132684 handle_b[0].socket()->Disconnect();
2685 handle_b[0].Reset();
2686 handle_a[0].socket()->Disconnect();
2687 handle_a[0].Reset();
[email protected]d7027bb2010-05-10 18:58:542688
2689 // Used to get stuck here.
fdoray5eeb7642016-06-22 16:11:282690 base::RunLoop().RunUntilIdle();
[email protected]d7027bb2010-05-10 18:58:542691
[email protected]2431756e2010-09-29 20:26:132692 handle_b[1].socket()->Disconnect();
2693 handle_b[1].Reset();
2694 handle_a[1].socket()->Disconnect();
2695 handle_a[1].Reset();
[email protected]d7027bb2010-05-10 18:58:542696
2697 for (int i = 2; i < 4; ++i) {
robpercival214763f2016-07-01 23:27:012698 EXPECT_THAT(callback_b[i].WaitForResult(), IsOk());
2699 EXPECT_THAT(callback_a[i].WaitForResult(), IsOk());
[email protected]d7027bb2010-05-10 18:58:542700 }
2701}
2702
[email protected]fd4fe0b2010-02-08 23:02:152703TEST_F(ClientSocketPoolBaseTest,
2704 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
2705 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2706
2707 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2708
Matt Menkec6b3edf72019-03-19 17:00:392709 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2710 IsError(ERR_IO_PENDING));
2711 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2712 IsError(ERR_IO_PENDING));
2713 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2714 IsError(ERR_IO_PENDING));
2715 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2716 IsError(ERR_IO_PENDING));
[email protected]fd4fe0b2010-02-08 23:02:152717
robpercival214763f2016-07-01 23:27:012718 EXPECT_THAT((*requests())[0]->WaitForResult(), IsOk());
2719 EXPECT_THAT((*requests())[1]->WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132720 EXPECT_EQ(2u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152721
2722 // Releases one connection.
[email protected]2431756e2010-09-29 20:26:132723 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
robpercival214763f2016-07-01 23:27:012724 EXPECT_THAT((*requests())[2]->WaitForResult(), IsOk());
[email protected]fd4fe0b2010-02-08 23:02:152725
[email protected]2431756e2010-09-29 20:26:132726 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
robpercival214763f2016-07-01 23:27:012727 EXPECT_THAT((*requests())[3]->WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132728 EXPECT_EQ(4u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152729
2730 EXPECT_EQ(1, GetOrderOfRequest(1));
2731 EXPECT_EQ(2, GetOrderOfRequest(2));
2732 EXPECT_EQ(3, GetOrderOfRequest(3));
2733 EXPECT_EQ(4, GetOrderOfRequest(4));
2734
2735 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:132736 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(5));
[email protected]fd4fe0b2010-02-08 23:02:152737}
2738
[email protected]6ecf2b92011-12-15 01:14:522739class TestReleasingSocketRequest : public TestCompletionCallbackBase {
[email protected]4f1e4982010-03-02 18:31:042740 public:
[email protected]2431756e2010-09-29 20:26:132741 TestReleasingSocketRequest(TestClientSocketPool* pool,
2742 int expected_result,
[email protected]e60e47a2010-07-14 03:37:182743 bool reset_releasing_handle)
2744 : pool_(pool),
2745 expected_result_(expected_result),
Bence Béky8ddc2492018-06-13 01:02:042746 reset_releasing_handle_(reset_releasing_handle) {}
[email protected]6ecf2b92011-12-15 01:14:522747
Chris Watkins7a41d3552017-12-01 02:13:272748 ~TestReleasingSocketRequest() override = default;
[email protected]4f1e4982010-03-02 18:31:042749
2750 ClientSocketHandle* handle() { return &handle_; }
2751
Bence Béky8ddc2492018-06-13 01:02:042752 CompletionOnceCallback callback() {
2753 return base::BindOnce(&TestReleasingSocketRequest::OnComplete,
2754 base::Unretained(this));
2755 }
[email protected]4f1e4982010-03-02 18:31:042756
2757 private:
[email protected]6ecf2b92011-12-15 01:14:522758 void OnComplete(int result) {
2759 SetResult(result);
2760 if (reset_releasing_handle_)
2761 handle_.Reset();
2762
mmenked3641e12016-01-28 16:06:152763 scoped_refptr<TestSocketParams> con_params(new TestSocketParams());
Matt Menkec6b3edf72019-03-19 17:00:392764 EXPECT_EQ(
2765 expected_result_,
2766 handle2_.Init(
2767 TestGroupId("a"), con_params, DEFAULT_PRIORITY, SocketTag(),
2768 ClientSocketPool::RespectLimits::ENABLED, CompletionOnceCallback(),
2769 ClientSocketPool::ProxyAuthCallback(), pool_, NetLogWithSource()));
[email protected]6ecf2b92011-12-15 01:14:522770 }
2771
[email protected]2431756e2010-09-29 20:26:132772 TestClientSocketPool* const pool_;
[email protected]e60e47a2010-07-14 03:37:182773 int expected_result_;
2774 bool reset_releasing_handle_;
[email protected]4f1e4982010-03-02 18:31:042775 ClientSocketHandle handle_;
2776 ClientSocketHandle handle2_;
[email protected]4f1e4982010-03-02 18:31:042777};
2778
[email protected]e60e47a2010-07-14 03:37:182779
2780TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) {
2781 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2782
Matt Menkec6b3edf72019-03-19 17:00:392783 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
2784 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
2785 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
[email protected]e60e47a2010-07-14 03:37:182786
[email protected]2431756e2010-09-29 20:26:132787 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]e60e47a2010-07-14 03:37:182788 client_socket_factory_.allocation_count());
2789
2790 connect_job_factory_->set_job_type(
2791 TestConnectJob::kMockPendingAdditionalErrorStateJob);
2792 TestReleasingSocketRequest req(pool_.get(), OK, false);
tfarina428341112016-09-22 13:38:202793 EXPECT_EQ(
2794 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:392795 req.handle()->Init(TestGroupId("a"), params_, DEFAULT_PRIORITY,
2796 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502797 req.callback(), ClientSocketPool::ProxyAuthCallback(),
2798 pool_.get(), NetLogWithSource()));
[email protected]e60e47a2010-07-14 03:37:182799 // The next job should complete synchronously
2800 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2801
robpercival214763f2016-07-01 23:27:012802 EXPECT_THAT(req.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:182803 EXPECT_FALSE(req.handle()->is_initialized());
2804 EXPECT_FALSE(req.handle()->socket());
2805 EXPECT_TRUE(req.handle()->is_ssl_error());
Raul Tambre94493c652019-03-11 17:18:352806 EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() ==
2807 nullptr);
[email protected]e60e47a2010-07-14 03:37:182808}
2809
[email protected]b6501d3d2010-06-03 23:53:342810// http://crbug.com/44724 regression test.
2811// We start releasing the pool when we flush on network change. When that
2812// happens, the only active references are in the ClientSocketHandles. When a
2813// ConnectJob completes and calls back into the last ClientSocketHandle, that
2814// callback can release the last reference and delete the pool. After the
2815// callback finishes, we go back to the stack frame within the now-deleted pool.
2816// Executing any code that refers to members of the now-deleted pool can cause
2817// crashes.
2818TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
2819 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2820 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2821
2822 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522823 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502824 EXPECT_EQ(
2825 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:392826 handle.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502827 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2828 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2829 NetLogWithSource()));
[email protected]b6501d3d2010-06-03 23:53:342830
[email protected]7af985a2012-12-14 22:40:422831 pool_->FlushWithError(ERR_NETWORK_CHANGED);
[email protected]b6501d3d2010-06-03 23:53:342832
2833 // We'll call back into this now.
2834 callback.WaitForResult();
2835}
2836
[email protected]a7e38572010-06-07 18:22:242837TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
2838 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2839 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2840
2841 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522842 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502843 EXPECT_EQ(
2844 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:392845 handle.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502846 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2847 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2848 NetLogWithSource()));
robpercival214763f2016-07-01 23:27:012849 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]a7e38572010-06-07 18:22:242850 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2851
[email protected]7af985a2012-12-14 22:40:422852 pool_->FlushWithError(ERR_NETWORK_CHANGED);
[email protected]a7e38572010-06-07 18:22:242853
2854 handle.Reset();
fdoray5eeb7642016-06-22 16:11:282855 base::RunLoop().RunUntilIdle();
[email protected]a7e38572010-06-07 18:22:242856
Matt Menke28ac03e2019-02-25 22:25:502857 EXPECT_EQ(
2858 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:392859 handle.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502860 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2861 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2862 NetLogWithSource()));
robpercival214763f2016-07-01 23:27:012863 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]a7e38572010-06-07 18:22:242864 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2865}
2866
[email protected]6ecf2b92011-12-15 01:14:522867class ConnectWithinCallback : public TestCompletionCallbackBase {
[email protected]06f92462010-08-31 19:24:142868 public:
Matt Menkec6b3edf72019-03-19 17:00:392869 ConnectWithinCallback(const ClientSocketPool::GroupId& group_id,
Bence Béky8ddc2492018-06-13 01:02:042870 const scoped_refptr<TestSocketParams>& params,
2871 TestClientSocketPool* pool)
Matt Menkec6b3edf72019-03-19 17:00:392872 : group_id_(group_id), params_(params), pool_(pool) {}
[email protected]06f92462010-08-31 19:24:142873
Chris Watkins7a41d3552017-12-01 02:13:272874 ~ConnectWithinCallback() override = default;
[email protected]06f92462010-08-31 19:24:142875
2876 int WaitForNestedResult() {
2877 return nested_callback_.WaitForResult();
2878 }
2879
Bence Béky8ddc2492018-06-13 01:02:042880 CompletionOnceCallback callback() {
2881 return base::BindOnce(&ConnectWithinCallback::OnComplete,
2882 base::Unretained(this));
2883 }
[email protected]6ecf2b92011-12-15 01:14:522884
[email protected]06f92462010-08-31 19:24:142885 private:
[email protected]6ecf2b92011-12-15 01:14:522886 void OnComplete(int result) {
2887 SetResult(result);
Matt Menke28ac03e2019-02-25 22:25:502888 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:392889 handle_.Init(group_id_, params_, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502890 ClientSocketPool::RespectLimits::ENABLED,
2891 nested_callback_.callback(),
2892 ClientSocketPool::ProxyAuthCallback(), pool_,
2893 NetLogWithSource()));
[email protected]6ecf2b92011-12-15 01:14:522894 }
2895
Matt Menkec6b3edf72019-03-19 17:00:392896 const ClientSocketPool::GroupId group_id_;
[email protected]06f92462010-08-31 19:24:142897 const scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:132898 TestClientSocketPool* const pool_;
[email protected]06f92462010-08-31 19:24:142899 ClientSocketHandle handle_;
[email protected]6ecf2b92011-12-15 01:14:522900 TestCompletionCallback nested_callback_;
2901
2902 DISALLOW_COPY_AND_ASSIGN(ConnectWithinCallback);
[email protected]06f92462010-08-31 19:24:142903};
2904
2905TEST_F(ClientSocketPoolBaseTest, AbortAllRequestsOnFlush) {
2906 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2907
2908 // First job will be waiting until it gets aborted.
2909 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2910
2911 ClientSocketHandle handle;
Matt Menkec6b3edf72019-03-19 17:00:392912 ConnectWithinCallback callback(TestGroupId("a"), params_, pool_.get());
Matt Menke28ac03e2019-02-25 22:25:502913 EXPECT_EQ(
2914 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:392915 handle.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502916 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2917 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2918 NetLogWithSource()));
[email protected]06f92462010-08-31 19:24:142919
2920 // Second job will be started during the first callback, and will
2921 // asynchronously complete with OK.
2922 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]7af985a2012-12-14 22:40:422923 pool_->FlushWithError(ERR_NETWORK_CHANGED);
robpercival214763f2016-07-01 23:27:012924 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NETWORK_CHANGED));
2925 EXPECT_THAT(callback.WaitForNestedResult(), IsOk());
[email protected]06f92462010-08-31 19:24:142926}
2927
Matt Menke141b87f22019-01-30 02:43:032928TEST_F(ClientSocketPoolBaseTest, BackupSocketWaitsForHostResolution) {
2929 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2930 pool_->EnableConnectBackupJobs();
2931
2932 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2933 ClientSocketHandle handle;
2934 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502935 EXPECT_EQ(
2936 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:392937 handle.Init(TestGroupId("bar"), params_, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502938 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2939 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2940 NetLogWithSource()));
Matt Menke141b87f22019-01-30 02:43:032941 // The backup timer fires but doesn't start a new ConnectJob while resolving
2942 // the hostname.
2943 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_RESOLVING_HOST);
2944 FastForwardBy(base::TimeDelta::FromMilliseconds(
2945 ClientSocketPool::kMaxConnectRetryIntervalMs * 100));
2946 EXPECT_EQ(1, client_socket_factory_.allocation_count());
2947
2948 // Once the ConnectJob has finished resolving the hostname, the backup timer
2949 // will create a ConnectJob when it fires.
2950 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_CONNECTING);
2951 FastForwardBy(base::TimeDelta::FromMilliseconds(
2952 ClientSocketPool::kMaxConnectRetryIntervalMs));
2953 EXPECT_EQ(2, client_socket_factory_.allocation_count());
2954}
2955
2956// Test that no backup socket is created when a ConnectJob connects before it
2957// completes.
2958TEST_F(ClientSocketPoolBaseTest, NoBackupSocketWhenConnected) {
2959 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2960 pool_->EnableConnectBackupJobs();
2961
2962 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2963 ClientSocketHandle handle;
2964 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502965 EXPECT_EQ(
2966 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:392967 handle.Init(TestGroupId("bar"), params_, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:502968 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2969 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2970 NetLogWithSource()));
Matt Menke141b87f22019-01-30 02:43:032971 // The backup timer fires but doesn't start a new ConnectJob while resolving
2972 // the hostname.
2973 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_RESOLVING_HOST);
2974 FastForwardBy(base::TimeDelta::FromMilliseconds(
2975 ClientSocketPool::kMaxConnectRetryIntervalMs * 100));
2976 EXPECT_EQ(1, client_socket_factory_.allocation_count());
2977
2978 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2979 client_socket_factory_.SetJobHasEstablishedConnection(0);
2980 FastForwardBy(base::TimeDelta::FromMilliseconds(
2981 ClientSocketPool::kMaxConnectRetryIntervalMs * 100));
2982 EXPECT_EQ(1, client_socket_factory_.allocation_count());
2983}
2984
[email protected]25eea382010-07-10 23:55:262985// Cancel a pending socket request while we're at max sockets,
2986// and verify that the backup socket firing doesn't cause a crash.
2987TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
2988 // Max 4 sockets globally, max 4 sockets per group.
2989 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
[email protected]06d94042010-08-25 01:45:222990 pool_->EnableConnectBackupJobs();
[email protected]25eea382010-07-10 23:55:262991
[email protected]4baaf9d2010-08-31 15:15:442992 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2993 // timer.
[email protected]25eea382010-07-10 23:55:262994 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2995 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522996 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502997 EXPECT_EQ(
2998 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:392999 handle.Init(TestGroupId("bar"), params_, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:503000 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
3001 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
3002 NetLogWithSource()));
[email protected]25eea382010-07-10 23:55:263003
3004 // Start (MaxSockets - 1) connected sockets to reach max sockets.
3005 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3006 ClientSocketHandle handles[kDefaultMaxSockets];
3007 for (int i = 1; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:523008 TestCompletionCallback callback;
Matt Menkec6b3edf72019-03-19 17:00:393009 EXPECT_EQ(OK, handles[i].Init(TestGroupId("bar"), params_, DEFAULT_PRIORITY,
3010 SocketTag(),
tfarina428341112016-09-22 13:38:203011 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503012 callback.callback(),
3013 ClientSocketPool::ProxyAuthCallback(),
3014 pool_.get(), NetLogWithSource()));
[email protected]25eea382010-07-10 23:55:263015 }
3016
fdoray5eeb7642016-06-22 16:11:283017 base::RunLoop().RunUntilIdle();
[email protected]25eea382010-07-10 23:55:263018
3019 // Cancel the pending request.
3020 handle.Reset();
3021
3022 // Wait for the backup timer to fire (add some slop to ensure it fires)
Alex Clarke0def2092018-12-10 12:01:453023 FastForwardBy(base::TimeDelta::FromMilliseconds(
[email protected]26b9973962012-01-28 00:57:003024 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]25eea382010-07-10 23:55:263025
[email protected]25eea382010-07-10 23:55:263026 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
3027}
3028
[email protected]3f00be82010-09-27 19:50:023029TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterCancelingAllRequests) {
[email protected]4baaf9d2010-08-31 15:15:443030 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3031 pool_->EnableConnectBackupJobs();
3032
3033 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
3034 // timer.
3035 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3036 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:523037 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:503038 EXPECT_EQ(
3039 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:393040 handle.Init(TestGroupId("bar"), params_, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:503041 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
3042 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
3043 NetLogWithSource()));
Matt Menkec6b3edf72019-03-19 17:00:393044 ASSERT_TRUE(pool_->HasGroup(TestGroupId("bar")));
3045 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("bar")));
3046 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("bar")));
3047 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("bar")));
[email protected]4baaf9d2010-08-31 15:15:443048
3049 // Cancel the socket request. This should cancel the backup timer. Wait for
3050 // the backup time to see if it indeed got canceled.
3051 handle.Reset();
3052 // Wait for the backup timer to fire (add some slop to ensure it fires)
Alex Clarke0def2092018-12-10 12:01:453053 FastForwardBy(base::TimeDelta::FromMilliseconds(
[email protected]26b9973962012-01-28 00:57:003054 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
Matt Menkec6b3edf72019-03-19 17:00:393055 ASSERT_TRUE(pool_->HasGroup(TestGroupId("bar")));
3056 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("bar")));
[email protected]4baaf9d2010-08-31 15:15:443057}
3058
[email protected]3f00be82010-09-27 19:50:023059TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterFinishingAllRequests) {
3060 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3061 pool_->EnableConnectBackupJobs();
3062
3063 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
3064 // timer.
3065 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3066 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:523067 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:503068 EXPECT_EQ(
3069 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:393070 handle.Init(TestGroupId("bar"), params_, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:503071 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
3072 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
3073 NetLogWithSource()));
[email protected]3f00be82010-09-27 19:50:023074 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3075 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523076 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203077 EXPECT_EQ(
3078 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:393079 handle2.Init(TestGroupId("bar"), params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203080 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503081 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3082 pool_.get(), NetLogWithSource()));
Matt Menkec6b3edf72019-03-19 17:00:393083 ASSERT_TRUE(pool_->HasGroup(TestGroupId("bar")));
3084 EXPECT_EQ(2u, pool_->NumConnectJobsInGroup(TestGroupId("bar")));
[email protected]3f00be82010-09-27 19:50:023085
3086 // Cancel request 1 and then complete request 2. With the requests finished,
3087 // the backup timer should be cancelled.
3088 handle.Reset();
robpercival214763f2016-07-01 23:27:013089 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]3f00be82010-09-27 19:50:023090 // Wait for the backup timer to fire (add some slop to ensure it fires)
Alex Clarke0def2092018-12-10 12:01:453091 FastForwardBy(base::TimeDelta::FromMilliseconds(
[email protected]26b9973962012-01-28 00:57:003092 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]3f00be82010-09-27 19:50:023093}
3094
[email protected]eb5a99382010-07-11 03:18:263095// Test delayed socket binding for the case where we have two connects,
3096// and while one is waiting on a connect, the other frees up.
3097// The socket waiting on a connect should switch immediately to the freed
3098// up socket.
3099TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
3100 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3101 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3102
3103 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523104 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:503105 EXPECT_EQ(
3106 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:393107 handle1.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:503108 ClientSocketPool::RespectLimits::ENABLED,
3109 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3110 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013111 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:263112
3113 // No idle sockets, no pending jobs.
3114 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menkec6b3edf72019-03-19 17:00:393115 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263116
3117 // Create a second socket to the same host, but this one will wait.
3118 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3119 ClientSocketHandle handle2;
Matt Menke28ac03e2019-02-25 22:25:503120 EXPECT_EQ(
3121 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:393122 handle2.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:503123 ClientSocketPool::RespectLimits::ENABLED,
3124 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3125 pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:263126 // No idle sockets, and one connecting job.
3127 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menkec6b3edf72019-03-19 17:00:393128 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263129
3130 // Return the first handle to the pool. This will initiate the delayed
3131 // binding.
3132 handle1.Reset();
3133
fdoray5eeb7642016-06-22 16:11:283134 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263135
3136 // Still no idle sockets, still one pending connect job.
3137 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menkec6b3edf72019-03-19 17:00:393138 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263139
3140 // The second socket connected, even though it was a Waiting Job.
robpercival214763f2016-07-01 23:27:013141 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:263142
3143 // And we can see there is still one job waiting.
Matt Menkec6b3edf72019-03-19 17:00:393144 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263145
3146 // Finally, signal the waiting Connect.
3147 client_socket_factory_.SignalJobs();
Matt Menkec6b3edf72019-03-19 17:00:393148 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263149
fdoray5eeb7642016-06-22 16:11:283150 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263151}
3152
3153// Test delayed socket binding when a group is at capacity and one
3154// of the group's sockets frees up.
3155TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
3156 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3157 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3158
3159 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523160 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:503161 EXPECT_EQ(
3162 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:393163 handle1.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:503164 ClientSocketPool::RespectLimits::ENABLED,
3165 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3166 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013167 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:263168
3169 // No idle sockets, no pending jobs.
3170 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menkec6b3edf72019-03-19 17:00:393171 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263172
3173 // Create a second socket to the same host, but this one will wait.
3174 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3175 ClientSocketHandle handle2;
Matt Menke28ac03e2019-02-25 22:25:503176 EXPECT_EQ(
3177 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:393178 handle2.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:503179 ClientSocketPool::RespectLimits::ENABLED,
3180 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3181 pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:263182 // No idle sockets, and one connecting job.
3183 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menkec6b3edf72019-03-19 17:00:393184 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263185
3186 // Return the first handle to the pool. This will initiate the delayed
3187 // binding.
3188 handle1.Reset();
3189
fdoray5eeb7642016-06-22 16:11:283190 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263191
3192 // Still no idle sockets, still one pending connect job.
3193 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menkec6b3edf72019-03-19 17:00:393194 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263195
3196 // The second socket connected, even though it was a Waiting Job.
robpercival214763f2016-07-01 23:27:013197 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:263198
3199 // And we can see there is still one job waiting.
Matt Menkec6b3edf72019-03-19 17:00:393200 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263201
3202 // Finally, signal the waiting Connect.
3203 client_socket_factory_.SignalJobs();
Matt Menkec6b3edf72019-03-19 17:00:393204 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263205
fdoray5eeb7642016-06-22 16:11:283206 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263207}
3208
3209// Test out the case where we have one socket connected, one
3210// connecting, when the first socket finishes and goes idle.
[email protected]2abfe90a2010-08-25 17:49:513211// Although the second connection is pending, the second request
[email protected]eb5a99382010-07-11 03:18:263212// should complete, by taking the first socket's idle socket.
3213TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
3214 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3215 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3216
3217 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523218 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:503219 EXPECT_EQ(
3220 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:393221 handle1.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:503222 ClientSocketPool::RespectLimits::ENABLED,
3223 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3224 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013225 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:263226
3227 // No idle sockets, no pending jobs.
3228 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menkec6b3edf72019-03-19 17:00:393229 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263230
3231 // Create a second socket to the same host, but this one will wait.
3232 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3233 ClientSocketHandle handle2;
Matt Menke28ac03e2019-02-25 22:25:503234 EXPECT_EQ(
3235 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:393236 handle2.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:503237 ClientSocketPool::RespectLimits::ENABLED,
3238 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3239 pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:263240 // No idle sockets, and one connecting job.
3241 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menkec6b3edf72019-03-19 17:00:393242 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263243
3244 // Return the first handle to the pool. This will initiate the delayed
3245 // binding.
3246 handle1.Reset();
3247
fdoray5eeb7642016-06-22 16:11:283248 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263249
3250 // Still no idle sockets, still one pending connect job.
3251 EXPECT_EQ(0, pool_->IdleSocketCount());
Matt Menkec6b3edf72019-03-19 17:00:393252 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263253
3254 // The second socket connected, even though it was a Waiting Job.
robpercival214763f2016-07-01 23:27:013255 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:263256
3257 // And we can see there is still one job waiting.
Matt Menkec6b3edf72019-03-19 17:00:393258 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263259
3260 // Finally, signal the waiting Connect.
3261 client_socket_factory_.SignalJobs();
Matt Menkec6b3edf72019-03-19 17:00:393262 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
[email protected]eb5a99382010-07-11 03:18:263263
fdoray5eeb7642016-06-22 16:11:283264 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263265}
3266
[email protected]2abfe90a2010-08-25 17:49:513267// Cover the case where on an available socket slot, we have one pending
3268// request that completes synchronously, thereby making the Group empty.
3269TEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) {
3270 const int kUnlimitedSockets = 100;
3271 const int kOneSocketPerGroup = 1;
3272 CreatePool(kUnlimitedSockets, kOneSocketPerGroup);
3273
3274 // Make the first request asynchronous fail.
3275 // This will free up a socket slot later.
3276 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
3277
3278 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523279 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203280 EXPECT_EQ(
3281 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:393282 handle1.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203283 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503284 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3285 pool_.get(), NetLogWithSource()));
Matt Menkec6b3edf72019-03-19 17:00:393286 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
[email protected]2abfe90a2010-08-25 17:49:513287
3288 // Make the second request synchronously fail. This should make the Group
3289 // empty.
3290 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3291 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523292 TestCompletionCallback callback2;
[email protected]2abfe90a2010-08-25 17:49:513293 // It'll be ERR_IO_PENDING now, but the TestConnectJob will synchronously fail
3294 // when created.
tfarina428341112016-09-22 13:38:203295 EXPECT_EQ(
3296 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:393297 handle2.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203298 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503299 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3300 pool_.get(), NetLogWithSource()));
[email protected]2abfe90a2010-08-25 17:49:513301
Matt Menkec6b3edf72019-03-19 17:00:393302 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
[email protected]2abfe90a2010-08-25 17:49:513303
robpercival214763f2016-07-01 23:27:013304 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
3305 EXPECT_THAT(callback2.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
Matt Menkec6b3edf72019-03-19 17:00:393306 EXPECT_FALSE(pool_->HasGroup(TestGroupId("a")));
[email protected]2abfe90a2010-08-25 17:49:513307}
3308
[email protected]e1b54dc2010-10-06 21:27:223309TEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) {
3310 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3311
3312 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3313
3314 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523315 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203316 EXPECT_EQ(
3317 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:393318 handle1.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203319 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503320 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3321 pool_.get(), NetLogWithSource()));
[email protected]e1b54dc2010-10-06 21:27:223322
3323 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523324 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203325 EXPECT_EQ(
3326 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:393327 handle2.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203328 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503329 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3330 pool_.get(), NetLogWithSource()));
[email protected]e1b54dc2010-10-06 21:27:223331 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:523332 TestCompletionCallback callback3;
tfarina428341112016-09-22 13:38:203333 EXPECT_EQ(
3334 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:393335 handle3.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203336 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503337 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
3338 pool_.get(), NetLogWithSource()));
[email protected]e1b54dc2010-10-06 21:27:223339
robpercival214763f2016-07-01 23:27:013340 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3341 EXPECT_THAT(callback2.WaitForResult(), IsOk());
3342 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]e1b54dc2010-10-06 21:27:223343
3344 // Use the socket.
Raul Tambre94493c652019-03-11 17:18:353345 EXPECT_EQ(1, handle1.socket()->Write(nullptr, 1, CompletionOnceCallback(),
Ramin Halavati0a08cc82018-02-06 07:46:383346 TRAFFIC_ANNOTATION_FOR_TESTS));
Raul Tambre94493c652019-03-11 17:18:353347 EXPECT_EQ(1, handle3.socket()->Write(nullptr, 1, CompletionOnceCallback(),
Ramin Halavati0a08cc82018-02-06 07:46:383348 TRAFFIC_ANNOTATION_FOR_TESTS));
[email protected]e1b54dc2010-10-06 21:27:223349
3350 handle1.Reset();
3351 handle2.Reset();
3352 handle3.Reset();
3353
Matt Menkec6b3edf72019-03-19 17:00:393354 EXPECT_EQ(OK, handle1.Init(
3355 TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
3356 ClientSocketPool::RespectLimits::ENABLED,
3357 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3358 pool_.get(), NetLogWithSource()));
3359 EXPECT_EQ(OK, handle2.Init(
3360 TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
3361 ClientSocketPool::RespectLimits::ENABLED,
3362 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3363 pool_.get(), NetLogWithSource()));
3364 EXPECT_EQ(OK, handle3.Init(
3365 TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
3366 ClientSocketPool::RespectLimits::ENABLED,
3367 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
3368 pool_.get(), NetLogWithSource()));
[email protected]e1b54dc2010-10-06 21:27:223369
3370 EXPECT_TRUE(handle1.socket()->WasEverUsed());
3371 EXPECT_TRUE(handle2.socket()->WasEverUsed());
3372 EXPECT_FALSE(handle3.socket()->WasEverUsed());
3373}
3374
[email protected]2c2bef152010-10-13 00:55:033375TEST_F(ClientSocketPoolBaseTest, RequestSockets) {
3376 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3377 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3378
Matt Menkec6b3edf72019-03-19 17:00:393379 pool_->RequestSockets(TestGroupId("a"), &params_, 2, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033380
Matt Menkec6b3edf72019-03-19 17:00:393381 ASSERT_TRUE(pool_->HasGroup(TestGroupId("a")));
3382 EXPECT_EQ(2u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
3383 EXPECT_EQ(2u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
3384 EXPECT_EQ(2u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
3385 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033386
3387 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523388 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203389 EXPECT_EQ(
3390 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:393391 handle1.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203392 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503393 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3394 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033395
3396 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523397 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203398 EXPECT_EQ(
3399 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:393400 handle2.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203401 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503402 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3403 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033404
Matt Menkec6b3edf72019-03-19 17:00:393405 EXPECT_EQ(2u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
3406 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
3407 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
3408 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033409
robpercival214763f2016-07-01 23:27:013410 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3411 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033412 handle1.Reset();
3413 handle2.Reset();
3414
Matt Menkec6b3edf72019-03-19 17:00:393415 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
3416 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
3417 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
3418 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033419}
3420
3421TEST_F(ClientSocketPoolBaseTest, RequestSocketsWhenAlreadyHaveAConnectJob) {
3422 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3423 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3424
3425 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523426 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203427 EXPECT_EQ(
3428 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:393429 handle1.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203430 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503431 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3432 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033433
Matt Menkec6b3edf72019-03-19 17:00:393434 ASSERT_TRUE(pool_->HasGroup(TestGroupId("a")));
3435 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
3436 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
3437 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
3438 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033439
Matt Menkec6b3edf72019-03-19 17:00:393440 pool_->RequestSockets(TestGroupId("a"), &params_, 2, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033441
Matt Menkec6b3edf72019-03-19 17:00:393442 EXPECT_EQ(2u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
3443 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
3444 EXPECT_EQ(1u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
3445 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033446
3447 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523448 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203449 EXPECT_EQ(
3450 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:393451 handle2.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203452 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503453 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3454 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033455
Matt Menkec6b3edf72019-03-19 17:00:393456 EXPECT_EQ(2u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
3457 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
3458 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
3459 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033460
robpercival214763f2016-07-01 23:27:013461 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3462 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033463 handle1.Reset();
3464 handle2.Reset();
3465
Matt Menkec6b3edf72019-03-19 17:00:393466 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
3467 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
3468 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
3469 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033470}
3471
3472TEST_F(ClientSocketPoolBaseTest,
3473 RequestSocketsWhenAlreadyHaveMultipleConnectJob) {
3474 CreatePool(4, 4);
3475 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3476
3477 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523478 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203479 EXPECT_EQ(
3480 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:393481 handle1.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203482 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503483 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3484 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033485
3486 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523487 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203488 EXPECT_EQ(
3489 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:393490 handle2.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203491 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503492 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3493 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033494
3495 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:523496 TestCompletionCallback callback3;
tfarina428341112016-09-22 13:38:203497 EXPECT_EQ(
3498 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:393499 handle3.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203500 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503501 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
3502 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033503
Matt Menkec6b3edf72019-03-19 17:00:393504 ASSERT_TRUE(pool_->HasGroup(TestGroupId("a")));
3505 EXPECT_EQ(3u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
3506 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
3507 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
3508 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033509
Matt Menkec6b3edf72019-03-19 17:00:393510 pool_->RequestSockets(TestGroupId("a"), &params_, 2, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033511
Matt Menkec6b3edf72019-03-19 17:00:393512 EXPECT_EQ(3u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
3513 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
3514 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
3515 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033516
robpercival214763f2016-07-01 23:27:013517 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3518 EXPECT_THAT(callback2.WaitForResult(), IsOk());
3519 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033520 handle1.Reset();
3521 handle2.Reset();
3522 handle3.Reset();
3523
Matt Menkec6b3edf72019-03-19 17:00:393524 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
3525 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
3526 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
3527 EXPECT_EQ(3u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033528}
3529
3530TEST_F(ClientSocketPoolBaseTest, RequestSocketsAtMaxSocketLimit) {
3531 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3532 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3533
Matt Menkec6b3edf72019-03-19 17:00:393534 ASSERT_FALSE(pool_->HasGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033535
Matt Menkec6b3edf72019-03-19 17:00:393536 pool_->RequestSockets(TestGroupId("a"), &params_, kDefaultMaxSockets,
3537 NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033538
Matt Menkec6b3edf72019-03-19 17:00:393539 ASSERT_TRUE(pool_->HasGroup(TestGroupId("a")));
Raul Tambre8335a6d2019-02-21 16:57:433540 EXPECT_EQ(kDefaultMaxSockets,
Matt Menkec6b3edf72019-03-19 17:00:393541 static_cast<int>(pool_->NumConnectJobsInGroup(TestGroupId("a"))));
Raul Tambre8335a6d2019-02-21 16:57:433542 EXPECT_EQ(kDefaultMaxSockets,
Matt Menkec6b3edf72019-03-19 17:00:393543 static_cast<int>(
3544 pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a"))));
Raul Tambre8335a6d2019-02-21 16:57:433545 EXPECT_EQ(kDefaultMaxSockets,
Matt Menkec6b3edf72019-03-19 17:00:393546 static_cast<int>(
3547 pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a"))));
[email protected]2c2bef152010-10-13 00:55:033548
Matt Menkec6b3edf72019-03-19 17:00:393549 ASSERT_FALSE(pool_->HasGroup(TestGroupId("b")));
[email protected]2c2bef152010-10-13 00:55:033550
Matt Menkec6b3edf72019-03-19 17:00:393551 pool_->RequestSockets(TestGroupId("b"), &params_, kDefaultMaxSockets,
3552 NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033553
Matt Menkec6b3edf72019-03-19 17:00:393554 ASSERT_FALSE(pool_->HasGroup(TestGroupId("b")));
[email protected]2c2bef152010-10-13 00:55:033555}
3556
3557TEST_F(ClientSocketPoolBaseTest, RequestSocketsHitMaxSocketLimit) {
3558 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3559 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3560
Matt Menkec6b3edf72019-03-19 17:00:393561 ASSERT_FALSE(pool_->HasGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033562
Matt Menkec6b3edf72019-03-19 17:00:393563 pool_->RequestSockets(TestGroupId("a"), &params_, kDefaultMaxSockets - 1,
Charlie Harrison55ce6082018-05-14 02:25:573564 NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033565
Matt Menkec6b3edf72019-03-19 17:00:393566 ASSERT_TRUE(pool_->HasGroup(TestGroupId("a")));
[email protected]8159a1c2012-06-07 00:00:103567 EXPECT_EQ(kDefaultMaxSockets - 1,
Matt Menkec6b3edf72019-03-19 17:00:393568 static_cast<int>(pool_->NumConnectJobsInGroup(TestGroupId("a"))));
Lily Chenecebf932018-11-02 17:15:433569 EXPECT_EQ(kDefaultMaxSockets - 1,
Matt Menkec6b3edf72019-03-19 17:00:393570 static_cast<int>(
3571 pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a"))));
Raul Tambre8335a6d2019-02-21 16:57:433572 EXPECT_EQ(kDefaultMaxSockets - 1,
Matt Menkec6b3edf72019-03-19 17:00:393573 static_cast<int>(
3574 pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a"))));
[email protected]51fdc7c2012-04-10 19:19:483575 EXPECT_FALSE(pool_->IsStalled());
[email protected]2c2bef152010-10-13 00:55:033576
Matt Menkec6b3edf72019-03-19 17:00:393577 ASSERT_FALSE(pool_->HasGroup(TestGroupId("b")));
[email protected]2c2bef152010-10-13 00:55:033578
Matt Menkec6b3edf72019-03-19 17:00:393579 pool_->RequestSockets(TestGroupId("b"), &params_, kDefaultMaxSockets,
3580 NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033581
Matt Menkec6b3edf72019-03-19 17:00:393582 ASSERT_TRUE(pool_->HasGroup(TestGroupId("b")));
3583 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("b")));
[email protected]51fdc7c2012-04-10 19:19:483584 EXPECT_FALSE(pool_->IsStalled());
[email protected]2c2bef152010-10-13 00:55:033585}
3586
3587TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) {
3588 CreatePool(4, 4);
3589 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3590
3591 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523592 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203593 EXPECT_EQ(
3594 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:393595 handle1.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203596 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503597 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3598 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013599 ASSERT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033600 handle1.Reset();
3601
Matt Menkec6b3edf72019-03-19 17:00:393602 ASSERT_TRUE(pool_->HasGroup(TestGroupId("a")));
3603 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
3604 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
3605 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
3606 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033607
Matt Menkec6b3edf72019-03-19 17:00:393608 pool_->RequestSockets(TestGroupId("a"), &params_, 2, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033609
Matt Menkec6b3edf72019-03-19 17:00:393610 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
3611 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
3612 EXPECT_EQ(1u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
3613 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033614}
3615
3616TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountActiveSockets) {
3617 CreatePool(4, 4);
3618 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3619
3620 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523621 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203622 EXPECT_EQ(
3623 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:393624 handle1.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203625 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503626 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3627 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013628 ASSERT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033629
Matt Menkec6b3edf72019-03-19 17:00:393630 ASSERT_TRUE(pool_->HasGroup(TestGroupId("a")));
3631 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
3632 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
3633 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
3634 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3635 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033636
Matt Menkec6b3edf72019-03-19 17:00:393637 pool_->RequestSockets(TestGroupId("a"), &params_, 2, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033638
Matt Menkec6b3edf72019-03-19 17:00:393639 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
3640 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
3641 EXPECT_EQ(1u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
3642 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3643 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033644}
3645
3646TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronous) {
3647 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3648 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3649
Matt Menkec6b3edf72019-03-19 17:00:393650 pool_->RequestSockets(TestGroupId("a"), &params_, kDefaultMaxSocketsPerGroup,
Charlie Harrison55ce6082018-05-14 02:25:573651 NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033652
Matt Menkec6b3edf72019-03-19 17:00:393653 ASSERT_TRUE(pool_->HasGroup(TestGroupId("a")));
3654 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
3655 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
3656 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
Raul Tambre8335a6d2019-02-21 16:57:433657 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
Matt Menkec6b3edf72019-03-19 17:00:393658 static_cast<int>(pool_->IdleSocketCountInGroup(TestGroupId("a"))));
[email protected]2c2bef152010-10-13 00:55:033659
Matt Menkec6b3edf72019-03-19 17:00:393660 pool_->RequestSockets(TestGroupId("b"), &params_, kDefaultMaxSocketsPerGroup,
Charlie Harrison55ce6082018-05-14 02:25:573661 NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033662
Matt Menkec6b3edf72019-03-19 17:00:393663 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup(TestGroupId("b")));
3664 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("b")));
3665 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("b")));
Raul Tambre8335a6d2019-02-21 16:57:433666 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
Matt Menkec6b3edf72019-03-19 17:00:393667 static_cast<int>(pool_->IdleSocketCountInGroup(TestGroupId("b"))));
[email protected]2c2bef152010-10-13 00:55:033668}
3669
[email protected]3c819f522010-12-02 02:03:123670TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronousError) {
3671 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3672 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3673
Matt Menkec6b3edf72019-03-19 17:00:393674 pool_->RequestSockets(TestGroupId("a"), &params_, kDefaultMaxSocketsPerGroup,
Charlie Harrison55ce6082018-05-14 02:25:573675 NetLogWithSource());
[email protected]3c819f522010-12-02 02:03:123676
Matt Menkec6b3edf72019-03-19 17:00:393677 ASSERT_FALSE(pool_->HasGroup(TestGroupId("a")));
[email protected]fd2e53e2011-01-14 20:40:523678
3679 connect_job_factory_->set_job_type(
3680 TestConnectJob::kMockAdditionalErrorStateJob);
Matt Menkec6b3edf72019-03-19 17:00:393681 pool_->RequestSockets(TestGroupId("a"), &params_, kDefaultMaxSocketsPerGroup,
Charlie Harrison55ce6082018-05-14 02:25:573682 NetLogWithSource());
[email protected]fd2e53e2011-01-14 20:40:523683
Matt Menkec6b3edf72019-03-19 17:00:393684 ASSERT_FALSE(pool_->HasGroup(TestGroupId("a")));
[email protected]3c819f522010-12-02 02:03:123685}
3686
[email protected]8159a1c2012-06-07 00:00:103687TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) {
[email protected]2c2bef152010-10-13 00:55:033688 CreatePool(4, 4);
Lily Chenecebf932018-11-02 17:15:433689 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
[email protected]2c2bef152010-10-13 00:55:033690
Matt Menkec6b3edf72019-03-19 17:00:393691 pool_->RequestSockets(TestGroupId("a"), &params_, 2, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033692
Matt Menkec6b3edf72019-03-19 17:00:393693 ASSERT_TRUE(pool_->HasGroup(TestGroupId("a")));
3694 EXPECT_EQ(2u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
3695 EXPECT_EQ(2u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
3696 EXPECT_EQ(2u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
3697 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup(TestGroupId("a")));
3698 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033699
Matt Menkec6b3edf72019-03-19 17:00:393700 pool_->RequestSockets(TestGroupId("a"), &params_, 2, NetLogWithSource());
3701 EXPECT_EQ(2u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
3702 EXPECT_EQ(2u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
3703 EXPECT_EQ(2u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
3704 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup(TestGroupId("a")));
3705 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033706
3707 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523708 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203709 EXPECT_EQ(
3710 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:393711 handle1.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203712 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503713 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3714 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:433715
3716 client_socket_factory_.SignalJob(0);
3717 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3718
Matt Menkec6b3edf72019-03-19 17:00:393719 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
3720 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
3721 EXPECT_EQ(1u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
3722 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup(TestGroupId("a")));
3723 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033724
3725 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523726 TestCompletionCallback callback2;
Lily Chenecebf932018-11-02 17:15:433727 EXPECT_EQ(
3728 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:393729 handle2.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
Lily Chenecebf932018-11-02 17:15:433730 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503731 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3732 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:433733 client_socket_factory_.SignalJob(0);
3734 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033735
Matt Menkec6b3edf72019-03-19 17:00:393736 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
3737 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
3738 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
3739 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup(TestGroupId("a")));
3740 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]8159a1c2012-06-07 00:00:103741
[email protected]2c2bef152010-10-13 00:55:033742 handle1.Reset();
3743 handle2.Reset();
3744
Matt Menkec6b3edf72019-03-19 17:00:393745 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
3746 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
3747 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
3748 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup(TestGroupId("a")));
3749 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033750
Matt Menkec6b3edf72019-03-19 17:00:393751 pool_->RequestSockets(TestGroupId("a"), &params_, 2, NetLogWithSource());
3752 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
3753 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
3754 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
3755 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup(TestGroupId("a")));
3756 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033757}
3758
3759TEST_F(ClientSocketPoolBaseTest, RequestSocketsDifferentNumSockets) {
3760 CreatePool(4, 4);
3761 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3762
Matt Menkec6b3edf72019-03-19 17:00:393763 pool_->RequestSockets(TestGroupId("a"), &params_, 1, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033764
Matt Menkec6b3edf72019-03-19 17:00:393765 ASSERT_TRUE(pool_->HasGroup(TestGroupId("a")));
3766 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
3767 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
3768 EXPECT_EQ(1u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
3769 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033770
Matt Menkec6b3edf72019-03-19 17:00:393771 pool_->RequestSockets(TestGroupId("a"), &params_, 2, NetLogWithSource());
3772 EXPECT_EQ(2u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
3773 EXPECT_EQ(2u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
3774 EXPECT_EQ(2u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
3775 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033776
Matt Menkec6b3edf72019-03-19 17:00:393777 pool_->RequestSockets(TestGroupId("a"), &params_, 3, NetLogWithSource());
3778 EXPECT_EQ(3u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
3779 EXPECT_EQ(3u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
3780 EXPECT_EQ(3u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
3781 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033782
Matt Menkec6b3edf72019-03-19 17:00:393783 pool_->RequestSockets(TestGroupId("a"), &params_, 1, NetLogWithSource());
3784 EXPECT_EQ(3u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
3785 EXPECT_EQ(3u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
3786 EXPECT_EQ(3u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
3787 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033788}
3789
3790TEST_F(ClientSocketPoolBaseTest, PreconnectJobsTakenByNormalRequests) {
3791 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
Lily Chenecebf932018-11-02 17:15:433792 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
[email protected]2c2bef152010-10-13 00:55:033793
Matt Menkec6b3edf72019-03-19 17:00:393794 pool_->RequestSockets(TestGroupId("a"), &params_, 1, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033795
Matt Menkec6b3edf72019-03-19 17:00:393796 ASSERT_TRUE(pool_->HasGroup(TestGroupId("a")));
3797 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
3798 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
3799 EXPECT_EQ(1u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
3800 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033801
3802 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523803 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203804 EXPECT_EQ(
3805 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:393806 handle1.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203807 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503808 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3809 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033810
Matt Menkec6b3edf72019-03-19 17:00:393811 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
3812 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
3813 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
3814 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033815
Lily Chenecebf932018-11-02 17:15:433816 client_socket_factory_.SignalJobs();
3817 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3818
Matt Menkec6b3edf72019-03-19 17:00:393819 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
3820 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
3821 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
3822 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3823 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033824
[email protected]0dc88b32014-03-26 20:12:283825 // Make sure if a preconnected socket is not fully connected when a request
[email protected]034df0f32013-01-07 23:17:483826 // starts, it has a connect start time.
3827 TestLoadTimingInfoConnectedNotReused(handle1);
[email protected]2c2bef152010-10-13 00:55:033828 handle1.Reset();
3829
Matt Menkec6b3edf72019-03-19 17:00:393830 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]2c2bef152010-10-13 00:55:033831}
3832
[email protected]034df0f32013-01-07 23:17:483833// Checks that fully connected preconnect jobs have no connect times, and are
3834// marked as reused.
3835TEST_F(ClientSocketPoolBaseTest, ConnectedPreconnectJobsHaveNoConnectTimes) {
3836 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3837 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
Matt Menkec6b3edf72019-03-19 17:00:393838 pool_->RequestSockets(TestGroupId("a"), &params_, 1, NetLogWithSource());
[email protected]034df0f32013-01-07 23:17:483839
Matt Menkec6b3edf72019-03-19 17:00:393840 ASSERT_TRUE(pool_->HasGroup(TestGroupId("a")));
3841 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
3842 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
3843 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
3844 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]034df0f32013-01-07 23:17:483845
3846 ClientSocketHandle handle;
3847 TestCompletionCallback callback;
Matt Menkec6b3edf72019-03-19 17:00:393848 EXPECT_EQ(OK, handle.Init(
3849 TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
3850 ClientSocketPool::RespectLimits::ENABLED,
3851 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3852 pool_.get(), NetLogWithSource()));
[email protected]034df0f32013-01-07 23:17:483853
3854 // Make sure the idle socket was used.
Matt Menkec6b3edf72019-03-19 17:00:393855 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]034df0f32013-01-07 23:17:483856
3857 TestLoadTimingInfoConnectedReused(handle);
3858 handle.Reset();
3859 TestLoadTimingInfoNotConnected(handle);
3860}
3861
[email protected]dcbe168a2010-12-02 03:14:463862// http://crbug.com/64940 regression test.
3863TEST_F(ClientSocketPoolBaseTest, PreconnectClosesIdleSocketRemovesGroup) {
3864 const int kMaxTotalSockets = 3;
3865 const int kMaxSocketsPerGroup = 2;
3866 CreatePool(kMaxTotalSockets, kMaxSocketsPerGroup);
Lily Chenecebf932018-11-02 17:15:433867 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
[email protected]dcbe168a2010-12-02 03:14:463868
Matt Menkef6edce752019-03-19 17:21:563869 // Note that group id ordering matters here. "a" comes before "b", so
[email protected]dcbe168a2010-12-02 03:14:463870 // CloseOneIdleSocket() will try to close "a"'s idle socket.
3871
3872 // Set up one idle socket in "a".
3873 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523874 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203875 EXPECT_EQ(
3876 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:393877 handle1.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203878 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503879 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3880 pool_.get(), NetLogWithSource()));
Matt Menkec6b3edf72019-03-19 17:00:393881 ASSERT_TRUE(pool_->HasGroup(TestGroupId("a")));
3882 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
3883 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
3884 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
3885 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]dcbe168a2010-12-02 03:14:463886
Lily Chenecebf932018-11-02 17:15:433887 client_socket_factory_.SignalJobs();
robpercival214763f2016-07-01 23:27:013888 ASSERT_THAT(callback1.WaitForResult(), IsOk());
Matt Menkec6b3edf72019-03-19 17:00:393889 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
3890 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
3891 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
3892 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:433893
[email protected]dcbe168a2010-12-02 03:14:463894 handle1.Reset();
Matt Menkec6b3edf72019-03-19 17:00:393895 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]dcbe168a2010-12-02 03:14:463896
3897 // Set up two active sockets in "b".
3898 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523899 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203900 EXPECT_EQ(
3901 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:393902 handle1.Init(TestGroupId("b"), params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203903 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503904 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3905 pool_.get(), NetLogWithSource()));
tfarina428341112016-09-22 13:38:203906 EXPECT_EQ(
3907 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:393908 handle2.Init(TestGroupId("b"), params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203909 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503910 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3911 pool_.get(), NetLogWithSource()));
[email protected]dcbe168a2010-12-02 03:14:463912
Matt Menkec6b3edf72019-03-19 17:00:393913 ASSERT_TRUE(pool_->HasGroup(TestGroupId("b")));
3914 EXPECT_EQ(2u, pool_->NumConnectJobsInGroup(TestGroupId("b")));
3915 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("b")));
3916 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("b")));
3917 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("b")));
Lily Chenecebf932018-11-02 17:15:433918
3919 client_socket_factory_.SignalJobs();
robpercival214763f2016-07-01 23:27:013920 ASSERT_THAT(callback1.WaitForResult(), IsOk());
3921 ASSERT_THAT(callback2.WaitForResult(), IsOk());
Matt Menkec6b3edf72019-03-19 17:00:393922 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("b")));
3923 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("b")));
3924 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("b")));
3925 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup(TestGroupId("b")));
[email protected]dcbe168a2010-12-02 03:14:463926
3927 // Now we have 1 idle socket in "a" and 2 active sockets in "b". This means
3928 // we've maxed out on sockets, since we set |kMaxTotalSockets| to 3.
3929 // Requesting 2 preconnected sockets for "a" should fail to allocate any more
3930 // sockets for "a", and "b" should still have 2 active sockets.
3931
Matt Menkec6b3edf72019-03-19 17:00:393932 pool_->RequestSockets(TestGroupId("a"), &params_, 2, NetLogWithSource());
3933 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
3934 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
3935 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
3936 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3937 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup(TestGroupId("a")));
3938 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup(TestGroupId("b")));
3939 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("b")));
3940 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("b")));
3941 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("b")));
3942 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup(TestGroupId("b")));
[email protected]dcbe168a2010-12-02 03:14:463943
3944 // Now release the 2 active sockets for "b". This will give us 1 idle socket
3945 // in "a" and 2 idle sockets in "b". Requesting 2 preconnected sockets for
3946 // "a" should result in closing 1 for "b".
3947 handle1.Reset();
3948 handle2.Reset();
Matt Menkec6b3edf72019-03-19 17:00:393949 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(TestGroupId("b")));
3950 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup(TestGroupId("b")));
[email protected]dcbe168a2010-12-02 03:14:463951
Matt Menkec6b3edf72019-03-19 17:00:393952 pool_->RequestSockets(TestGroupId("a"), &params_, 2, NetLogWithSource());
3953 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
3954 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
3955 EXPECT_EQ(1u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
3956 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3957 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup(TestGroupId("a")));
3958 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup(TestGroupId("b")));
3959 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("b")));
3960 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("b")));
3961 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("b")));
3962 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup(TestGroupId("b")));
[email protected]dcbe168a2010-12-02 03:14:463963}
3964
[email protected]b7b8be42011-07-12 12:46:413965TEST_F(ClientSocketPoolBaseTest, PreconnectWithoutBackupJob) {
[email protected]a9fc8fc2011-05-10 02:41:073966 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3967 pool_->EnableConnectBackupJobs();
3968
3969 // Make the ConnectJob hang until it times out, shorten the timeout.
3970 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3971 connect_job_factory_->set_timeout_duration(
3972 base::TimeDelta::FromMilliseconds(500));
Matt Menkec6b3edf72019-03-19 17:00:393973 pool_->RequestSockets(TestGroupId("a"), &params_, 1, NetLogWithSource());
3974 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
3975 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
3976 EXPECT_EQ(1u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
3977 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]a9fc8fc2011-05-10 02:41:073978
[email protected]b7b8be42011-07-12 12:46:413979 // Verify the backup timer doesn't create a backup job, by making
3980 // the backup job a pending job instead of a waiting job, so it
3981 // *would* complete if it were created.
[email protected]a9fc8fc2011-05-10 02:41:073982 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
skyostil4891b25b2015-06-11 11:43:453983 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
Gabriel Charetteea918012018-05-16 11:53:443984 FROM_HERE, base::RunLoop::QuitCurrentWhenIdleClosureDeprecated(),
[email protected]2da659e2013-05-23 20:51:343985 base::TimeDelta::FromSeconds(1));
fdoray5eeb7642016-06-22 16:11:283986 base::RunLoop().Run();
Matt Menkec6b3edf72019-03-19 17:00:393987 EXPECT_FALSE(pool_->HasGroup(TestGroupId("a")));
[email protected]a9fc8fc2011-05-10 02:41:073988}
3989
[email protected]b7b8be42011-07-12 12:46:413990TEST_F(ClientSocketPoolBaseTest, PreconnectWithBackupJob) {
[email protected]a9fc8fc2011-05-10 02:41:073991 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3992 pool_->EnableConnectBackupJobs();
3993
3994 // Make the ConnectJob hang forever.
3995 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
Matt Menkec6b3edf72019-03-19 17:00:393996 pool_->RequestSockets(TestGroupId("a"), &params_, 1, NetLogWithSource());
3997 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
3998 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
3999 EXPECT_EQ(1u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
4000 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
fdoray5eeb7642016-06-22 16:11:284001 base::RunLoop().RunUntilIdle();
[email protected]a9fc8fc2011-05-10 02:41:074002
4003 // Make the backup job be a pending job, so it completes normally.
4004 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
4005 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:524006 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:504007 EXPECT_EQ(
4008 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:394009 handle.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:504010 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
4011 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4012 NetLogWithSource()));
[email protected]b7b8be42011-07-12 12:46:414013 // Timer has started, but the backup connect job shouldn't be created yet.
Matt Menkec6b3edf72019-03-19 17:00:394014 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
4015 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
4016 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
4017 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4018 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup(TestGroupId("a")));
robpercival214763f2016-07-01 23:27:014019 ASSERT_THAT(callback.WaitForResult(), IsOk());
[email protected]a9fc8fc2011-05-10 02:41:074020
4021 // The hung connect job should still be there, but everything else should be
4022 // complete.
Matt Menkec6b3edf72019-03-19 17:00:394023 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
4024 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
4025 EXPECT_EQ(1u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
4026 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4027 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup(TestGroupId("a")));
[email protected]a9fc8fc2011-05-10 02:41:074028}
4029
[email protected]0dc88b32014-03-26 20:12:284030// Tests that a preconnect that starts out with unread data can still be used.
4031// http://crbug.com/334467
4032TEST_F(ClientSocketPoolBaseTest, PreconnectWithUnreadData) {
4033 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4034 connect_job_factory_->set_job_type(TestConnectJob::kMockUnreadDataJob);
4035
Matt Menkec6b3edf72019-03-19 17:00:394036 pool_->RequestSockets(TestGroupId("a"), &params_, 1, NetLogWithSource());
[email protected]0dc88b32014-03-26 20:12:284037
Matt Menkec6b3edf72019-03-19 17:00:394038 ASSERT_TRUE(pool_->HasGroup(TestGroupId("a")));
4039 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
4040 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
4041 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
4042 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]0dc88b32014-03-26 20:12:284043
4044 // Fail future jobs to be sure that handle receives the preconnected socket
4045 // rather than closing it and making a new one.
4046 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
4047 ClientSocketHandle handle;
4048 TestCompletionCallback callback;
Matt Menkec6b3edf72019-03-19 17:00:394049 EXPECT_EQ(OK, handle.Init(
4050 TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
4051 ClientSocketPool::RespectLimits::ENABLED,
4052 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
4053 pool_.get(), NetLogWithSource()));
[email protected]0dc88b32014-03-26 20:12:284054
Matt Menkec6b3edf72019-03-19 17:00:394055 ASSERT_TRUE(pool_->HasGroup(TestGroupId("a")));
4056 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
4057 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
4058 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
4059 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4060 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup(TestGroupId("a")));
[email protected]0dc88b32014-03-26 20:12:284061
4062 // Drain the pending read.
Raul Tambre94493c652019-03-11 17:18:354063 EXPECT_EQ(1, handle.socket()->Read(nullptr, 1, CompletionOnceCallback()));
[email protected]0dc88b32014-03-26 20:12:284064
4065 TestLoadTimingInfoConnectedReused(handle);
4066 handle.Reset();
4067
4068 // The socket should be usable now that it's idle again.
Matt Menkec6b3edf72019-03-19 17:00:394069 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
[email protected]0dc88b32014-03-26 20:12:284070}
4071
Lily Chenecebf932018-11-02 17:15:434072TEST_F(ClientSocketPoolBaseTest, RequestGetsAssignedJob) {
4073 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4074 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4075
4076 ClientSocketHandle handle1;
4077 TestCompletionCallback callback1;
4078 EXPECT_EQ(
4079 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:394080 handle1.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
Lily Chenecebf932018-11-02 17:15:434081 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504082 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4083 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434084
Matt Menkec6b3edf72019-03-19 17:00:394085 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
4086 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
4087 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
4088 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434089
Matt Menkec6b3edf72019-03-19 17:00:394090 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4091 &handle1));
Lily Chenecebf932018-11-02 17:15:434092}
4093
4094TEST_F(ClientSocketPoolBaseTest, MultipleRequestsGetAssignedJobs) {
4095 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4096 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4097
4098 ClientSocketHandle handle1;
4099 TestCompletionCallback callback1;
4100 EXPECT_EQ(
4101 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:394102 handle1.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
Lily Chenecebf932018-11-02 17:15:434103 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504104 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4105 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434106
Matt Menkec6b3edf72019-03-19 17:00:394107 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
4108 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
4109 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
4110 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434111
4112 ClientSocketHandle handle2;
4113 TestCompletionCallback callback2;
4114 EXPECT_EQ(
4115 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:394116 handle2.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
Lily Chenecebf932018-11-02 17:15:434117 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504118 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4119 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434120
Matt Menkec6b3edf72019-03-19 17:00:394121 EXPECT_EQ(2u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
4122 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
4123 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
4124 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434125
Matt Menkec6b3edf72019-03-19 17:00:394126 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4127 &handle1));
4128 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4129 &handle2));
Lily Chenecebf932018-11-02 17:15:434130
4131 // One job completes. The other request should still have its job.
4132 client_socket_factory_.SignalJob(0);
4133 EXPECT_THAT(callback1.WaitForResult(), IsOk());
4134
Matt Menkec6b3edf72019-03-19 17:00:394135 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
4136 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
4137 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
4138 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup(TestGroupId("a")));
4139 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434140
Matt Menkec6b3edf72019-03-19 17:00:394141 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4142 &handle2));
Lily Chenecebf932018-11-02 17:15:434143}
4144
4145TEST_F(ClientSocketPoolBaseTest, PreconnectJobGetsAssignedToRequest) {
4146 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4147 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4148
Matt Menkec6b3edf72019-03-19 17:00:394149 pool_->RequestSockets(TestGroupId("a"), &params_, 1, NetLogWithSource());
Lily Chenecebf932018-11-02 17:15:434150
Matt Menkec6b3edf72019-03-19 17:00:394151 ASSERT_TRUE(pool_->HasGroup(TestGroupId("a")));
4152 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
4153 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
4154 EXPECT_EQ(1u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
4155 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434156
4157 ClientSocketHandle handle1;
4158 TestCompletionCallback callback1;
4159 EXPECT_EQ(
4160 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:394161 handle1.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
Lily Chenecebf932018-11-02 17:15:434162 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504163 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4164 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434165
Matt Menkec6b3edf72019-03-19 17:00:394166 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
4167 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
4168 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
4169 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434170
Matt Menkec6b3edf72019-03-19 17:00:394171 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4172 &handle1));
Lily Chenecebf932018-11-02 17:15:434173}
4174
4175TEST_F(ClientSocketPoolBaseTest, HigherPriorityRequestStealsJob) {
4176 CreatePool(kDefaultMaxSockets, 1);
4177 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4178
4179 ClientSocketHandle handle1;
4180 TestCompletionCallback callback1;
4181 EXPECT_EQ(
4182 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:394183 handle1.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
Lily Chenecebf932018-11-02 17:15:434184 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504185 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4186 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434187
Matt Menkec6b3edf72019-03-19 17:00:394188 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
4189 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
4190 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
4191 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434192
Matt Menkec6b3edf72019-03-19 17:00:394193 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4194 &handle1));
Lily Chenecebf932018-11-02 17:15:434195
4196 // Insert a higher priority request
4197 ClientSocketHandle handle2;
4198 TestCompletionCallback callback2;
4199 EXPECT_EQ(
4200 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:394201 handle2.Init(TestGroupId("a"), params_, HIGHEST, SocketTag(),
Lily Chenecebf932018-11-02 17:15:434202 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504203 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4204 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434205
Matt Menkec6b3edf72019-03-19 17:00:394206 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
4207 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
4208 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
4209 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434210
4211 // The highest priority request should steal the job from the default priority
4212 // request.
Matt Menkec6b3edf72019-03-19 17:00:394213 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4214 &handle2));
4215 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4216 &handle1));
Lily Chenecebf932018-11-02 17:15:434217}
4218
4219TEST_F(ClientSocketPoolBaseTest, RequestStealsJobFromLowestRequestWithJob) {
4220 CreatePool(3, 3);
4221 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4222
4223 ClientSocketHandle handle_lowest;
4224 TestCompletionCallback callback_lowest;
4225 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:394226 handle_lowest.Init(TestGroupId("a"), params_, LOWEST, SocketTag(),
Lily Chenecebf932018-11-02 17:15:434227 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504228 callback_lowest.callback(),
4229 ClientSocketPool::ProxyAuthCallback(),
4230 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434231
Matt Menkec6b3edf72019-03-19 17:00:394232 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
4233 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
4234 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
4235 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434236
4237 ClientSocketHandle handle_highest;
4238 TestCompletionCallback callback_highest;
4239 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:394240 handle_highest.Init(TestGroupId("a"), params_, HIGHEST, SocketTag(),
Lily Chenecebf932018-11-02 17:15:434241 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504242 callback_highest.callback(),
4243 ClientSocketPool::ProxyAuthCallback(),
4244 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434245
Matt Menkec6b3edf72019-03-19 17:00:394246 EXPECT_EQ(2u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
4247 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
4248 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
4249 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434250
4251 ClientSocketHandle handle_low;
4252 TestCompletionCallback callback_low;
4253 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:394254 handle_low.Init(TestGroupId("a"), params_, LOW, SocketTag(),
Lily Chenecebf932018-11-02 17:15:434255 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504256 callback_low.callback(),
4257 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
Lily Chenecebf932018-11-02 17:15:434258 NetLogWithSource()));
4259
Matt Menkec6b3edf72019-03-19 17:00:394260 EXPECT_EQ(3u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
4261 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
4262 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
4263 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434264
4265 ClientSocketHandle handle_lowest2;
4266 TestCompletionCallback callback_lowest2;
4267 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:394268 handle_lowest2.Init(TestGroupId("a"), params_, LOWEST, SocketTag(),
Lily Chenecebf932018-11-02 17:15:434269 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504270 callback_lowest2.callback(),
4271 ClientSocketPool::ProxyAuthCallback(),
4272 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434273
Matt Menkec6b3edf72019-03-19 17:00:394274 EXPECT_EQ(3u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
4275 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
4276 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
4277 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434278
4279 // The top three requests in the queue should have jobs.
Matt Menkec6b3edf72019-03-19 17:00:394280 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4281 &handle_highest));
4282 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4283 &handle_low));
4284 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4285 &handle_lowest));
4286 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(
4287 TestGroupId("a"), &handle_lowest2));
Lily Chenecebf932018-11-02 17:15:434288
4289 // Add another request with medium priority. It should steal the job from the
4290 // lowest priority request with a job.
4291 ClientSocketHandle handle_medium;
4292 TestCompletionCallback callback_medium;
4293 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:394294 handle_medium.Init(TestGroupId("a"), params_, MEDIUM, SocketTag(),
Lily Chenecebf932018-11-02 17:15:434295 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504296 callback_medium.callback(),
4297 ClientSocketPool::ProxyAuthCallback(),
4298 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434299
Matt Menkec6b3edf72019-03-19 17:00:394300 EXPECT_EQ(3u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
4301 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
4302 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
4303 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4304 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4305 &handle_highest));
4306 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4307 &handle_medium));
4308 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4309 &handle_low));
4310 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4311 &handle_lowest));
4312 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(
4313 TestGroupId("a"), &handle_lowest2));
Lily Chenecebf932018-11-02 17:15:434314}
4315
4316TEST_F(ClientSocketPoolBaseTest, ReprioritizeRequestStealsJob) {
4317 CreatePool(kDefaultMaxSockets, 1);
4318 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4319
4320 ClientSocketHandle handle1;
4321 TestCompletionCallback callback1;
4322 EXPECT_EQ(
4323 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:394324 handle1.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
Lily Chenecebf932018-11-02 17:15:434325 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504326 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4327 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434328
Matt Menkec6b3edf72019-03-19 17:00:394329 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
4330 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
4331 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
4332 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434333
4334 ClientSocketHandle handle2;
4335 TestCompletionCallback callback2;
4336 EXPECT_EQ(
4337 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:394338 handle2.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
Lily Chenecebf932018-11-02 17:15:434339 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504340 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4341 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434342
Matt Menkec6b3edf72019-03-19 17:00:394343 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
4344 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
4345 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
4346 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434347
4348 // The second request doesn't get a job because we are at the limit.
Matt Menkec6b3edf72019-03-19 17:00:394349 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4350 &handle1));
4351 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4352 &handle2));
Lily Chenecebf932018-11-02 17:15:434353
4354 // Reprioritizing the second request places it above the first, and it steals
4355 // the job from the first request.
Matt Menkec6b3edf72019-03-19 17:00:394356 pool_->SetPriority(TestGroupId("a"), &handle2, HIGHEST);
4357 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4358 &handle2));
4359 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4360 &handle1));
Lily Chenecebf932018-11-02 17:15:434361}
4362
4363TEST_F(ClientSocketPoolBaseTest, CancelRequestReassignsJob) {
4364 CreatePool(kDefaultMaxSockets, 1);
4365 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4366
4367 ClientSocketHandle handle1;
4368 TestCompletionCallback callback1;
4369 EXPECT_EQ(
4370 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:394371 handle1.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
Lily Chenecebf932018-11-02 17:15:434372 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504373 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4374 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434375
Matt Menkec6b3edf72019-03-19 17:00:394376 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
4377 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
4378 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
4379 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434380
Matt Menkec6b3edf72019-03-19 17:00:394381 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4382 &handle1));
Lily Chenecebf932018-11-02 17:15:434383
4384 ClientSocketHandle handle2;
4385 TestCompletionCallback callback2;
4386 EXPECT_EQ(
4387 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:394388 handle2.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
Lily Chenecebf932018-11-02 17:15:434389 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504390 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4391 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434392
Matt Menkec6b3edf72019-03-19 17:00:394393 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
4394 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
4395 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
4396 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434397
4398 // The second request doesn't get a job because we are the limit.
Matt Menkec6b3edf72019-03-19 17:00:394399 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4400 &handle1));
4401 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4402 &handle2));
Lily Chenecebf932018-11-02 17:15:434403
4404 // The second request should get a job upon cancelling the first request.
4405 handle1.Reset();
Matt Menkec6b3edf72019-03-19 17:00:394406 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
4407 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
4408 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
4409 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434410
Matt Menkec6b3edf72019-03-19 17:00:394411 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4412 &handle2));
Lily Chenecebf932018-11-02 17:15:434413}
4414
4415TEST_F(ClientSocketPoolBaseTest, JobCompletionReassignsJob) {
4416 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4417 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4418
4419 ClientSocketHandle handle1;
4420 TestCompletionCallback callback1;
4421 EXPECT_EQ(
4422 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:394423 handle1.Init(TestGroupId("a"), params_, HIGHEST, SocketTag(),
Lily Chenecebf932018-11-02 17:15:434424 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504425 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4426 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434427
Matt Menkec6b3edf72019-03-19 17:00:394428 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
4429 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
4430 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
4431 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434432
4433 ClientSocketHandle handle2;
4434 TestCompletionCallback callback2;
4435 EXPECT_EQ(
4436 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:394437 handle2.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
Lily Chenecebf932018-11-02 17:15:434438 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504439 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4440 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434441
Matt Menkec6b3edf72019-03-19 17:00:394442 EXPECT_EQ(2u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
4443 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
4444 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
4445 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434446
Matt Menkec6b3edf72019-03-19 17:00:394447 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4448 &handle1));
4449 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4450 &handle2));
Lily Chenecebf932018-11-02 17:15:434451
4452 // The lower-priority job completes first. The higher-priority request should
4453 // get the socket, and the lower-priority request should get the remaining
4454 // job.
4455 client_socket_factory_.SignalJob(1);
4456 EXPECT_THAT(callback1.WaitForResult(), IsOk());
Matt Menkec6b3edf72019-03-19 17:00:394457 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
4458 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup(TestGroupId("a")));
4459 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup(TestGroupId("a")));
4460 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup(TestGroupId("a")));
4461 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Lily Chenecebf932018-11-02 17:15:434462 EXPECT_TRUE(handle1.socket());
Matt Menkec6b3edf72019-03-19 17:00:394463 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4464 &handle2));
Lily Chenecebf932018-11-02 17:15:434465}
4466
[email protected]043b68c82013-08-22 23:41:524467class MockLayeredPool : public HigherLayeredPool {
[email protected]58e562f2013-04-22 17:32:204468 public:
4469 MockLayeredPool(TestClientSocketPool* pool,
Matt Menkec6b3edf72019-03-19 17:00:394470 const ClientSocketPool::GroupId& group_id)
4471 : pool_(pool), group_id_(group_id), can_release_connection_(true) {
[email protected]043b68c82013-08-22 23:41:524472 pool_->AddHigherLayeredPool(this);
[email protected]58e562f2013-04-22 17:32:204473 }
4474
Daniel Cheng4496d0822018-04-26 21:52:154475 ~MockLayeredPool() override { pool_->RemoveHigherLayeredPool(this); }
[email protected]58e562f2013-04-22 17:32:204476
4477 int RequestSocket(TestClientSocketPool* pool) {
mmenked3641e12016-01-28 16:06:154478 scoped_refptr<TestSocketParams> params(new TestSocketParams());
Matt Menke28ac03e2019-02-25 22:25:504479 return handle_.Init(
Matt Menkec6b3edf72019-03-19 17:00:394480 group_id_, params, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:504481 ClientSocketPool::RespectLimits::ENABLED, callback_.callback(),
4482 ClientSocketPool::ProxyAuthCallback(), pool, NetLogWithSource());
[email protected]58e562f2013-04-22 17:32:204483 }
4484
4485 int RequestSocketWithoutLimits(TestClientSocketPool* pool) {
mmenked3641e12016-01-28 16:06:154486 scoped_refptr<TestSocketParams> params(new TestSocketParams());
Matt Menke28ac03e2019-02-25 22:25:504487 return handle_.Init(
Matt Menkec6b3edf72019-03-19 17:00:394488 group_id_, params, MAXIMUM_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:504489 ClientSocketPool::RespectLimits::DISABLED, callback_.callback(),
4490 ClientSocketPool::ProxyAuthCallback(), pool, NetLogWithSource());
[email protected]58e562f2013-04-22 17:32:204491 }
4492
4493 bool ReleaseOneConnection() {
4494 if (!handle_.is_initialized() || !can_release_connection_) {
4495 return false;
4496 }
4497 handle_.socket()->Disconnect();
4498 handle_.Reset();
4499 return true;
4500 }
4501
4502 void set_can_release_connection(bool can_release_connection) {
4503 can_release_connection_ = can_release_connection;
4504 }
4505
4506 MOCK_METHOD0(CloseOneIdleConnection, bool());
4507
4508 private:
4509 TestClientSocketPool* const pool_;
[email protected]58e562f2013-04-22 17:32:204510 ClientSocketHandle handle_;
4511 TestCompletionCallback callback_;
Matt Menkec6b3edf72019-03-19 17:00:394512 const ClientSocketPool::GroupId group_id_;
[email protected]58e562f2013-04-22 17:32:204513 bool can_release_connection_;
4514};
4515
[email protected]58e562f2013-04-22 17:32:204516// Tests the basic case of closing an idle socket in a higher layered pool when
4517// a new request is issued and the lower layer pool is stalled.
4518TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsHeldByLayeredPoolWhenNeeded) {
4519 CreatePool(1, 1);
4520 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4521
Matt Menkec6b3edf72019-03-19 17:00:394522 MockLayeredPool mock_layered_pool(pool_.get(), TestGroupId("foo"));
robpercival214763f2016-07-01 23:27:014523 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:204524 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4525 .WillOnce(Invoke(&mock_layered_pool,
4526 &MockLayeredPool::ReleaseOneConnection));
4527 ClientSocketHandle handle;
4528 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:504529 EXPECT_EQ(
4530 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:394531 handle.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:504532 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
4533 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4534 NetLogWithSource()));
robpercival214763f2016-07-01 23:27:014535 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204536}
4537
Matt Menke833678642019-03-05 22:05:514538// Tests the case that trying to close an idle socket in a higher layered pool
4539// fails.
4540TEST_F(ClientSocketPoolBaseTest,
4541 CloseIdleSocketsHeldByLayeredPoolWhenNeededFails) {
4542 CreatePool(1, 1);
4543 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4544
Matt Menkec6b3edf72019-03-19 17:00:394545 MockLayeredPool mock_layered_pool(pool_.get(), TestGroupId("foo"));
Matt Menke833678642019-03-05 22:05:514546 mock_layered_pool.set_can_release_connection(false);
4547 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
4548 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4549 .WillOnce(Invoke(&mock_layered_pool,
4550 &MockLayeredPool::ReleaseOneConnection));
4551 ClientSocketHandle handle;
4552 TestCompletionCallback callback;
4553 EXPECT_EQ(
4554 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:394555 handle.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
Matt Menke833678642019-03-05 22:05:514556 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
4557 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4558 NetLogWithSource()));
4559 base::RunLoop().RunUntilIdle();
4560 EXPECT_FALSE(callback.have_result());
4561}
4562
[email protected]58e562f2013-04-22 17:32:204563// Same as above, but the idle socket is in the same group as the stalled
4564// socket, and closes the only other request in its group when closing requests
4565// in higher layered pools. This generally shouldn't happen, but it may be
4566// possible if a higher level pool issues a request and the request is
4567// subsequently cancelled. Even if it's not possible, best not to crash.
4568TEST_F(ClientSocketPoolBaseTest,
4569 CloseIdleSocketsHeldByLayeredPoolWhenNeededSameGroup) {
4570 CreatePool(2, 2);
4571 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4572
4573 // Need a socket in another group for the pool to be stalled (If a group
4574 // has the maximum number of connections already, it's not stalled).
4575 ClientSocketHandle handle1;
4576 TestCompletionCallback callback1;
Matt Menkec6b3edf72019-03-19 17:00:394577 EXPECT_EQ(OK, handle1.Init(
4578 TestGroupId("group1"), params_, DEFAULT_PRIORITY,
4579 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4580 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4581 pool_.get(), NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:204582
Matt Menkec6b3edf72019-03-19 17:00:394583 MockLayeredPool mock_layered_pool(pool_.get(), TestGroupId("group2"));
robpercival214763f2016-07-01 23:27:014584 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:204585 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4586 .WillOnce(Invoke(&mock_layered_pool,
4587 &MockLayeredPool::ReleaseOneConnection));
4588 ClientSocketHandle handle;
4589 TestCompletionCallback callback2;
Matt Menke28ac03e2019-02-25 22:25:504590 EXPECT_EQ(
4591 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:394592 handle.Init(TestGroupId("group2"), params_, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:504593 ClientSocketPool::RespectLimits::ENABLED,
4594 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4595 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:014596 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204597}
4598
4599// Tests the case when an idle socket can be closed when a new request is
4600// issued, and the new request belongs to a group that was previously stalled.
4601TEST_F(ClientSocketPoolBaseTest,
4602 CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded) {
4603 CreatePool(2, 2);
4604 std::list<TestConnectJob::JobType> job_types;
4605 job_types.push_back(TestConnectJob::kMockJob);
4606 job_types.push_back(TestConnectJob::kMockJob);
4607 job_types.push_back(TestConnectJob::kMockJob);
4608 job_types.push_back(TestConnectJob::kMockJob);
4609 connect_job_factory_->set_job_types(&job_types);
4610
4611 ClientSocketHandle handle1;
4612 TestCompletionCallback callback1;
Matt Menkec6b3edf72019-03-19 17:00:394613 EXPECT_EQ(OK, handle1.Init(
4614 TestGroupId("group1"), params_, DEFAULT_PRIORITY,
4615 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4616 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4617 pool_.get(), NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:204618
Matt Menkec6b3edf72019-03-19 17:00:394619 MockLayeredPool mock_layered_pool(pool_.get(), TestGroupId("group2"));
robpercival214763f2016-07-01 23:27:014620 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:204621 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4622 .WillRepeatedly(Invoke(&mock_layered_pool,
4623 &MockLayeredPool::ReleaseOneConnection));
4624 mock_layered_pool.set_can_release_connection(false);
4625
4626 // The third request is made when the socket pool is in a stalled state.
4627 ClientSocketHandle handle3;
4628 TestCompletionCallback callback3;
tfarina428341112016-09-22 13:38:204629 EXPECT_EQ(
4630 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:394631 handle3.Init(TestGroupId("group3"), params_, DEFAULT_PRIORITY,
4632 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504633 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
4634 pool_.get(), NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:204635
4636 base::RunLoop().RunUntilIdle();
4637 EXPECT_FALSE(callback3.have_result());
4638
4639 // The fourth request is made when the pool is no longer stalled. The third
4640 // request should be serviced first, since it was issued first and has the
4641 // same priority.
4642 mock_layered_pool.set_can_release_connection(true);
4643 ClientSocketHandle handle4;
4644 TestCompletionCallback callback4;
tfarina428341112016-09-22 13:38:204645 EXPECT_EQ(
4646 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:394647 handle4.Init(TestGroupId("group3"), params_, DEFAULT_PRIORITY,
4648 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504649 callback4.callback(), ClientSocketPool::ProxyAuthCallback(),
4650 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:014651 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204652 EXPECT_FALSE(callback4.have_result());
4653
4654 // Closing a handle should free up another socket slot.
4655 handle1.Reset();
robpercival214763f2016-07-01 23:27:014656 EXPECT_THAT(callback4.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204657}
4658
4659// Tests the case when an idle socket can be closed when a new request is
4660// issued, and the new request belongs to a group that was previously stalled.
4661//
4662// The two differences from the above test are that the stalled requests are not
4663// in the same group as the layered pool's request, and the the fourth request
4664// has a higher priority than the third one, so gets a socket first.
4665TEST_F(ClientSocketPoolBaseTest,
4666 CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded2) {
4667 CreatePool(2, 2);
4668 std::list<TestConnectJob::JobType> job_types;
4669 job_types.push_back(TestConnectJob::kMockJob);
4670 job_types.push_back(TestConnectJob::kMockJob);
4671 job_types.push_back(TestConnectJob::kMockJob);
4672 job_types.push_back(TestConnectJob::kMockJob);
4673 connect_job_factory_->set_job_types(&job_types);
4674
4675 ClientSocketHandle handle1;
4676 TestCompletionCallback callback1;
Matt Menkec6b3edf72019-03-19 17:00:394677 EXPECT_EQ(OK, handle1.Init(
4678 TestGroupId("group1"), params_, DEFAULT_PRIORITY,
4679 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4680 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4681 pool_.get(), NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:204682
Matt Menkec6b3edf72019-03-19 17:00:394683 MockLayeredPool mock_layered_pool(pool_.get(), TestGroupId("group2"));
robpercival214763f2016-07-01 23:27:014684 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:204685 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4686 .WillRepeatedly(Invoke(&mock_layered_pool,
4687 &MockLayeredPool::ReleaseOneConnection));
4688 mock_layered_pool.set_can_release_connection(false);
4689
4690 // The third request is made when the socket pool is in a stalled state.
4691 ClientSocketHandle handle3;
4692 TestCompletionCallback callback3;
tfarina428341112016-09-22 13:38:204693 EXPECT_EQ(
4694 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:394695 handle3.Init(TestGroupId("group3"), params_, MEDIUM, SocketTag(),
tfarina428341112016-09-22 13:38:204696 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504697 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
4698 pool_.get(), NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:204699
4700 base::RunLoop().RunUntilIdle();
4701 EXPECT_FALSE(callback3.have_result());
4702
4703 // The fourth request is made when the pool is no longer stalled. This
4704 // request has a higher priority than the third request, so is serviced first.
4705 mock_layered_pool.set_can_release_connection(true);
4706 ClientSocketHandle handle4;
4707 TestCompletionCallback callback4;
tfarina428341112016-09-22 13:38:204708 EXPECT_EQ(
4709 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:394710 handle4.Init(TestGroupId("group3"), params_, HIGHEST, SocketTag(),
tfarina428341112016-09-22 13:38:204711 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504712 callback4.callback(), ClientSocketPool::ProxyAuthCallback(),
4713 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:014714 EXPECT_THAT(callback4.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204715 EXPECT_FALSE(callback3.have_result());
4716
4717 // Closing a handle should free up another socket slot.
4718 handle1.Reset();
robpercival214763f2016-07-01 23:27:014719 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204720}
4721
4722TEST_F(ClientSocketPoolBaseTest,
4723 CloseMultipleIdleSocketsHeldByLayeredPoolWhenNeeded) {
4724 CreatePool(1, 1);
4725 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4726
Matt Menkec6b3edf72019-03-19 17:00:394727 MockLayeredPool mock_layered_pool1(pool_.get(), TestGroupId("foo"));
robpercival214763f2016-07-01 23:27:014728 EXPECT_THAT(mock_layered_pool1.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:204729 EXPECT_CALL(mock_layered_pool1, CloseOneIdleConnection())
4730 .WillRepeatedly(Invoke(&mock_layered_pool1,
4731 &MockLayeredPool::ReleaseOneConnection));
Matt Menkec6b3edf72019-03-19 17:00:394732 MockLayeredPool mock_layered_pool2(pool_.get(), TestGroupId("bar"));
robpercival214763f2016-07-01 23:27:014733 EXPECT_THAT(mock_layered_pool2.RequestSocketWithoutLimits(pool_.get()),
4734 IsOk());
[email protected]58e562f2013-04-22 17:32:204735 EXPECT_CALL(mock_layered_pool2, CloseOneIdleConnection())
4736 .WillRepeatedly(Invoke(&mock_layered_pool2,
4737 &MockLayeredPool::ReleaseOneConnection));
4738 ClientSocketHandle handle;
4739 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:504740 EXPECT_EQ(
4741 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:394742 handle.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
Matt Menke28ac03e2019-02-25 22:25:504743 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
4744 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4745 NetLogWithSource()));
robpercival214763f2016-07-01 23:27:014746 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204747}
4748
[email protected]b021ece62013-06-11 11:06:334749// Test that when a socket pool and group are at their limits, a request
mmenked3641e12016-01-28 16:06:154750// with RespectLimits::DISABLED triggers creation of a new socket, and gets the
4751// socket instead of a request with the same priority that was issued earlier,
4752// but has RespectLimits::ENABLED.
[email protected]b021ece62013-06-11 11:06:334753TEST_F(ClientSocketPoolBaseTest, IgnoreLimits) {
[email protected]b021ece62013-06-11 11:06:334754 CreatePool(1, 1);
4755
4756 // Issue a request to reach the socket pool limit.
Matt Menkec6b3edf72019-03-19 17:00:394757 EXPECT_EQ(OK, StartRequestWithIgnoreLimits(
4758 TestGroupId("a"), MAXIMUM_PRIORITY,
4759 ClientSocketPool::RespectLimits::ENABLED));
4760 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
[email protected]b021ece62013-06-11 11:06:334761
4762 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
4763
mmenked3641e12016-01-28 16:06:154764 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
Matt Menkec6b3edf72019-03-19 17:00:394765 TestGroupId("a"), MAXIMUM_PRIORITY,
mmenked3641e12016-01-28 16:06:154766 ClientSocketPool::RespectLimits::ENABLED));
Matt Menkec6b3edf72019-03-19 17:00:394767 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
[email protected]b021ece62013-06-11 11:06:334768
mmenked3641e12016-01-28 16:06:154769 // Issue a request that ignores the limits, so a new ConnectJob is
4770 // created.
4771 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
Matt Menkec6b3edf72019-03-19 17:00:394772 TestGroupId("a"), MAXIMUM_PRIORITY,
mmenked3641e12016-01-28 16:06:154773 ClientSocketPool::RespectLimits::DISABLED));
Matt Menkec6b3edf72019-03-19 17:00:394774 ASSERT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
[email protected]b021ece62013-06-11 11:06:334775
robpercival214763f2016-07-01 23:27:014776 EXPECT_THAT(request(2)->WaitForResult(), IsOk());
[email protected]b021ece62013-06-11 11:06:334777 EXPECT_FALSE(request(1)->have_result());
4778}
4779
[email protected]c55fabd2013-11-04 23:26:564780// Test that when a socket pool and group are at their limits, a ConnectJob
mmenked3641e12016-01-28 16:06:154781// issued for a request with RespectLimits::DISABLED is not cancelled when a
4782// request with RespectLimits::ENABLED issued to the same group is cancelled.
[email protected]c55fabd2013-11-04 23:26:564783TEST_F(ClientSocketPoolBaseTest, IgnoreLimitsCancelOtherJob) {
[email protected]c55fabd2013-11-04 23:26:564784 CreatePool(1, 1);
4785
4786 // Issue a request to reach the socket pool limit.
Matt Menkec6b3edf72019-03-19 17:00:394787 EXPECT_EQ(OK, StartRequestWithIgnoreLimits(
4788 TestGroupId("a"), MAXIMUM_PRIORITY,
4789 ClientSocketPool::RespectLimits::ENABLED));
4790 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
[email protected]c55fabd2013-11-04 23:26:564791
4792 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
4793
mmenked3641e12016-01-28 16:06:154794 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
Matt Menkec6b3edf72019-03-19 17:00:394795 TestGroupId("a"), MAXIMUM_PRIORITY,
mmenked3641e12016-01-28 16:06:154796 ClientSocketPool::RespectLimits::ENABLED));
Matt Menkec6b3edf72019-03-19 17:00:394797 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
[email protected]c55fabd2013-11-04 23:26:564798
mmenked3641e12016-01-28 16:06:154799 // Issue a request with RespectLimits::DISABLED, so a new ConnectJob is
4800 // created.
4801 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
Matt Menkec6b3edf72019-03-19 17:00:394802 TestGroupId("a"), MAXIMUM_PRIORITY,
mmenked3641e12016-01-28 16:06:154803 ClientSocketPool::RespectLimits::DISABLED));
Matt Menkec6b3edf72019-03-19 17:00:394804 ASSERT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
[email protected]b021ece62013-06-11 11:06:334805
mmenked3641e12016-01-28 16:06:154806 // Cancel the pending request with RespectLimits::ENABLED. The ConnectJob
[email protected]b021ece62013-06-11 11:06:334807 // should not be cancelled.
4808 request(1)->handle()->Reset();
Matt Menkec6b3edf72019-03-19 17:00:394809 ASSERT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
[email protected]b021ece62013-06-11 11:06:334810
robpercival214763f2016-07-01 23:27:014811 EXPECT_THAT(request(2)->WaitForResult(), IsOk());
[email protected]b021ece62013-06-11 11:06:334812 EXPECT_FALSE(request(1)->have_result());
4813}
4814
Matt Menkeb57663b32019-03-01 17:17:104815TEST_F(ClientSocketPoolBaseTest, ProxyAuthNoAuthCallback) {
4816 CreatePool(1, 1);
4817
4818 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
4819
4820 ClientSocketHandle handle;
4821 TestCompletionCallback callback;
4822 EXPECT_EQ(
4823 ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:394824 handle.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(),
Matt Menkeb57663b32019-03-01 17:17:104825 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
4826 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4827 NetLogWithSource()));
4828
Matt Menkec6b3edf72019-03-19 17:00:394829 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:104830
4831 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_PROXY_AUTH_REQUESTED));
4832 EXPECT_FALSE(handle.is_initialized());
4833 EXPECT_FALSE(handle.socket());
4834
4835 // The group should now be empty, and thus be deleted.
Matt Menkec6b3edf72019-03-19 17:00:394836 EXPECT_FALSE(pool_->HasGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:104837}
4838
4839class TestAuthHelper {
4840 public:
4841 TestAuthHelper() = default;
4842 ~TestAuthHelper() = default;
4843
Matt Menkec6b3edf72019-03-19 17:00:394844 void InitHandle(
4845 scoped_refptr<TestSocketParams> params,
4846 TestClientSocketPool* pool,
4847 RequestPriority priority = DEFAULT_PRIORITY,
4848 ClientSocketPool::RespectLimits respect_limits =
4849 ClientSocketPool::RespectLimits::ENABLED,
4850 const ClientSocketPool::GroupId& group_id_in = TestGroupId("a")) {
Matt Menkeb57663b32019-03-01 17:17:104851 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkec6b3edf72019-03-19 17:00:394852 handle_.Init(group_id_in, params.get(), priority, SocketTag(),
Matt Menkeb57663b32019-03-01 17:17:104853 respect_limits, callback_.callback(),
4854 base::BindRepeating(&TestAuthHelper::AuthCallback,
4855 base::Unretained(this)),
4856 pool, NetLogWithSource()));
4857 }
4858
4859 void WaitForAuth() {
4860 run_loop_ = std::make_unique<base::RunLoop>();
4861 run_loop_->Run();
4862 run_loop_.reset();
4863 }
4864
4865 void WaitForAuthAndRestartSync() {
4866 restart_sync_ = true;
4867 WaitForAuth();
4868 restart_sync_ = false;
4869 }
4870
4871 void WaitForAuthAndResetHandleSync() {
4872 reset_handle_sync_ = true;
4873 WaitForAuth();
4874 reset_handle_sync_ = false;
4875 }
4876
4877 void RestartWithAuth() {
4878 DCHECK(restart_with_auth_callback_);
4879 std::move(restart_with_auth_callback_).Run();
4880 }
4881
4882 int WaitForResult() {
4883 int result = callback_.WaitForResult();
4884 // There shouldn't be any callback waiting to be invoked once the request is
4885 // complete.
4886 EXPECT_FALSE(restart_with_auth_callback_);
4887 // The socket should only be initialized on success.
4888 EXPECT_EQ(result == OK, handle_.is_initialized());
4889 EXPECT_EQ(result == OK, handle_.socket() != nullptr);
4890 return result;
4891 }
4892
4893 ClientSocketHandle* handle() { return &handle_; }
4894 int auth_count() const { return auth_count_; }
4895 int have_result() const { return callback_.have_result(); }
4896
4897 private:
4898 void AuthCallback(const HttpResponseInfo& response,
4899 HttpAuthController* auth_controller,
4900 base::OnceClosure restart_with_auth_callback) {
4901 EXPECT_FALSE(restart_with_auth_callback_);
4902 EXPECT_TRUE(restart_with_auth_callback);
4903
4904 // Once there's a result, this method shouldn't be invoked again.
4905 EXPECT_FALSE(callback_.have_result());
4906
4907 ++auth_count_;
4908 run_loop_->Quit();
4909 if (restart_sync_) {
4910 std::move(restart_with_auth_callback).Run();
4911 return;
4912 }
4913
4914 restart_with_auth_callback_ = std::move(restart_with_auth_callback);
4915
4916 if (reset_handle_sync_) {
4917 handle_.Reset();
4918 return;
4919 }
4920 }
4921
4922 std::unique_ptr<base::RunLoop> run_loop_;
4923 base::OnceClosure restart_with_auth_callback_;
4924
4925 bool restart_sync_ = false;
4926 bool reset_handle_sync_ = false;
4927
4928 ClientSocketHandle handle_;
4929 int auth_count_ = 0;
4930 TestCompletionCallback callback_;
4931
4932 DISALLOW_COPY_AND_ASSIGN(TestAuthHelper);
4933};
4934
4935TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnce) {
4936 CreatePool(1, 1);
4937 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
4938
4939 TestAuthHelper auth_helper;
4940 auth_helper.InitHandle(params_, pool_.get());
Matt Menkec6b3edf72019-03-19 17:00:394941 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
Matt Menke4b69f932019-03-04 16:20:014942 EXPECT_EQ(LOAD_STATE_CONNECTING,
Matt Menkec6b3edf72019-03-19 17:00:394943 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:104944
4945 auth_helper.WaitForAuth();
Matt Menkec6b3edf72019-03-19 17:00:394946 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
Matt Menke4b69f932019-03-04 16:20:014947 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
Matt Menkec6b3edf72019-03-19 17:00:394948 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:104949
4950 auth_helper.RestartWithAuth();
Matt Menkec6b3edf72019-03-19 17:00:394951 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
Matt Menke4b69f932019-03-04 16:20:014952 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
Matt Menkec6b3edf72019-03-19 17:00:394953 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:104954
4955 EXPECT_THAT(auth_helper.WaitForResult(), IsOk());
4956 EXPECT_EQ(1, auth_helper.auth_count());
Matt Menkec6b3edf72019-03-19 17:00:394957 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
4958 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup(TestGroupId("a")));
4959 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:104960 EXPECT_EQ(0, pool_->IdleSocketCount());
4961}
4962
4963TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceSync) {
4964 CreatePool(1, 1);
4965 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
4966
4967 TestAuthHelper auth_helper;
4968 auth_helper.InitHandle(params_, pool_.get());
Matt Menkec6b3edf72019-03-19 17:00:394969 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
Matt Menke4b69f932019-03-04 16:20:014970 EXPECT_EQ(LOAD_STATE_CONNECTING,
Matt Menkec6b3edf72019-03-19 17:00:394971 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:104972
4973 auth_helper.WaitForAuthAndRestartSync();
Matt Menkec6b3edf72019-03-19 17:00:394974 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
Matt Menke4b69f932019-03-04 16:20:014975 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
Matt Menkec6b3edf72019-03-19 17:00:394976 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:104977
4978 EXPECT_THAT(auth_helper.WaitForResult(), IsOk());
4979 EXPECT_EQ(1, auth_helper.auth_count());
Matt Menkec6b3edf72019-03-19 17:00:394980 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
4981 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup(TestGroupId("a")));
4982 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:104983 EXPECT_EQ(0, pool_->IdleSocketCount());
4984}
4985
4986TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceFails) {
4987 CreatePool(1, 1);
4988 connect_job_factory_->set_job_type(
4989 TestConnectJob::kMockAuthChallengeOnceFailingJob);
4990
4991 TestAuthHelper auth_helper;
4992 auth_helper.InitHandle(params_, pool_.get());
Matt Menkec6b3edf72019-03-19 17:00:394993 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:104994
4995 auth_helper.WaitForAuth();
4996 auth_helper.RestartWithAuth();
4997 EXPECT_THAT(auth_helper.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
4998
4999 EXPECT_EQ(1, auth_helper.auth_count());
Matt Menkec6b3edf72019-03-19 17:00:395000 EXPECT_FALSE(pool_->HasGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105001 EXPECT_EQ(0, pool_->IdleSocketCount());
5002}
5003
5004TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceSyncFails) {
5005 CreatePool(1, 1);
5006 connect_job_factory_->set_job_type(
5007 TestConnectJob::kMockAuthChallengeOnceFailingJob);
5008
5009 TestAuthHelper auth_helper;
5010 auth_helper.InitHandle(params_, pool_.get());
Matt Menkec6b3edf72019-03-19 17:00:395011 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105012
5013 auth_helper.WaitForAuthAndRestartSync();
5014 EXPECT_THAT(auth_helper.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
5015
5016 EXPECT_EQ(1, auth_helper.auth_count());
Matt Menkec6b3edf72019-03-19 17:00:395017 EXPECT_FALSE(pool_->HasGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105018 EXPECT_EQ(0, pool_->IdleSocketCount());
5019}
5020
5021TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceDeleteHandle) {
5022 CreatePool(1, 1);
5023 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5024
5025 TestAuthHelper auth_helper;
5026 auth_helper.InitHandle(params_, pool_.get());
Matt Menkec6b3edf72019-03-19 17:00:395027 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105028
5029 auth_helper.WaitForAuth();
Matt Menkec6b3edf72019-03-19 17:00:395030 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105031
5032 auth_helper.handle()->Reset();
5033
5034 EXPECT_EQ(1, auth_helper.auth_count());
Matt Menkec6b3edf72019-03-19 17:00:395035 EXPECT_FALSE(pool_->HasGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105036 EXPECT_EQ(0, pool_->IdleSocketCount());
5037 EXPECT_FALSE(auth_helper.handle()->is_initialized());
5038 EXPECT_FALSE(auth_helper.handle()->socket());
5039}
5040
5041TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceDeleteHandleSync) {
5042 CreatePool(1, 1);
5043 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5044
5045 TestAuthHelper auth_helper;
5046 auth_helper.InitHandle(params_, pool_.get());
Matt Menkec6b3edf72019-03-19 17:00:395047 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105048
5049 auth_helper.WaitForAuthAndResetHandleSync();
5050 EXPECT_EQ(1, auth_helper.auth_count());
Matt Menkec6b3edf72019-03-19 17:00:395051 EXPECT_FALSE(pool_->HasGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105052 EXPECT_EQ(0, pool_->IdleSocketCount());
5053 EXPECT_FALSE(auth_helper.handle()->is_initialized());
5054 EXPECT_FALSE(auth_helper.handle()->socket());
5055}
5056
5057TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceFlushWithError) {
5058 CreatePool(1, 1);
5059 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5060
5061 TestAuthHelper auth_helper;
5062 auth_helper.InitHandle(params_, pool_.get());
Matt Menkec6b3edf72019-03-19 17:00:395063 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105064
5065 auth_helper.WaitForAuth();
5066
5067 pool_->FlushWithError(ERR_FAILED);
5068 base::RunLoop().RunUntilIdle();
5069
5070 // When flushing the socket pool, bound sockets should delay returning the
5071 // error until completion.
5072 EXPECT_FALSE(auth_helper.have_result());
Matt Menkec6b3edf72019-03-19 17:00:395073 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105074 EXPECT_EQ(0, pool_->IdleSocketCount());
5075
5076 auth_helper.RestartWithAuth();
5077 // The callback should be called asynchronously.
5078 EXPECT_FALSE(auth_helper.have_result());
5079
5080 EXPECT_THAT(auth_helper.WaitForResult(), IsError(ERR_FAILED));
Matt Menkec6b3edf72019-03-19 17:00:395081 EXPECT_FALSE(pool_->HasGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105082 EXPECT_EQ(0, pool_->IdleSocketCount());
5083}
5084
5085TEST_F(ClientSocketPoolBaseTest, ProxyAuthTwice) {
5086 CreatePool(1, 1);
5087 connect_job_factory_->set_job_type(
5088 TestConnectJob::kMockAuthChallengeTwiceJob);
5089
5090 TestAuthHelper auth_helper;
5091 auth_helper.InitHandle(params_, pool_.get());
Matt Menkec6b3edf72019-03-19 17:00:395092 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
Matt Menke4b69f932019-03-04 16:20:015093 EXPECT_EQ(LOAD_STATE_CONNECTING,
Matt Menkec6b3edf72019-03-19 17:00:395094 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:105095
5096 auth_helper.WaitForAuth();
5097 auth_helper.RestartWithAuth();
Matt Menkec6b3edf72019-03-19 17:00:395098 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105099 EXPECT_EQ(1, auth_helper.auth_count());
Matt Menke4b69f932019-03-04 16:20:015100 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
Matt Menkec6b3edf72019-03-19 17:00:395101 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:105102
5103 auth_helper.WaitForAuth();
Matt Menkec6b3edf72019-03-19 17:00:395104 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
Matt Menke4b69f932019-03-04 16:20:015105 EXPECT_EQ(2, auth_helper.auth_count());
5106 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
Matt Menkec6b3edf72019-03-19 17:00:395107 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
Matt Menke4b69f932019-03-04 16:20:015108
Matt Menkeb57663b32019-03-01 17:17:105109 auth_helper.RestartWithAuth();
Matt Menkec6b3edf72019-03-19 17:00:395110 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105111 EXPECT_EQ(2, auth_helper.auth_count());
Matt Menke4b69f932019-03-04 16:20:015112 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
Matt Menkec6b3edf72019-03-19 17:00:395113 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:105114
5115 EXPECT_THAT(auth_helper.WaitForResult(), IsOk());
5116 EXPECT_EQ(2, auth_helper.auth_count());
Matt Menkec6b3edf72019-03-19 17:00:395117 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
5118 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup(TestGroupId("a")));
5119 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105120 EXPECT_EQ(0, pool_->IdleSocketCount());
5121}
5122
5123TEST_F(ClientSocketPoolBaseTest, ProxyAuthTwiceFails) {
5124 CreatePool(1, 1);
5125 connect_job_factory_->set_job_type(
5126 TestConnectJob::kMockAuthChallengeTwiceFailingJob);
5127
5128 TestAuthHelper auth_helper;
5129 auth_helper.InitHandle(params_, pool_.get());
Matt Menkec6b3edf72019-03-19 17:00:395130 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105131
5132 auth_helper.WaitForAuth();
5133 auth_helper.RestartWithAuth();
Matt Menkec6b3edf72019-03-19 17:00:395134 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105135 EXPECT_EQ(1, auth_helper.auth_count());
5136
5137 auth_helper.WaitForAuth();
5138 auth_helper.RestartWithAuth();
Matt Menkec6b3edf72019-03-19 17:00:395139 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105140 EXPECT_EQ(2, auth_helper.auth_count());
5141
5142 EXPECT_THAT(auth_helper.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
5143 EXPECT_EQ(2, auth_helper.auth_count());
Matt Menkec6b3edf72019-03-19 17:00:395144 EXPECT_FALSE(pool_->HasGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105145 EXPECT_EQ(0, pool_->IdleSocketCount());
5146}
5147
5148// Makes sure that when a bound request is destroyed, a new ConnectJob is
5149// created, if needed.
5150TEST_F(ClientSocketPoolBaseTest,
5151 ProxyAuthCreateNewConnectJobOnDestroyBoundRequest) {
5152 CreatePool(1 /* max_sockets */, 1 /* max_sockets_per_group */);
5153 connect_job_factory_->set_job_type(
5154 TestConnectJob::kMockAuthChallengeOnceFailingJob);
5155
5156 // First request creates a ConnectJob.
5157 TestAuthHelper auth_helper1;
5158 auth_helper1.InitHandle(params_, pool_.get());
Matt Menkec6b3edf72019-03-19 17:00:395159 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105160
5161 // A second request come in, but no new ConnectJob is needed, since the limit
5162 // has been reached.
5163 TestAuthHelper auth_helper2;
5164 auth_helper2.InitHandle(params_, pool_.get());
Matt Menkec6b3edf72019-03-19 17:00:395165 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105166
5167 // Run until the auth callback for the first request is invoked.
5168 auth_helper1.WaitForAuth();
5169 EXPECT_EQ(0, auth_helper2.auth_count());
Matt Menkec6b3edf72019-03-19 17:00:395170 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
5171 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup(TestGroupId("a")));
5172 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105173
5174 // Make connect jobs succeed, then cancel the first request, which should
5175 // destroy the bound ConnectJob, and cause a new ConnectJob to start.
5176 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
5177 auth_helper1.handle()->Reset();
5178 EXPECT_EQ(0, auth_helper2.auth_count());
Matt Menkec6b3edf72019-03-19 17:00:395179 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105180
5181 // The second ConnectJob should succeed.
5182 EXPECT_THAT(auth_helper2.WaitForResult(), IsOk());
5183 EXPECT_EQ(0, auth_helper2.auth_count());
Matt Menkec6b3edf72019-03-19 17:00:395184 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105185}
5186
5187// Makes sure that when a bound request is destroyed, a new ConnectJob is
5188// created for another group, if needed.
5189TEST_F(ClientSocketPoolBaseTest,
5190 ProxyAuthCreateNewConnectJobOnDestroyBoundRequestDifferentGroups) {
5191 CreatePool(1 /* max_sockets */, 1 /* max_sockets_per_group */);
5192 connect_job_factory_->set_job_type(
5193 TestConnectJob::kMockAuthChallengeOnceFailingJob);
5194
5195 // First request creates a ConnectJob.
5196 TestAuthHelper auth_helper1;
5197 auth_helper1.InitHandle(params_, pool_.get(), DEFAULT_PRIORITY);
Matt Menkec6b3edf72019-03-19 17:00:395198 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105199
5200 // A second request come in, but no new ConnectJob is needed, since the limit
5201 // has been reached.
5202 TestAuthHelper auth_helper2;
5203 auth_helper2.InitHandle(params_, pool_.get(), DEFAULT_PRIORITY,
Matt Menkec6b3edf72019-03-19 17:00:395204 ClientSocketPool::RespectLimits::ENABLED,
5205 TestGroupId("b"));
5206 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
5207 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup(TestGroupId("b")));
Matt Menkeb57663b32019-03-01 17:17:105208
5209 // Run until the auth callback for the first request is invoked.
5210 auth_helper1.WaitForAuth();
5211 EXPECT_EQ(0, auth_helper2.auth_count());
Matt Menkec6b3edf72019-03-19 17:00:395212 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
5213 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup(TestGroupId("a")));
5214 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
5215 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup(TestGroupId("b")));
5216 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup(TestGroupId("b")));
5217 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("b")));
Matt Menkeb57663b32019-03-01 17:17:105218
5219 // Make connect jobs succeed, then cancel the first request, which should
5220 // destroy the bound ConnectJob, and cause a new ConnectJob to start for the
5221 // other group.
5222 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
5223 auth_helper1.handle()->Reset();
5224 EXPECT_EQ(0, auth_helper2.auth_count());
Matt Menkec6b3edf72019-03-19 17:00:395225 EXPECT_FALSE(pool_->HasGroup(TestGroupId("a")));
5226 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("b")));
Matt Menkeb57663b32019-03-01 17:17:105227
5228 // The second ConnectJob should succeed.
5229 EXPECT_THAT(auth_helper2.WaitForResult(), IsOk());
5230 EXPECT_EQ(0, auth_helper2.auth_count());
Matt Menkec6b3edf72019-03-19 17:00:395231 EXPECT_FALSE(pool_->HasGroup(TestGroupId("a")));
5232 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup(TestGroupId("b")));
Matt Menkeb57663b32019-03-01 17:17:105233}
5234
5235// Test that once an auth challenge is bound, that's the request that gets all
5236// subsequent calls and the socket itself.
5237TEST_F(ClientSocketPoolBaseTest, ProxyAuthStaysBound) {
5238 CreatePool(1, 1);
5239 connect_job_factory_->set_job_type(
5240 TestConnectJob::kMockAuthChallengeTwiceJob);
5241
5242 // First request creates a ConnectJob.
5243 TestAuthHelper auth_helper1;
5244 auth_helper1.InitHandle(params_, pool_.get(), LOWEST);
Matt Menkec6b3edf72019-03-19 17:00:395245 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105246
5247 // A second, higher priority request is made.
5248 TestAuthHelper auth_helper2;
5249 auth_helper2.InitHandle(params_, pool_.get(), LOW);
Matt Menkec6b3edf72019-03-19 17:00:395250 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105251
5252 // Run until the auth callback for the second request is invoked.
5253 auth_helper2.WaitForAuth();
5254 EXPECT_EQ(0, auth_helper1.auth_count());
Matt Menkec6b3edf72019-03-19 17:00:395255 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
5256 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup(TestGroupId("a")));
5257 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105258
5259 // Start a higher priority job. It shouldn't be able to steal |auth_helper2|'s
5260 // ConnectJob.
5261 TestAuthHelper auth_helper3;
5262 auth_helper3.InitHandle(params_, pool_.get(), HIGHEST);
Matt Menkec6b3edf72019-03-19 17:00:395263 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105264
5265 // Start a higher job that ignores limits, creating a hanging socket. It
5266 // shouldn't be able to steal |auth_helper2|'s ConnectJob.
5267 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
5268 TestAuthHelper auth_helper4;
5269 auth_helper4.InitHandle(params_, pool_.get(), HIGHEST,
5270 ClientSocketPool::RespectLimits::DISABLED);
Matt Menkec6b3edf72019-03-19 17:00:395271 EXPECT_EQ(2u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105272
5273 // Restart with auth, and |auth_helper2|'s auth method should be invoked
5274 // again.
5275 auth_helper2.RestartWithAuth();
5276 auth_helper2.WaitForAuth();
5277 EXPECT_EQ(0, auth_helper1.auth_count());
5278 EXPECT_FALSE(auth_helper1.have_result());
5279 EXPECT_EQ(2, auth_helper2.auth_count());
5280 EXPECT_FALSE(auth_helper2.have_result());
5281 EXPECT_EQ(0, auth_helper3.auth_count());
5282 EXPECT_FALSE(auth_helper3.have_result());
5283 EXPECT_EQ(0, auth_helper4.auth_count());
5284 EXPECT_FALSE(auth_helper4.have_result());
5285
5286 // Advance auth again, and |auth_helper2| should get the socket.
5287 auth_helper2.RestartWithAuth();
5288 EXPECT_THAT(auth_helper2.WaitForResult(), IsOk());
5289 // The hung ConnectJob for the RespectLimits::DISABLED request is still in the
5290 // socket pool.
Matt Menkec6b3edf72019-03-19 17:00:395291 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup(TestGroupId("a")));
5292 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup(TestGroupId("a")));
Matt Menkeb57663b32019-03-01 17:17:105293 EXPECT_EQ(0, auth_helper1.auth_count());
5294 EXPECT_FALSE(auth_helper1.have_result());
5295 EXPECT_EQ(0, auth_helper3.auth_count());
5296 EXPECT_FALSE(auth_helper3.have_result());
5297 EXPECT_EQ(0, auth_helper4.auth_count());
5298 EXPECT_FALSE(auth_helper4.have_result());
5299
5300 // If the socket is returned to the socket pool, the RespectLimits::DISABLED
5301 // socket request should be able to claim it.
5302 auth_helper2.handle()->Reset();
5303 EXPECT_THAT(auth_helper4.WaitForResult(), IsOk());
5304 EXPECT_EQ(0, auth_helper1.auth_count());
5305 EXPECT_FALSE(auth_helper1.have_result());
5306 EXPECT_EQ(0, auth_helper3.auth_count());
5307 EXPECT_FALSE(auth_helper3.have_result());
5308 EXPECT_EQ(0, auth_helper4.auth_count());
5309}
5310
[email protected]f6d1d6eb2009-06-24 20:16:095311} // namespace
5312
5313} // namespace net